#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 bitson(maxcount, count, numbits, bitvec)
unsigned maxcount, count, numbits;
unsigned bitvec[16];
{
unsigned success;
unsigned numtest, test, mask, bitno;
success = 0;
test = count;
numtest = 0;
mask = 1;
bitno = 0;
do {
bitvec[bitno] = 0;
if (test & mask) {
++numtest;
bitvec[bitno] = 1;
}
mask += mask;
++bitno;
} while (mask < maxcount);
if (numtest == numbits) success = 1;
return(success);
}
void makejig(index, jig)
unsigned index;
unsigned jig[37];
{
unsigned jndex;
jndex = north(north(north(index)));
jig[1] = west(jndex);
jig[2] = jndex;
jig[3] = east(jndex);
jndex = north(north(index));
jig[4] = west(west(jndex));
jig[5] = west(jndex);
jig[6] = jndex;
jig[7] = east(jndex);
jig[8] = east(east(jndex));
jndex = north(index);
jig[9] = west(west(west(jndex)));
jig[10] = west(west(jndex));
jig[11] = west(jndex);
jig[12] = jndex;
jig[13] = east(jndex);
jig[14] = east(east(jndex));
jig[15] = east(east(east(jndex)));
jndex = index;
jig[16] = west(west(west(jndex)));
jig[17] = west(west(jndex));
jig[18] = west(jndex);
jig[19] = east(jndex);
jig[20] = east(east(jndex));
jig[21] = east(east(east(jndex)));
jndex = south(index);
jig[22] = west(west(west(jndex)));
jig[23] = west(west(jndex));
jig[24] = west(jndex);
jig[25] = jndex;
jig[26] = east(jndex);
jig[27] = east(east(jndex));
jig[28] = east(east(east(jndex)));
jndex = south(south(index));
jig[29] = west(west(jndex));
jig[30] = west(jndex);
jig[31] = jndex;
jig[32] = east(jndex);
jig[33] = east(east(jndex));
jndex = south(south(south(index)));
jig[34] = west(jndex);
jig[35] = jndex;
jig[36] = east(jndex);
}
unsigned template(index, jig)
unsigned index;
unsigned jig[37];
{
unsigned i, idx;
idx = 0;
for (i=1; i<=36; ++i) {
if (jig[i] == index) {
idx = i;
i = 36;
}
}
return(idx);
}
void setbit(bitno, being)
unsigned bitno;
unsigned being[3];
{
unsigned iword, ibit, imask, i;
--bitno;
iword = bitno / 16;
ibit = bitno - iword * 16;
imask = 1;
if (ibit) for (i=1; i<=ibit; ++i) imask += imask;
being[iword] = being[iword] | imask;
}
void encode(indexes, jig, being)
unsigned indexes;
unsigned jig[37];
unsigned being[3];
{
unsigned bitno, i, index, indexp;
being[0] = 0;
being[1] = 0;
being[2] = 0;
indexp = peek(indexes, NEXTL);
if (indexp) {
do {
index = peek(indexp, LOC);
bitno = template(index, jig);
setbit(bitno, being);
indexp = peek(indexp, NEXTL);
} while (indexp);
}
}
void decode(being, jig, indexes)
unsigned being[3];
unsigned jig[37];
unsigned indexes;
{
unsigned bitno, i, index, indexp;
unsigned imask, iword, ibit;
indexp = indexes;
bitno = 0;
for (iword=0; iword<=2; ++iword) {
imask = 1;
for (ibit=0; ibit<=15; ++ibit) {
++bitno;
if (being[iword] & imask) {
index = jig[bitno];
indexp = xtlocate(index, indexp);
indexp = xtinsert(index, indexp);
}
imask += imask;
}
}
}
unsigned subset(being, other) /* true if being is subset of other */
unsigned being[3];
unsigned other[3];
{
unsigned match;
unsigned imask, iword, ibit;
match = 1;
for (iword=0; iword<=2; ++iword) {
imask = 1;
for (ibit=0; ibit<=15; ++ibit) {
if (being[iword] & imask) {
if (!(other[iword] & imask)) match = 0;
}
imask += imask;
}
}
return(match);
}
void minlife(forms)
unsigned forms;
{
unsigned formp, being[3], formb, other[3];
formp = peek(forms, NEXTL);
if (formp) {
do {
being[0] = peek(formp, (LEVEL+2));
being[1] = peek(formp, (LEVEL+4));
being[2] = peek(formp, (LEVEL+6));
formb = peek(forms, NEXTL);
if (formb) {
do {
if (formb != formp) {
other[0] = peek(formb, (LEVEL+2));
other[1] = peek(formb, (LEVEL+4));
other[2] = peek(formb, (LEVEL+6));
if (subset(being, other)) formb = xtdelete(formb);
}
formb = peek(formb, NEXTL);
} while (formb);
}
formp = peek(formp, NEXTL);
} while (formp);
}
}
void showforms(index)
unsigned index;
{
unsigned forms, formp;
unsigned livers, being[3], indexes;
unsigned jig[37];
makejig(index, jig);
forms = bugs[index];
if (forms && col80) {
formp = peek(forms, NEXTL);
if (formp) {
livers = 0;
do {
++livers;
being[0] = peek(formp, (LEVEL+2));
being[1] = peek(formp, (LEVEL+4));
being[2] = peek(formp, (LEVEL+6));
indexes = xtinsert(0,0);
decode(being, jig, indexes);
board();
xtturnon(indexes);
hundelay(timer);
xtfreelist(indexes);
formp = peek(formp, NEXTL);
/*keybreak(0);*/
} while (formp && !attn);
board();
}
}
}
void showguy(stringuy, ntot)
unsigned stringuy[12], ntot;
{
int iguy;
board();
for (iguy=1; iguy<=ntot; ++iguy) curon(stringuy[iguy]);
}
/*
void belive(jndex, otheye, being, jig, index, bw)
unsigned jndex; /* primary eye of being (index != jndex) */
unsigned otheye; /* other eye (index ?= otheye possibly) */
unsigned being[3];
unsigned jig[37];
unsigned index; /* position of bw stone (to be played) */
unsigned bw; /* bw is BLK or WHT */
{
unsigned allowed;
unsigned bitno, i, kndex, incontext;
unsigned imask, iword, ibit;
struct root *rootp;
unsigned iguy, stringuy[12], ntot, ntogo, nocc;
allowed = 1;
ntot = 0;
ntogo = 0;
nocc = 0;
bitno = 0;
incontext = 0;
/* assemble being into stringuy and check damage to bw's opponent */
rootp = dir[otheye];
if (rootp) {
if (rootp->clr != bw) allowed = 0;
}
rootp = dir[jndex];
if (rootp) {
if (rootp->clr != bw) allowed = 0;
}
for (iword=0; iword<=2; ++iword) {
imask = 1;
for (ibit=0; ibit<=15; ++ibit) {
++bitno;
if (being[iword] & imask) {
kndex = jig[bitno];
if (kndex) {
++ntot;
stringuy[ntot] = kndex;
if (kndex == index) incontext = 1;
rootp = dir[kndex];
if (!rootp) {
++ntogo;
}
if (rootp) {
++nocc;
if (bw == rootp->clr) {
allowed = 0;
}
}
}
}
imask += imask;
}
}
if (allowed && incontext) {
if (nocc && ntogo) {
for (iguy=1; iguy<=ntot; ++iguy) {
kndex = stringuy[iguy];
if (!dir[kndex]) {
if (bw == BLK) wstovote[kndex] -= nocc;
else bstovote[kndex] -= nocc;
}
}
/* remove eyevotes from disallowed lifeforms */
if (bw == BLK) {
weyevote[otheye] -= nocc;
weyevote[jndex] -= nocc;
}
else {
beyevote[otheye] -= nocc;
beyevote[jndex] -= nocc;
}
/*
showguy(stringuy, ntot);
newline();
printf("%d %d %d %d pause", allowed, incontext, nocc, ntogo);
hundelay(100);
*/
}
}
/* now distribute votes from index to bw's own empty allowables */
allowed = incontext;
if (allowed) {
rootp = dir[otheye];
if (rootp) {
if (rootp->clr == bw) allowed = 0;
}
rootp = dir[jndex];
if (rootp) {
if (rootp->clr == bw) allowed = 0;
}
for (iguy=1; iguy<=ntot; ++iguy) {
kndex = stringuy[iguy];
rootp = dir[kndex];
if (rootp) {
if (rootp->clr != bw) allowed = 0;
}
}
}
if (allowed) {
for (iguy=1; iguy<=ntot; ++iguy) {
kndex = stringuy[iguy];
rootp = dir[kndex];
if (!rootp) {
if (index != otheye) {
if (bw == BLK) ++bstovote[kndex];
else ++wstovote[kndex];
}
}
}
if (index != otheye) {
if (bw == BLK) {
++beyevote[jndex];
++beyevote[otheye];
}
else {
++weyevote[jndex];
++weyevote[otheye];
}
}
}
}
void bedead(index, otheye, being, jig, bw)
unsigned index; /* primary eye of being and stone to be played */
unsigned otheye; /* other eye */
unsigned being[3];
unsigned jig[37];
unsigned bw; /* bw at index is going to be BLK or WHT */
{
unsigned allowed;
unsigned bitno, i, kndex;
unsigned imask, iword, ibit;
struct root *rootp;
unsigned iguy, stringuy[12], ntot, ntogo, nocc;
allowed = 1;
ntot = 0;
ntogo = 0;
nocc = 0;
bitno = 0;
/* assemble being into stringuy */
for (iword=0; iword<=2; ++iword) {
imask = 1;
for (ibit=0; ibit<=15; ++ibit) {
++bitno;
if (being[iword] & imask) {
kndex = jig[bitno];
if (kndex) {
++ntot;
stringuy[ntot] = kndex;
rootp = dir[kndex];
if (!rootp) {
++ntogo;
}
if (rootp) {
++nocc;
if (bw != rootp->clr) {
allowed = 0;
}
}
}
}
imask += imask;
}
}
if (allowed) {
rootp = dir[otheye];
if (rootp) {
if (rootp->clr == bw) allowed = 0;
}
}
if (allowed) {
/* account for lifeforms disallowed by index in eye */
/* twice nocc because index takes out votes from otheye too */
for (iguy=1; iguy<=ntot; ++iguy) {
kndex = stringuy[iguy];
rootp = dir[kndex];
if (!rootp) {
if (bw == BLK) bstovote[kndex] -= nocc + nocc;
else wstovote[kndex] -= nocc + nocc;
}
}
/* remove eye votes from otheye */
if (bw == BLK) beyevote[otheye] -= nocc+nocc;
else weyevote[otheye] -= nocc+nocc;
}
}
void valeye(jndex, index, bw)
unsigned jndex; /* evaluate opponents lifeforms with eye at jndex */
unsigned index; /* given own bw stone to be played at index */
unsigned bw; /* colour of own stone at index */
{
unsigned otheye, forms, formp;
unsigned being[3];
unsigned jig[37];
forms = bugs[jndex];
makejig(jndex, jig);
if (forms) {
formp = peek(forms, NEXTL);
if (formp) {
do {
otheye = peek(formp, LEVEL);
otheye = jig[otheye];
being[0] = peek(formp, (LEVEL+2));
being[1] = peek(formp, (LEVEL+4));
being[2] = peek(formp, (LEVEL+6));
belive(jndex, otheye, being, jig, index, bw);
formp = peek(formp, NEXTL);
} while (formp);
}
}
}
void deadeye(index, bw)
unsigned index; /* bw stone at index may be in own eye */
unsigned bw; /* colour of own stone at index */
{
unsigned otheye, forms, formp;
unsigned being[3];
unsigned jig[37];
forms = bugs[index];
makejig(index, jig);
if (forms) {
formp = peek(forms, NEXTL);
if (formp) {
do {
otheye = peek(formp, LEVEL);
otheye = jig[otheye];
being[0] = peek(formp, (LEVEL+2));
being[1] = peek(formp, (LEVEL+4));
being[2] = peek(formp, (LEVEL+6));
bedead(index, otheye, being, jig, bw);
formp = peek(formp, NEXTL);
} while (formp);
}
}
}
*/
unsigned stotogo(index, otheye, being, jig, bw, n, togos)
unsigned index; /* primary eye of being and stone to be played */
unsigned otheye; /* other eye */
unsigned being[3];
unsigned jig[37];
unsigned bw; /* bw at index is BLK or WHT */
unsigned n; /* put required stoned in togos if ntogo==n */
unsigned togos;
{
unsigned ntogo;
unsigned allowed;
unsigned bitno, i, kndex;
unsigned imask, iword, ibit;
struct root *rootp;
unsigned iguy, stringuy[12], ntot, nocc;
unsigned needed[12];
unsigned id;
ntogo = 0;
allowed = 1;
rootp = dir[index];
if (rootp) {
if (rootp->clr == bw) allowed = 0;
}
if (allowed) {
rootp = dir[otheye];
if (rootp) {
if (rootp->clr == bw) allowed = 0;
}
}
ntot = 0;
nocc = 0;
bitno = 0;
/* assemble being into stringuy */
for (iword=0; iword<=2; ++iword) {
imask = 1;
for (ibit=0; ibit<=15; ++ibit) {
++bitno;
if (being[iword] & imask) {
kndex = jig[bitno];
if (kndex) {
++ntot;
stringuy[ntot] = kndex;
rootp = dir[kndex];
if (!rootp) ++ntogo; else ++nocc;
if (!rootp) needed[ntogo] = kndex;
}
}
imask += imask;
}
}
for (iguy=1; iguy<=ntot; ++iguy) {
kndex = stringuy[iguy];
rootp = dir[kndex];
if (rootp) {
if (rootp->clr != bw) {
allowed = 0;
}
}
}
if (!allowed) ntogo = 99;
if (ntogo <= n) {
kndex = needed[1];
togos = xttaillist(togos);
id = peek(togos, LOC);
++id;
togos = xtlocate(id, togos);
togos = xtinsert(id, togos);
poke(togos, LEVEL, 0);
poke(togos, (LEVEL+2), 0);
poke(togos, (LEVEL+4), 0);
poke(togos, (LEVEL+6), 0);
if (ntogo >= 1) poke(togos, LEVEL, needed[1]);
if (ntogo >= 2) poke(togos, (LEVEL+2), needed[2]);
if (ntogo >= 3) poke(togos, (LEVEL+4), needed[3]);
if (ntogo == 4) poke(togos, (LEVEL+6), needed[4]);
}
return(ntogo);
}
unsigned nstotogo(index, bw, n, togos)
unsigned index, bw, n;
unsigned togos;
{
unsigned mintogo, ntogo;
unsigned otheye, forms, formp;
unsigned being[3];
unsigned jig[37];
mintogo = 99;
forms = bugs[index];
makejig(index, jig);
if (forms) {
formp = peek(forms, NEXTL);
if (formp) {
do {
otheye = peek(formp, LEVEL);
otheye = jig[otheye];
being[0] = peek(formp, (LEVEL+2));
being[1] = peek(formp, (LEVEL+4));
being[2] = peek(formp, (LEVEL+6));
ntogo = stotogo(index, otheye, being, jig, bw, n, togos);
if (ntogo <= n) mintogo = ntogo;
formp = peek(formp, NEXTL);
} while (formp);
}
}
return(mintogo);
}
unsigned miai(index)
unsigned index;
{
unsigned bw;
unsigned mintogo, ntogo;
unsigned eyes, eyep;
unsigned jndex, kndex, dist, nways;
unsigned togos, togop;
unsigned n, id;
struct root *rootp;
struct link *libp;
unsigned needed[12];
rootp = dir[index];
kndex = 0;
if (rootp) {
for (n=4; n<=4; ++n) {
bw = rootp->clr;
eyes = xtinsert(0,0);
togos = xtinsert(0, 0);
togop = togos;
libp = rootp->liberties->nextl;
eyep = eyes;
do {
jndex = libp->loc;
eyep = xtlocate(jndex, eyep);
eyep = xtinsert(jndex, eyep);
libp = libp->nextl;
} while (libp);
libp = rootp->spaces->nextl;
if (libp) {
do {
jndex = libp->loc;
eyep = xtlocate(jndex, eyep);
eyep = xtinsert(jndex, eyep);
libp = libp->nextl;
} while (libp);
}
eyep = peek(eyes, NEXTL);
if (eyep) {
do {
jndex = peek(eyep, LOC);
ntogo = nstotogo(jndex, bw, n, togos);
ntogo = ntogo; /* useless */
eyep = peek(eyep, NEXTL);
} while (eyep);
}
togop = peek(togos, NEXTL);
if (togop) {
nways = 0;
do {
++nways;
jndex = peek(togop, LEVEL);
needed[1] = peek(togop, LEVEL);
needed[2] = peek(togop, (LEVEL+2));
needed[3] = peek(togop, (LEVEL+4));
needed[4] = peek(togop, (LEVEL+6));
newline();
printf(" miai:");
if (n >= 1) coords(needed[1]);
if (n >= 2) coords(needed[2]);
if (n >= 3) coords(needed[3]);
if (n == 4) coords(needed[4]);
togop = peek(togop, NEXTL);
} while (togop);
if (nways == 1) kndex = jndex;
}
xtfreelist(togos);
xtfreelist(eyes);
}
}
return(kndex);
}
int issafe(unsigned index, unsigned genes)
{
int safe;
unsigned bw;
unsigned mintogo, ntogo;
unsigned eyes, eyep;
unsigned jndex, kndex, dist, nways;
unsigned togos, togop;
struct root *rootp;
struct link *libp;
eyes = xtinsert(0,0);
togos = xtinsert(0, 0);
togop = togos;
rootp = dir[index];
safe = 0;
if (!safe) {
if (rootp) {
bw = rootp->clr;
mintogo = 11;
/*
for (dist=2; dist<=3; ++dist) {
ring(index, dist, eyes);
}
*/
libp = rootp->liberties->nextl;
eyep = eyes;
do {
jndex = libp->loc;
eyep = xtlocate(jndex, eyep);
eyep = xtinsert(jndex, eyep);
libp = libp->nextl;
} while (libp);
libp = rootp->spaces->nextl;
if (libp) {
do {
jndex = libp->loc;
eyep = xtlocate(jndex, eyep);
eyep = xtinsert(jndex, eyep);
libp = libp->nextl;
} while (libp);
}
eyep = peek(eyes, NEXTL);
if (eyep) {
do {
jndex = peek(eyep, LOC);
ntogo = nstotogo(jndex, bw, 1, togos);
if (ntogo < mintogo) {
mintogo = ntogo;
}
safe = !ntogo;
eyep = peek(eyep, NEXTL);
} while (eyep && !safe);
}
}
if (!safe) {
togop = peek(togos, NEXTL);
if (mintogo == 1) {
if (togop) {
nways = 0;
do {
++nways;
jndex = peek(togop, LEVEL);
/*
if (col80) {
newline();
printf("miai1:");
coords(jndex);
}
*/
togop = peek(togop, NEXTL);
} while (togop);
if (nways == 1) {
genes = xtlocate(jndex, genes);
genes = xtinsert(jndex, genes);
}
}
}
}
}
xtfreelist(togos);
xtfreelist(eyes);
return(safe);
}
/*
void vote(unsigned index, unsigned bw)
{
unsigned eyes;
unsigned eyep;
unsigned jndex, dist;
int livers;
for (jndex=1; jndex<=nsize2; ++jndex) {
bstovote[jndex] = 0;
wstovote[jndex] = 0;
beyevote[jndex] = 0;
weyevote[jndex] = 0;
}
eyes = xtinsert(0,0);
for (dist=2; dist<=7; ++dist) {
ring(index, dist, eyes);
}
eyep = peek(eyes, NEXTL);
if (eyep) {
do {
jndex = peek(eyep, LOC);
valeye(jndex, index, bw);
eyep = peek(eyep, NEXTL);
} while (eyep);
}
xtfreelist(eyes);
deadeye(index, bw);
/* miai(index, bw);*/
}
*/
void lifeforms(index, forms)
unsigned index;
unsigned forms;
{
unsigned i, jndex, count, maxcount, trash, othereye, numbits, oldclops;
unsigned itab[7], bitvec[16], gotta[7];
unsigned livers, thismove, thatmove;
unsigned jig[37];
unsigned indexes, indexp;
unsigned formp;
unsigned being[3];
int iomit;
oldclops = cyclops;
cyclops = 0;
livers = 0;
formp = forms;
makejig(index, jig);
for (i=1; i<=36; ++i) {
trash = jig[i];
if (trash) curon(trash);
}
livers = 0;
for (iomit=0; iomit<=6; ++iomit) {
for (dizzy=0; dizzy<=3; ++dizzy) {
othereye = south(east(index));
thismove = kount;
for (i=0; i<=5; ++i) gotta[i] = 0;
if (iomit != 0) gotta[0] = east(index);
if (iomit != 1) gotta[1] = south(index);
if (iomit != 2) gotta[2] = north(index);
if (iomit != 3) gotta[3] = west(index);
if (iomit != 4) gotta[4] = east(south(east(index)));
if (iomit != 5) gotta[5] = south(south(east(index)));
doit(gotta[0]);
for (i=1; i<=5; ++i) {
doit(0);
doit(gotta[i]);
}
thatmove = kount;
itab[0] = north(west(index));
itab[1] = north(east(index));
itab[2] = east(east(index));
itab[3] = south(west(index));
itab[4] = south(south(index));
itab[5] = east(east(itab[4]));
maxcount = 63;
for (numbits=2; numbits<=4; ++numbits) {
for (count=1; count<=maxcount; ++count) {
if (bitson(maxcount, count, numbits, bitvec)) {
for (i=0; i<=5; ++i) {
if (bitvec[i]) {
doit(0);
doit(itab[i]);
if (!itab[i]) bitvec[i] = 0;
}
}
if (binside[index] && binside[othereye]) {
++livers;
newline