/* Strajedy ... Yah, that's the ticket. */
#include <dos.h>
#include <conio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <alloc.h>
#include <graphics.h>
#define EXTCDECL extern
#include "goh.c"
int scoregam()
{
int value;
if (player == WHT) value = wscore - bscore;
else value = bscore - wscore;
value += BIAS;
return(value);
}
/*
int scoreye()
{
int value; /* model on Japanese score B = Bterr + Wdead + Wcap */
int bval, wval;
struct link *rootlp;
struct link *libp;
struct root *rootp;
unsigned index, bw;
rootlp = rootlist->nextl;
bval = 0;
wval = 0;
/* replace this pig with separate estimate of live eyes.. or areas.. */
/*
for(index=1; index<=nsize2; ++index) {
if (!dir[index]) {
bw = BLK;
if (geteye(index, bw)) {
if (!getceye(index, bw)) {
if (!getoeye(index, bw)) {
++bval;
}
}
}
bw = WHT;
if (geteye(index, bw)) {
if (!getceye(index, bw)) {
if (!getoeye(index, bw)) {
++wval;
}
}
}
}
}
newline();
printf(" eyesb/w: %d %d ::", bval, wval);
*/
bval = eyeterr[BLK];
wval = eyeterr[WHT];
/* count dead stones */
/*
if (rootlp) {
do {
rootp = rootlp->loc;
bw = rootp->clr;
if (!rootp->reallive) {
if (bw == BLK) wval += rootp->nsto;
else bval += rootp->nsto;
}
rootlp = rootlp->nextl;
} while (rootlp);
}
*/
bval += deadsto[WHT];
wval += deadsto[BLK];
bval += wcaps;
wval += bcaps;
eyescore[BLK] = bval;
eyescore[WHT] = wval;
if (player == WHT) value = wval - bval;
else value = bval - wval;
value += BIAS;
return(value);
}
*/
/*
int scoreye()
{
int value;
int bval, wval;
struct link *rootlp;
struct link *libp;
struct root *rootp;
unsigned index, bw;
rootlp = rootlist->nextl;
bval = 0;
wval = 0;
if (rootlp) {
do {
rootp = rootlp->loc;
bw = rootp->clr;
if (!rootp->reallive) {
if (bw == BLK) bval -= rootp->nsto + rootp->nsto + rootp->nlib;
else wval -= rootp->nsto + rootp->nsto + rootp->nlib;
}
else {
if (bw == BLK) bval += rootp->nsto;
else wval += rootp->nsto;
libp = rootp->liberties->nextl;
do {
index = libp->loc;
if (bw == BLK) {
if (!confeye(index, WHT)) {
if (beyes[index]) ++bval;
}
}
else {
if (!confeye(index, BLK)) {
if (weyes[index]) ++ wval;
}
}
libp = libp->nextl;
} while (libp);
}
rootlp = rootlp->nextl;
} while (rootlp);
}
if (colour == BLK) value = wval - bval;
else value = bval - wval;
value += BIAS;
return(value);
}
*/
int scoresph()
{
int value;
unsigned index, jndex, i, *point, bw;
if (player == WHT) {
value = (sphscore[WHT] - sphscore[BLK]);
}
else {
value = (sphscore[BLK] - sphscore[WHT]);
}
value += BIAS;
/*
/* deduct points for each partition */
value += 1000; /* start with a bunch */
for (i=1; i<=numparts; ++i) {
if (partinfo[i]>>8 == player) value -= 20;
else value += 20;
}
*/
/*
/* add 1000 points for each eye surrounding last move */
index = movep->midx;
if (index) {
bw = dir[index]->clr;
point = NEWS(index);
for (i=0; i<NLIBS; ++i) {
jndex = *point;
if (jndex) {
if (!dir[jndex] && geteye(jndex, bw) && (bw == player)) value += 1000;
}
++point;
}
}
*/
return(value);
}
int scoreye()
{
int value;
if (player == WHT) value = eyescore[WHT] - eyescore[BLK];
else value = eyescore[BLK] - eyescore[WHT];
value += BIAS;
return(value);
}
int scoreter()
{
int value;
if (player == WHT) value = triscore[WHT] - triscore[BLK];
else value = triscore[BLK] - triscore[WHT];
value += BIAS;
return(value);
}
void oppeye(unsigned indexes)
{
struct link *rootlp, *libp;
struct root *rootp;
unsigned i, j, k, *point, indexp, opp;
opp = flip(colour);
indexp = indexes;
rootlp = rootlist->nextl;
if (rootlp) {
do {
rootp = rootlp->loc;
if (rootp->clr == opp) {
libp = rootp->liberties->nextl;
do {
i = libp->loc;
if (getgeye(i, opp)) {
indexp = xtlocate(i, indexp);
indexp = xtinsert(i, indexp);
}
libp = libp->nextl;
} while (libp);
}
rootlp = rootlp->nextl;
} while (rootlp);
}
}
void deadeye(unsigned indexes)
{
struct link *rootlp, *libp;
struct root *rootp;
unsigned i, j, k, *point, indexp;
indexp = indexes;
rootlp = rootlist->nextl;
if (rootlp) {
do {
rootp = rootlp->loc;
libp = rootp->liberties->nextl;
do {
i = libp->loc;
if (!geteye(i, BLK) && !geteye(i, WHT)) {
indexp = xtlocate(i, indexp);
indexp = xtinsert(i, indexp);
}
libp = libp->nextl;
} while (libp);
rootlp = rootlp->nextl;
} while (rootlp);
}
}
void conflict(unsigned indexes)
{
struct link *rootlp, *libp;
struct root *rootp;
unsigned i, j, k, *point, indexp;
indexp = indexes;
rootlp = rootlist->nextl;
if (rootlp) {
do {
rootp = rootlp->loc;
libp = rootp->liberties->nextl;
do {
i = libp->loc;
if (getceye(i, BLK) || getceye(i, WHT)) {
indexp = xtlocate(i, indexp);
indexp = xtinsert(i, indexp);
}
libp = libp->nextl;
} while (libp);
rootlp = rootlp->nextl;
} while (rootlp);
}
}
void angle(unsigned indexes)
{
struct link *rootlp, *spcp;
struct root *rootp;
unsigned i, j, k, indexp, *point;
indexp = indexes;
rootlp = rootlist->nextl;
if (rootlp) {
do {
rootp = rootlp->loc;
spcp = rootp->spaces->nextl;
do {
i = spcp->loc;
point = NEWS(i);
for (k=1; k<=NLIBS; ++k) {
j = *point;
if (j) {
if (getgeye(j, BLK) || getgeye(j,WHT)) {
indexp = xtlocate(i, indexp);
indexp = xtinsert(i, indexp);
}
}
++point;
}
spcp = spcp->nextl;
} while (spcp);
rootlp = rootlp->nextl;
} while (rootlp);
}
}
void ikken(unsigned indexes)
{
struct link *rootlp, *libp;
struct root *rootp;
unsigned i, j, k, indexp, *point;
indexp = indexes;
rootlp = rootlist->nextl;
if (rootlp) {
do {
rootp = rootlp->loc;
libp = rootp->liberties->nextl;
do {
i = libp->loc;
if (getgeye(i, BLK) || getgeye(i,WHT)) {
point = NEWS(i);
for (k=1; k<=NLIBS; ++k) {
j = *point;
if (j) {
if (!dir[j]) {
if (!member(j, locate(j, rootp->liberties))) {
if (!member(j, locate(j, rootp->spaces))) {
indexp = xtlocate(j, indexp);
indexp = xtinsert(j, indexp);
}
}
}
}
++point;
}
}
libp = libp->nextl;
} while (libp);
rootlp = rootlp->nextl;
} while (rootlp);
}
}
void stealer(unsigned indexes)
{
struct link *rootlp, *libp;
struct root *rootp;
unsigned i, j, k, indexp, *point;
unsigned index;
unsigned diagvec[NDIAGS];
indexp = indexes;
rootlp = rootlist->nextl;
if (rootlp) {
do {
rootp = rootlp->loc;
libp = rootp->liberties->nextl;
do {
index = rootp->ridx;
i = libp->loc;
if (getgeye(i, BLK) || getgeye(i, WHT)) {
diags(i, diagvec);
point = diagvec;
for (k=1; k<=NDIAGS; ++k) {
j = *point;
if (j) {
if (!dir[j]) {
if (howfar(index, j) == 5) {
indexp = xtlocate(j, indexp);
indexp = xtinsert(j, indexp);
}
}
}
++point;
}
}
libp = libp->nextl;
} while (libp);
rootlp = rootlp->nextl;
} while (rootlp);
}
}
/*
void stoneye(unsigned indexes)
{
struct link *rootlp, *eyep;
struct root *rootp;
unsigned i, j, k, indexp, *point;
indexp = indexes;
rootlp = rootlist->nextl;
if (rootlp) {
do {
rootp = rootlp->loc;
if (rootp->nsto == 1) {
eyep = rootp->neighbs->nextl;
do {
i = eyep->loc;
if ((weyes[i] || beyes[i]) && !binside[i] && !winside[i]) {
indexp = xtlocate(j, indexp);
indexp = xtinsert(j, indexp);
}
eyep = eyep->nextl;
} while (eyep);
}
rootlp = rootlp->nextl;
} while (rootlp);
}
}
*/
/*
unsigned haseyes(unsigned index)
{
unsigned enuf;
unsigned jndex;
struct link *libp;
struct root *rootp;
enuf = 0;
rootp = dir[index];
if (rootp) {
libp = rootp->liberties->nextl;
do {
jndex = libp->loc;
if ((rootp->clr == BLK) && (beyes[jndex])) ++enuf;
else if ((rootp->clr == WHT) && (weyes[jndex])) ++enuf;
/*libp = locate(jndex, libp);*/
libp = libp->nextl;
} while (libp);
}
if (enuf < 2) enuf = 0;
return(enuf);
}
*/
unsigned connected(unsigned index)
{
unsigned iscon;
unsigned dist, jndex, jndexes, jndexp, blockers;
iscon = 0;
jndexes = xtinsert(0, 0);
for (dist=2; dist<=4; ++dist) {
cring(index, dist, jndexes, dir[index]->clr);
}
jndexp = peek(jndexes, NEXTL);
if (jndexp) {
do {
jndex = peek(jndexp, LOC);
blockers = xtinsert(0, 0);
if (!block(index, jndex, blockers, 1)) iscon = 1;
xtfreelist(blockers);
jndexp = peek(jndexp, NEXTL);
} while (jndexp && !iscon);
}
xtfreelist(jndexes);
return(iscon);
}
int best(unsigned wieners)
{
unsigned index;
unsigned maxscore;
unsigned score, baseline, dist;
unsigned wienerp, indexes, indexp;
unsigned jndex, jndexes, which, killer, oldsphr, gotone, gotopp;
unsigned killers, cankill;
unsigned befo, iscon, madmove;
int i, value, bogus;
alloff();
eyeson = 1;
sphron = 1;
wienerp = wieners;
maxscore = 0;
/* play eye-killers and sort best score first */
for (which=1; which<=1; ++which) {
madmove = ((kount/3)*3 == kount);
if (col80) {
newline();
printf(" best madmove:%d", madmove);
}
indexes = xtinsert(0, 0);
/* specify universe here */
befo = 1;
if (kount > 100) befo = 0;
befo = 0;
if (madmove) {
indexp = indexes;
for (index=1; index<=nsize2; ++index) {
if (!dir[index]) {
if (!edge(index)) {
indexp = xtlocate(index, indexp);
indexp = xtinsert(index, indexp);
}
}
}
}
else {
indexp = indexes;
for (index=1; index<=nsize2; ++index) {
if ((whose[index]&255) <= 5) {
if ((whose[index]&255) >= 2) {
/*if ((whose[index]>>8 == player) || !(whose[index]>>8)) {*/
indexp = xtlocate(index, indexp);
indexp = xtinsert(index, indexp);
/*}*/
}
}
}
}
indexp = peek(indexes, NEXTL);
if (indexp) {
do {
index = peek(indexp, LOC);
poke(indexp, LEVEL, NEGINF);
if (!madmove || (madmove && perisphr[index])) {
bogus = 0;
value = 0;
score = 0;
valid = doit(index);
if (valid) {
/*if (!dir[index]->reallive) bogus = 1;*/
evaluate();
value = scoresph();
if (!bogus) poke(indexp, LEVEL, value);
index = undoit();
}
if (valid && !bogus) {
if (value) {
value += scoresph();
/*value -= BIAS;*/
doit(0);
valid = doit(index);
if (valid) {
evaluate();
/*value += BIAS;*/
value -= scoresph();
score = value;
poke(indexp, LEVEL, score);
index = undoit();
}
undoit();
}
}
}
indexp = peek(indexp, NEXTL);
} while (indexp && !attn);
}
maxsort(indexes);
alloff();
if (col80) {
indexp = peek(indexes, NEXTS);
if (indexp) {
i = 0;
do {
if (!(i % 3)) {
newline();
}
++i;
coords(peek(indexp, LOC));
printf(" %-5d ", peek(indexp, LEVEL));
indexp = peek(indexp, NEXTS);
if (i > 52) {
indexp = 0;
printf(" ..more");
}
} while (indexp);
indexp = peek(indexes, NEXTS);
/*
do {
if (peek(indexp, LEVEL) == value) curon(peek(indexp, LOC));
indexp = peek(indexp, NEXTS);
} while (indexp);
*/
}
}
indexp = peek(indexes, NEXTS);
if (indexp) {
gotone = 0;
do {
index = peek(indexp, LOC);
score = peek(indexp, LEVEL);
if (score) {
/*
gotopp = 0;
doit(0);
valid = doit(index);
if (valid) {
max3 = kount;
killers = xtinsert(0, 0);
if (!kill(index, killers)) { /*(!att(index, &killer)) {*/
gotopp = 1;
}
xtfreelist(killers);
index = undoit();
}
undoit();
*/
iscon = 0;
doit(0);
valid = doit(index);
if (valid) {
if (!akill(index)) {
iscon = 1;
}
index = undoit();
}
undoit();
if (iscon) { /*gotopp) {*/
valid = doit(index);
if (valid) {
if (1) {
/* every fourth move need not be connected */
iscon = 1;
if (!befo) {
if (!madmove) iscon = connected(index);
}
if (iscon) {
killers = xtinsert(0, 0);
if (!akill(index)) {
if (!forkaji(index, killers)) {
gotone = 1;
wienerp = xtlocate(index, wienerp);
wienerp = xtinsert(index, wienerp);
poke(wienerp, LEVEL, score);
if (score > maxscore) maxscore = score;
}
}
xtfreelist(killers);
}
}
index = undoit();
}
}
}
indexp = peek(indexp, NEXTS);
} while (indexp && !gotone);
}
xtfreelist(indexes);
/*if (maxscore) break;*/
}
maxsort(wieners);
return(maxscore);
}
int postfu(unsigned wieners)
{
unsigned index;
unsigned maxscore;
unsigned score, baseline, dist, mxdst;
unsigned wienerp, indexes, indexp;
unsigned jndex, jndexes, which, killer, oldsphr, gotone, gotopp;
unsigned killers, cankill;
unsigned befo, iscon;
int i, value, bogus;
alloff();
eyeson = 1;
sphron = 1;
wienerp = wieners;
maxscore = 0;
/* find mxdst from anywhere, given not too close to edge */
mxdst = 0;
for (index=1; index<=nsize2; ++index) {
dist = whose[index] & 255;
if (dist > mxdst) {
if ((edgedist[index] > 4)) {
mxdst = dist;
}
}
}
if (col80) {
newline();
printf(" mxdst: %d", mxdst);
}
if (mxdst >= 7) {
if (col80) {
newline();
printf(" postfu");
}
indexes = xtinsert(0, 0);
/* specify universe here */
befo = 1;
if (kount > 100) befo = 0;
if (befo) {
indexp = indexes;
for (index=1; index<=nsize2; ++index) {
if (!dir[index]) {
if (edgedist[index] > 4) {
if ((whose[index]&255) >= (mxdst-1)) {
indexp = xtlocate(index, indexp);
indexp = xtinsert(index, indexp);
}
}
}
}
}
else {
indexp = indexes;
for (index=1; index<=nsize2; ++index) {
if (dir[index]) {
if (dir[index]->clr == player) {
for (dist=2; dist<=5; ++dist) oring(index, dist, indexes);
}
else {
if (((kount/2)/4)*4 == (kount/2)) {
for (dist=2; dist<=6; ++dist) oring(index, dist, indexes);
}
}
}
}
}
indexp = peek(indexes, NEXTL);
if (indexp) {
do {
index = peek(indexp, LOC);
poke(indexp, LEVEL, NEGINF);
if (1) { /*!edge(index)) {*/
bogus = 0;
value = 0;
score = 0;
valid = doit(index);
if (valid) {
/*if (!dir[index]->reallive) bogus = 1;*/
evaluate();
value = scoresph();
if (!bogus) poke(indexp, LEVEL, value);
index = undoit();
}
if (valid && !bogus) {
if (value) {
value += scoresph();
/*value -= BIAS;*/
doit(0);
valid = doit(index);
if (valid) {
evaluate();
/*value += BIAS;*/
value -= scoresph();
score = value;
poke(indexp, LEVEL, score);
index = undoit();
}
undoit();
}
}
}
indexp = peek(indexp, NEXTL);
} while (indexp && !attn);
}
maxsort(indexes);
alloff();
if (col80) {
indexp = peek(indexes, NEXTS);
if (indexp) {
i = 0;
do {
if (!(i % 3)) {
newline();
}
++i;
coords(peek(indexp, LOC));
printf(" %-5d ", peek(indexp, LEVEL));
indexp = peek(indexp, NEXTS);
if (i > 52) {
indexp = 0;
printf(" ..more");
}
} while (indexp);
indexp = peek(indexes, NEXTS);
}
}
indexp = peek(indexes, NEXTS);
if (indexp) {
gotone = 0;
do {
index = peek(indexp, LOC);
score = peek(indexp, LEVEL);
if (score) {
iscon = 0;
doit(0);
valid = doit(index);
if (valid) {
if (!akill(index)) {
iscon = 1;
}
index = undoit();
}
undoit();
if (iscon) { /*gotopp) {*/
valid = doit(index);
if (valid) {
if (1) {
/* every fourth move need not be connected */
iscon = 1;
if (!befo) {
if ((((kount/2)/4)*4 != (kount/2))) iscon = connected(index);
}
if (iscon) {
killers = xtinsert(0, 0);
if (!akill(index)) {
if (!forkaji(index, killers)) {
gotone = 1;
wienerp = xtlocate(index, wienerp);
wienerp = xtinsert(index, wienerp);
poke(wienerp, LEVEL, score);
if (score > maxscore) maxscore = score;
}
}
xtfreelist(killers);
}
}
index = undoit();
}
}
}
indexp = peek(indexp, NEXTS);
} while (indexp && !gotone);
}
xtfreelist(indexes);
/*if (maxscore) break;*/
}
maxsort(wieners);
return(maxscore);
}
int bestyose(unsigned wieners)
{
unsigned index;
unsigned maxscore;
unsigned score, baseline, dist;
unsigned wienerp, indexes, indexp;
unsigned jndex, jndexes, which, killer, oldsphr, gotone, gotopp;
unsigned killers, cankill;
unsigned befo, iscon, madmove;
int i, value, bogus;
alloff();
eyeson = 1;
sphron = 1;
wienerp = wieners;
maxscore = 0;
/* play eye-killers and sort best score first */
for (which=1; which<=1; ++which) {
madmove = ((kount/3)*3 == kount);
if (col80) {
newline();
printf(" best madmove:%d", madmove);
}
indexes = xtinsert(0, 0);
/* specify universe here */
befo = 1;
if (kount > 100) befo = 0;
befo = 0;
if (madmove) {
indexp = indexes;
for (index=1; index<=nsize2; ++index) {
if (!dir[index]) {
if (!edge(index)) {
indexp = xtlocate(index, indexp);
indexp = xtinsert(index, indexp);
}
}
}
}
else {
indexp = indexes;
for (index=1; index<=nsize2; ++index) {
if ((whose[index]&255) <= 5) {
if ((whose[index]&255) >= 2) {
/*if ((whose[index]>>8 == player) || !(whose[index]>>8)) {*/
indexp = xtlocate(index, indexp);
indexp = xtinsert(index, indexp);
/*}*/
}
}
}
}
indexp = peek(indexes, NEXTL);
if (indexp) {
do {
index = peek(indexp, LOC);
poke(indexp, LEVEL, NEGINF);
if ((!madmove && perisphr[index]) || madmove) {
bogus = 0;
value = 0;
score = 0;
valid = doit(index);
if (valid) {
/*if (!dir[index]->reallive) bogus = 1;*/
evaluate();
value = scoresph();
if (!bogus) poke(indexp, LEVEL, value);
index = undoit();
}
if (madmove && valid && !bogus) {
if (value) {
value += scoresph();
/*value -= BIAS;*/
doit(0);
valid = doit(index);
if (valid) {
evaluate();
/*value += BIAS;*/
value -= scoresph();
score = value;
poke(indexp, LEVEL, score);
index = undoit();
}
undoit();
}
}
}
indexp = peek(indexp, NEXTL);
} while (indexp && !attn);
}
maxsort(indexes);
alloff();
if (col80) {
indexp = peek(indexes, NEXTS);
if (indexp) {
i = 0;
do {
if (!(i % 3)) {
newline();
}
++i;
coords(peek(indexp, LOC));
printf(" %-5d ", peek(indexp, LEVEL));
indexp = peek(indexp, NEXTS);
if (i > 52) {
indexp = 0;
printf(" ..more");
}
} while (indexp);
indexp = peek(indexes, NEXTS);
/*
do {
if (peek(indexp, LEVEL) == value) curon(peek(indexp, LOC));
indexp = peek(indexp, NEXTS);
} while (indexp);
*/
}
}
indexp = peek(indexes, NEXTS);
if (indexp) {
gotone = 0;
do {
index = peek(indexp, LOC);
score = peek(indexp, LEVEL);
if (score) {
iscon = 0;
doit(0);
valid = doit(index);
if (valid) {
if (!akill(index)) {
iscon = 1;
}
index = undoit();
}
undoit();
if (iscon) {
valid = doit(index);
if (valid) {
if (1) {
iscon = 1;
if (!befo) {
if (!madmove) iscon = connected(index);
}
if (iscon) {
killers = xtinsert(0, 0);
if (!akill(index)) {
if (!forkaji(index, killers)) {
gotone = 1;
wienerp = xtlocate(index, wienerp);
wienerp = xtinsert(index, wienerp);
poke(wienerp, LEVEL, score);
if (score > maxscore) maxscore = score;
}
}
xtfreelist(killers);
}
}
index = undoit();
}
}
}
indexp = peek(indexp, NEXTS);
} while (indexp && !gotone);
}
xtfreelist(indexes);
/*if (maxscore) break;*/
}
maxsort(wieners);
return(maxscore);
}
int worst(unsigned wieners)
{
unsigned index;
unsigned minscore;
unsigned score, baseline;
unsigned wienerp, indexes, indexp;
unsigned jndexes, which, killer, oldmax3, gotone, gotopp;
unsigned killers;
int i, value;
oldmax3 = max3;
wienerp = wieners;
minscore = POSINF;
/* play eye-killers and sort best score first */
for (which=1; which<=6; ++which) {
newline();
printf(" worst which %d", which);
indexes = xtinsert(0, 0);
maxsort(indexes);
/*
if (which == 1) stealer(indexes);
if (which == 2) ikken(indexes);
if (which == 3) angle(indexes);
if (which == 4) conflict(indexes);
if (which == 5) deadeye(indexes);
if (which == 6) oppeye(indexes);
*/
/*
indexp = indexes;
for (i=1; i<=nsize2; ++i) {
if (!dir[i]) {
indexp = xtlocate(i, indexp);
indexp = xtinsert(i, indexp);
}
}
*/
/*
index = movep->midx;
if (index) {
for (i=2; i<=5; ++i) oring(index, i, indexes);
}
if (movep->prevm) {
index = movep->prevm->midx;
if (index) {
for (i=2; i<=5; ++i) oring(index, i, indexes);
}
}