/* liberty not close to opponent (?:eye) */
#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"
unsigned getlib(unsigned index, unsigned bw)
{
unsigned val;
unsigned far *farp;
farp = lib;
if (bw == WHT) farp += nsize21;
farp += index;
val = *farp;
return(val);
}
void setlib(unsigned index, unsigned bw, unsigned val)
{ /* put val in eye info */
unsigned seg, off;
unsigned far *farp;
farp = lib;
if (bw == WHT) farp += nsize21;
farp += index;
seg = FP_SEG(farp);
off = FP_OFF(farp);
if (peek(seg, off) != val) {
uzxlmod(seg, off, val); /* put change in transaction list */
}
}
unsigned geteye(unsigned index, unsigned bw)
{
unsigned val;
unsigned far *farp;
farp = eye;
if (bw == WHT) farp += nsize21;
farp += index;
val = *farp;
return(val);
}
void seteye(unsigned index, unsigned bw, unsigned val)
{ /* put val in eye info */
unsigned seg, off;
unsigned far *farp;
farp = eye;
if (bw == WHT) farp += nsize21;
farp += index;
seg = FP_SEG(farp);
off = FP_OFF(farp);
if (peek(seg, off) != val) {
uzxlmod(seg, off, val); /* put change in transaction list */
}
}
unsigned getceye(unsigned index, unsigned bw)
{
unsigned val;
unsigned far *farp;
farp = coneye;
if (bw == WHT) farp += nsize21;
farp += index;
val = *farp;
return(val);
}
void setceye(unsigned index, unsigned bw, unsigned val)
{ /* put val in coneye info */
unsigned seg, off;
unsigned far *farp;
farp = coneye;
if (bw == WHT) farp += nsize21;
farp += index;
seg = FP_SEG(farp);
off = FP_OFF(farp);
if (peek(seg, off) != val) {
uzxlmod(seg, off, val); /* put change in transaction list */
}
}
unsigned getoeye(unsigned index, unsigned bw)
{
unsigned val;
unsigned far *farp;
farp = oneeye;
if (bw == WHT) farp += nsize21;
farp += index;
val = *farp;
return(val);
}
void setoeye(unsigned index, unsigned bw, unsigned val)
{ /* put val in oneeye (false eye) info */
unsigned seg, off;
unsigned far *farp;
farp = oneeye;
if (bw == WHT) farp += nsize21;
farp += index;
seg = FP_SEG(farp);
off = FP_OFF(farp);
if (peek(seg, off) != val) {
uzxlmod(seg, off, val); /* put change in transaction list */
}
}
unsigned getgeye(unsigned index, unsigned bw)
{
unsigned val;
unsigned far *farp;
farp = gudeye;
if (bw == WHT) farp += nsize21;
farp += index;
val = *farp;
return(val);
}
void setgeye(unsigned index, unsigned bw, unsigned val)
{ /* put val in oneeye (false eye) info */
unsigned seg, off;
unsigned far *farp;
farp = gudeye;
if (bw == WHT) farp += nsize21;
farp += index;
seg = FP_SEG(farp);
off = FP_OFF(farp);
if (peek(seg, off) != val) {
uzxlmod(seg, off, val); /* put change in transaction list */
}
}
unsigned evalib(unsigned index, unsigned bw)
{
unsigned val;
unsigned *point, jndex, i;
val = 0;
if (!dir[index]) {
point = NEWS(index);
for (i=0; i<NLIBS; ++i) {
jndex = *point;
if (jndex) {
if (dir[jndex]) {
if (dir[jndex]->clr == bw) val = 1;
}
}
++point;
if (val) break;
}
}
return(val);
}
unsigned evalcon(unsigned index, unsigned bw)
{
unsigned contested;
unsigned i, jndex, opp, *point;
contested = 0;
if (geteye(index, bw)) {
opp = flip(bw);
point = NEWS(index);
for (i=0; i<NLIBS; ++i) {
jndex = *point;
if (jndex) {
if (geteye(jndex, opp)) contested = 1;
}
++point;
if (contested) break;
}
}
return(contested);
}
unsigned findiz(struct root *rootp, unsigned oneyes, unsigned ilist)
{
unsigned alive;
unsigned ip, jp, oneyep;
unsigned index, jndex, goteye, who;
struct link *libp;
alive = 0;
oneyep = oneyes;
who = rootp->clr;
ip = ilist;
libp = rootp->liberties->nextl;
do {
goteye = 0;
index = libp->loc;
oneyep = xtlocate(index, oneyep);
if (!xtmember(index, oneyep)) {
/*if (!getoeye(index, who)) {*/
if (geteye(index, who)) {
if (!getceye(index, who)) {
goteye = 1;
ip = xtlocate(index, ip);
ip = xtinsert(index, ip);
}
}
}
if (goteye) {
jp = peek(ilist, NEXTL);
if (jp) {
if (peek(jp, NEXTL)) {
do {
jndex = peek(jp, LOC);
if (!adjacent(index, jndex)) alive = 1;
jp = peek(jp, NEXTL);
if (jp) {
if (!peek(jp, NEXTL)) jp = 0;
}
} while (jp && !alive);
}
}
}
libp = libp->nextl;
} while (libp && !alive);
return(alive);
}
void fdeyes(unsigned rlist, unsigned bw, unsigned oldones)
{ /* include dead roots in rlist via false eyes making oldones */
unsigned i, ptr, oldp;
unsigned newrs, newrp;
unsigned jndex, kndex, *point;
unsigned oi, da;
unsigned gotone;
struct root *rootp, *rootr;
struct link *libp;
do {
gotone = 0;
oldp = oldones;
newrs = xtinsert(0, 0);
newrp = newrs;
ptr = peek(rlist, NEXTL);
if (ptr) {
do {
rootr = peek(ptr, LOC);
libp = rootr->liberties->nextl;
do {
kndex = libp->loc;
oi = getoeye(kndex, bw);
if (oi) {
oldp = xtlocate(kndex, oldp);
if (!xtmember(kndex, oldp)) {
oldp = xtinsert(kndex, oldp);
point = NEWS(kndex);
for (i=0; i<NLIBS; ++i) {
jndex = *point;
if (jndex) {
rootp = dir[jndex];
if (rootp) {
if (rootp->clr == bw) {
da = rootp->reallive;
if (!da) {
newrp = xtlocate(rootp, newrp);
if (!xtmember(rootp, xtlocate(rootp, rlist))) {
newrp = xtinsert(rootp, newrp);
gotone = 1;
}
}
}
}
}
++point;
}
}
}
libp = libp->nextl;
} while (libp);
ptr = peek(ptr, NEXTL);
} while (ptr);
newrp = peek(newrs, NEXTL);
if (newrp) {
ptr = rlist;
do {
rootp = peek(newrp, LOC);
ptr = xtlocate(rootp, ptr);
ptr = xtinsert(rootp, ptr);
poke(ptr, LEVEL, 1);
newrp = peek(newrp, NEXTL);
} while (newrp);
}
}
xtfreelist(newrs);
} while (gotone);
}
unsigned evaldead(unsigned rlist, unsigned bw, unsigned oneyes)
{
unsigned gotone;
unsigned index;
unsigned rlistp;
unsigned ilist, ilistp;
unsigned fp;
unsigned newrs, newrp;
unsigned i, jndex, *point;
unsigned liveflag;
unsigned oldones;
unsigned alive, da;
struct root *rootp;
gotone = 0;
rlistp = peek(rlist, NEXTL);
if (rlistp) {
newrs = xtinsert(0, 0);
newrp = newrs;
do {
liveflag = peek(rlistp, LEVEL);
if (liveflag) {
rootp = peek(rlistp, LOC);
ilist = xtinsert(0, 0);
alive = findiz(rootp, oneyes, ilist);
if (!alive) {
poke(rlistp, LEVEL, 0);
ilistp = peek(ilist, NEXTL);
if (ilistp) {
gotone = 1;
fp = oneyes;
do {
index = peek(ilistp, LOC);
fp = xtlocate(index, fp);
if (!xtmember(index, fp)) {
fp = xtinsert(index, fp);
point = NEWS(index);
for (i=0; i<NLIBS; ++i) {
jndex = *point;
if (jndex) {
rootp = dir[jndex];
if (rootp) {
if (rootp->clr == bw) {
newrp = xtlocate(rootp, newrp);
if (!xtmember(rootp, xtlocate(rootp, rlist))) {
newrp = xtinsert(rootp, newrp);
}
}
}
}
++point;
}
}
ilistp = peek(ilistp, NEXTL);
} while (ilistp);
}
}
xtfreelist(ilist);
}
rlistp = peek(rlistp, NEXTL);
} while (rlistp);
newrp = peek(newrs, NEXTL);
if (newrp) {
rlistp = rlist;
do {
rootp = peek(newrp, LOC);
rlistp = xtlocate(rootp, rlistp);
rlistp = xtinsert(rootp, rlistp);
poke(rlistp, LEVEL, 1);
newrp = peek(newrp, NEXTL);
} while (newrp);
}
xtfreelist(newrs);
}
if (gotone) {
oldones = xtinsert(0, 0);
fdeyes(rlist, bw, oldones);
xtfreelist(oldones);
gotone = evaldead(rlist, bw, oneyes);
}
return(gotone);
}
unsigned special(struct root *rootp, unsigned libexes)
{
unsigned realdead;
unsigned libexp, index, jndex, deaddead;
struct link *ctcp, *libp;
struct root *rootq;
deaddead = 1;
ctcp = rootp->contacts->nextl;
if (ctcp) {
libexp = libexes;
do {
jndex = ctcp->loc;
rootq = dir[jndex];
if (!rootq->reallive) {
deaddead = 0;
libp = rootq->liberties->nextl;
do {
index = libp->loc;
libexp = xtlocate(index, libexp);
libexp = xtinsert(index, libexp);
poke(libexp, LEVEL, rootq->clr);
libp = libp->nextl;
} while (libp);
}
ctcp = ctcp->nextl;
} while (ctcp && deaddead);
}
return(deaddead);
}
void mkeyes(index)
unsigned index;
{
unsigned *point;
unsigned diagvec[NDIAGS];
unsigned llist[3], ptl[3];
int neyes[3];
unsigned i, jndex, kndex, num, oldnum, da, oi, bval, wval;
unsigned indexp, indexes, who;
unsigned rlist, ptr;
unsigned oneyes, oneyep, llistp;
unsigned oldones, oldonep;
unsigned self, opp, bw;
unsigned speclibs, speclibp, dbsto, dwsto, dblib, dwlib;
unsigned deaddead;
struct root *rootp, *rooti;
struct link *stonep;
struct link *libp;
struct link *capp;
struct link *rlistp;
if (!eyeson) return;
if (!index) return;
self = colour;
opp = flip(self);
llist[BLK] = xtinsert(0, 0);
ptl[BLK] = llist[BLK];
llist[WHT] = xtinsert(0, 0);
ptl[WHT] = llist[WHT];
rooti = dir[index];
setlib(index, self, 0);
seteye(index, self, 0);
setceye(index, self, 0);
setoeye(index, self, 0);
if (rooti) {
setlib(index, opp, 0);
seteye(index, opp, 0);
setceye(index, opp, 0);
setoeye(index, opp, 0);
/* next process the liberty (or contact) points around index */
point = NEWS(index);
for (i=0; i<NLIBS; ++i) {
jndex = *point;
if (jndex) {
if (!dir[jndex]) {
for (bw=BLK; bw<=WHT; ++bw) {
oldnum = getlib(jndex, bw);
num = evalib(jndex, bw);
if (num != oldnum) {
ptl[bw] = xtlocate(jndex, ptl[bw]);
ptl[bw] = xtinsert(jndex, ptl[bw]);
setlib(jndex, bw, num);
}
oldnum = geteye(jndex, bw);
num = evaleye(jndex, bw);
if (num != oldnum) {
seteye(jndex, bw, num);
}
if ((num && !oldnum) || (!num && oldnum)) {
ptl[bw] = xtlocate(jndex, ptl[bw]);
ptl[bw] = xtinsert(jndex, ptl[bw]);
}
}
}
}
++point;
}
/* process the diagonal points around index */
diags(index, diagvec);
point = diagvec;
for (i=0; i<NDIAGS; ++i) {
jndex = *point;
if (jndex) {
if (!dir[jndex]) {
bw = opp;
oldnum = geteye(jndex, bw);
num = evaleye(jndex, bw);
if (num != oldnum) {
seteye(jndex, bw, num);
}
if ((num && !oldnum) || (!num && oldnum)) {
ptl[bw] = xtlocate(jndex, ptl[bw]);
ptl[bw] = xtinsert(jndex, ptl[bw]);
}
}
}
++point;
}
/* process the captures made by index */
capp = movep->caps->nextl;
if (capp) {
do {
rootp = capp->loc;
/* process captures themselves */
stonep = rootp->neighbs->nextl;
do {
jndex = stonep->loc;
if (jndex) {
if (!dir[jndex]) {
for (bw=BLK; bw<=WHT; ++bw) {
oldnum = getlib(jndex, bw);
num = evalib(jndex, bw);
if (num != oldnum) {
ptl[bw] = xtlocate(jndex, ptl[bw]);
ptl[bw] = xtinsert(jndex, ptl[bw]);
setlib(jndex, bw, num);
}
oldnum = geteye(jndex, bw);
num = evaleye(jndex, bw);
if (num != oldnum) {
seteye(jndex, bw, num);
}
if ((num && !oldnum) || (!num && oldnum)) {
ptl[bw] = xtlocate(jndex, ptl[bw]);
ptl[bw] = xtinsert(jndex, ptl[bw]);
}
}
}
}
stonep = stonep->nextl;
} while (stonep);
capp = capp->nextl;
} while (capp);
}
}
/* process the captures made by Chinese suicide */
capp = movep->suicaps->nextl;
if (capp) {
/* reprocess index separately */
jndex = index;
if (!dir[jndex]) {
for (bw=BLK; bw<=WHT; ++bw) {
oldnum = getlib(jndex, bw);
num = evalib(jndex, bw);
if (num != oldnum) {
ptl[bw] = xtlocate(jndex, ptl[bw]);
ptl[bw] = xtinsert(jndex, ptl[bw]);
setlib(jndex, bw, num);
}
oldnum = geteye(jndex, bw);
num = evaleye(jndex, bw);
if (num != oldnum) {
ptl[bw] = xtlocate(jndex, ptl[bw]);
ptl[bw] = xtinsert(jndex, ptl[bw]);
seteye(jndex, bw, num);
}
}
}
do {
rootp = capp->loc;
stonep = rootp->neighbs->nextl;
do {
jndex = stonep->loc;
if (jndex) {
if (!dir[jndex]) {
for (bw=BLK; bw<=WHT; ++bw) {
oldnum = getlib(jndex, bw);
num = evalib(jndex, bw);
if (num != oldnum) {
ptl[bw] = xtlocate(jndex, ptl[bw]);
ptl[bw] = xtinsert(jndex, ptl[bw]);
setlib(jndex, bw, num);
}
oldnum = geteye(jndex, bw);
num = evaleye(jndex, bw);
if (num != oldnum) {
ptl[bw] = xtlocate(jndex, ptl[bw]);
ptl[bw] = xtinsert(jndex, ptl[bw]);
seteye(jndex, bw, num);
}
}
}
}
stonep = stonep->nextl;
} while (stonep);
capp = capp->nextl;
} while (capp);
}
/* update conflicting eye info */
indexes = xtinsert(0, 0);
indexp = indexes;
ring(index, 2, indexp);
ring(index, 3, indexp);
ring(index, 4, indexp);
ring(index, 5, indexp);
indexp = peek(indexes, NEXTL);
if (indexp) {
do {
jndex = peek(indexp, LOC);
if (jndex) {
if (!dir[jndex]) {
for (bw=BLK; bw<=WHT; ++bw) {
oldnum = getceye(jndex, bw);
num = evalcon(jndex, bw);
if (num != oldnum) {
setceye(jndex, bw, num);
ptl[bw] = xtlocate(jndex, ptl[bw]);
ptl[bw] = xtinsert(jndex, ptl[bw]);
}
}
}
}
indexp = peek(indexp, NEXTL);
} while (indexp);
}
xtfreelist(indexes);
for (bw=BLK; bw<=WHT; ++bw) {
rlist = xtinsert(0, 0);
oldones = xtinsert(0, 0);
oneyes = xtinsert(0, 0);
indexes = xtinsert(0, 0);
speclibs = xtinsert(0, 0);
ptr = rlist;
if ((bw == self) && rooti) {
ptr = xtlocate(rooti, ptr);
ptr = xtinsert(rooti, ptr);
poke(ptr, LEVEL, 1);
}
if ((bw == opp) && rooti) {
point = NEWS(index);
for (i=0; i<NLIBS; ++i) {
jndex = *point;
if (jndex) {
rootp = dir[jndex];
if (rootp) {
if (rootp->clr == bw) {
ptr = xtlocate(rootp, ptr);
ptr = xtinsert(rootp, ptr);
poke(ptr, LEVEL, 1);
}
}
}
++point;
}
}
/* put affected roots in rlist LEVEL=1 indicates life */
llistp = llist[bw];
llistp = peek(llistp, NEXTL);
if (llistp) {
do {
kndex = peek(llistp, LOC);
point = NEWS(kndex);
for (i=0; i<NLIBS; ++i) {
jndex = *point;
if (jndex) {
rootp = dir[jndex];
if (rootp) {
if (rootp->clr == bw) {
ptr = xtlocate(rootp, ptr);
ptr = xtinsert(rootp, ptr);
poke(ptr, LEVEL, 1);
}
}
}
++point;
}
llistp = peek(llistp, NEXTL);
} while (llistp);
}
fdeyes(rlist, bw, oldones); /* include dead roots via false eyes */
evaldead(rlist, bw, oneyes);
ptr = peek(rlist, NEXTL);
if (ptr) {
do {
rootp = (struct root *) peek(ptr, LOC);
da = peek(ptr, LEVEL);
if (rootp->reallive != da) uzgvmod(&rootp->reallive, da);
ptr = peek(ptr, NEXTL);
} while (ptr);
}
oneyep = peek(oneyes, NEXTL);
if (oneyep) {
do {
jndex = peek(oneyep, LOC);
oi = getoeye(jndex, bw);
if (!oi) setoeye(jndex, bw, 1);
oneyep = peek(oneyep, NEXTL);
} while (oneyep);
}
oldonep = peek(oldones, NEXTL);
if (oldonep) {
oneyep = oneyes;
do {
jndex = peek(oldonep, LOC);
oneyep = xtlocate(jndex, oneyep);
if (!xtmember(jndex, oneyep)) setoeye(jndex, bw, 0);
oldonep = peek(oldonep, NEXTL);
} while (oldonep);
}
/* score-keeping for count of good eyes and dead stones */
/* count dead stones globally noting special ones .. */
/* if contacts all live, count liberties and deads count twice */
dbsto = 0;
dwsto = 0;
dblib = 0;
dwlib = 0;
bval = 0;
wval = 0;
rlistp = rootlist->nextl;
if (rlistp) {
do {
rootp = rlistp->loc;
deaddead = 0;
if (!rootp->reallive) {
if (!rootp->realdead) {
if (rootp->clr == WHT) wval += rootp->nsto;
else bval += rootp->nsto;
}
deaddead = special(rootp, speclibs);
if (deaddead) {
if (rootp->clr == WHT) dwsto += rootp->nsto;
else dbsto += rootp->nsto;
}
}
if (deaddead != rootp->realdead) uzgvmod(&rootp->realdead, deaddead);
rlistp = rlistp->nextl;
} while (rlistp);
speclibp = peek(speclibs, NEXTL);
if (speclibp) {
do {
if (peek(speclibp, LEVEL) == WHT) ++dwlib;
else ++dblib;
speclibp = peek(speclibp, NEXTL);
} while (speclibp);
}
}
uzgvmod(&sekisto[BLK], bval);
uzgvmod(&sekisto[WHT], wval);
uzgvmod(&deadsto[BLK], dbsto);
uzgvmod(&deadsto[WHT], dwsto);
uzgvmod(&deadlib[BLK], dblib);
uzgvmod(&deadlib[WHT], dwlib);
/* make list of liberties of roots in rlist for eye count */
neyes[BLK] = eyeterr[BLK];
neyes[WHT] = eyeterr[WHT];
indexp = indexes;
indexp = xtlocate(index, indexp);
indexp = xtinsert(index, indexp);
ptr = peek(rlist, NEXTL);
if (ptr) {
do {
rootp = peek(ptr, LOC);
libp = rootp->liberties->nextl;
do {
jndex = libp->loc;
indexp = xtlocate(jndex, indexp);
indexp = xtinsert(jndex, indexp);
libp = libp->nextl;
} while (libp);
ptr = peek(ptr, NEXTL);
} while (ptr);
indexp = peek(indexes, NEXTL);
do {
jndex = peek(indexp, LOC);
num = getgeye(jndex, bw);
oi = 0;
if (geteye(jndex, bw)) {
if (!getceye(jndex, bw)) {
if (!getoeye(jndex, bw)) oi = 1;
}
}
if (!num && oi) ++neyes[bw];
if (num && !oi) --neyes[bw];
if (num != oi) setgeye(jndex, bw, oi);
indexp = peek(indexp, NEXTL);
} while (indexp);
uzgvmod(&eyeterr[BLK], neyes[BLK]);
uzgvmod(&eyeterr[WHT], neyes[WHT]);
neyes[BLK] += wcaps + dwsto + dwsto + dwlib;
neyes[WHT] += bcaps + dbsto + dbsto + dblib;
uzgvmod(&eyescore[BLK], neyes[BLK]);
uzgvmod(&eyescore[WHT], neyes[WHT]);
}
xtfreelist(speclibs);
xtfreelist(indexes);
xtfreelist(rlist);
xtfreelist(oldones);
xtfreelist(oneyes);
}
xtfreelist(llist[BLK]);
xtfreelist(llist[WHT]);
}
/*
void audeye()
{
/* use obsolete global eyes() to check mkeyes() */
/* flaw:if mkeyes indicates null then this method will not report */
unsigned da, oi;
unsigned i, ptr, bw, pass;
struct link *rootlp;
struct root *rootp;
unsigned index, bval, wval;
if (col80) {
newline();
printf(" auditing eyes");
}
pass = 1;
rootlp = rootlist->nextl;
if (rootlp) {
ptr = movep->deaders;
do {
rootp = rootlp->loc;
if (!rootp->reallive) {
ptr = peek(ptr, NEXTL);
if (ptr) {
if (!xtmember(rootp, ptr)) pass = 0;
}
else pass = 0;
}
rootlp = rootlp->nextl;
} while (rootlp && pass);
}
if (!pass) {
newline();
printf("audeye: fails! dead roots");
sound(500);
hundelay(200);
nosound();
}
pass = 1;
ptr = movep->falseye;
for (i=1; i<=nsize2; ++i) {
oi = getoeye(i, BLK) + getoeye(i, WHT);
if (oi) {
ptr = peek(ptr, NEXTL);
if (ptr) {
if (!xtmember(i, ptr)) pass = 0;
}
else pass = 0;
}
}
if (!pass) {
newline();
printf("audeye: fails! one-eyes");
sound(400);
hundelay(200);
nosound();
}
pass = 1;
bval = 0;
wval = 0;
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;
}
}
}
}
}
if (bval != eyeterr[BLK]) pass = 0;
if (wval != eyeterr[WHT]) pass = 0;
if (!pass) {
newline();
printf("audeye: fails! eyeterr");
sound(400);
hundelay(200);
nosound();
}
}
*/