#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"
#define TRACENETS 0 /* 1 for printout */
/*
unsigned xxxx(jndex)
unsigned jndex;
{
struct root *rootp;
unsigned value;
value = 0;
if (jndex) {
value = 0;
rootp = dir[jndex];
if (rootp) {
if ((colour == BLK) && (rootp->clr == WHT)) value = 1;
if ((colour == WHT) && (rootp->clr == BLK)) value = 1;
}
}
return (value);
}
unsigned *diarota(index)
unsigned index;
{
unsigned *diagp, *kp, *point;
unsigned north, east, west, south, neast;
kp = &env10[0];
diagp = kp;
point = NEWS(index);
north = *point;
++point;
west = *point;
++point;
east = *point;
++point;
south = *point;
*kp = east;
++kp;
if (north && east)
*kp = (north + 1);
else *kp = 0;
neast = *kp;
++kp;
*kp = north;
++kp;
if (north && west)
*kp = (north - 1);
else *kp = 0;
++kp;
*kp = west;
++kp;
if (south && west)
*kp = (south - 1);
else *kp = 0;
++kp;
*kp = south;
++kp;
if (south && east)
*kp = (south + 1);
else *kp = 0;
++kp;
*kp = east;
++kp;
*kp = neast;
return (diagp);
}
unsigned fourex(index)
unsigned index;
{
unsigned value;
unsigned bit, i, j, jndex, *point;
value = 0;
point = diarota(index);
jndex = *point;
for (i = 1; i <= 4; ++i) {
bit = xxxx(jndex);
++point;
jndex = *point;
bit += xxxx(jndex);
++point;
jndex = *point;
bit += xxxx(jndex);
if (bit == 3)
++value;
}
return (value);
}
unsigned *diagonal(index)
unsigned index;
{
unsigned *diagp, *kp, *point;
unsigned north, east, west, south;
kp = &env10[0];
diagp = kp;
point = NEWS(index);
north = *point;
++point;
west = *point;
++point;
east = *point;
++point;
south = *point;
if (north && west)
*kp = (north - 1);
else *kp = 0;
++kp;
*kp = north;
++kp;
if (north && east)
*kp = (north + 1);
else *kp = 0;
++kp;
*kp = west;
++kp;
*kp = east;
++kp;
if (south && west)
*kp = (south - 1);
else *kp = 0;
++kp;
*kp = south;
++kp;
if (south && east)
*kp = (south + 1);
else *kp = 0;
return (diagp);
}
unsigned teerex(index)
unsigned index;
{
unsigned value;
unsigned bit, i, j, jndex, *point;
value = 0;
point = diagonal(index);
++point;
jndex = *point;
for (i = 1; i <= 4; ++i) {
bit = xxxx(jndex);
++point;
jndex = *point;
bit += xxxx(jndex);
++point;
jndex = *point;
bit += xxxx(jndex);
if (bit == 3)
++value;
}
return (value);
}
*/
#if DDD
#if DDD == 3 /* 3D */
void diags(unsigned index, unsigned *diagp)
{
unsigned *kp, *point;
unsigned north, west, east, south, up, down;
kp = diagp;
point = NEWS(index);
down = *point;
++point;
north = *point;
++point;
west = *point;
++point;
east = *point;
++point;
south = *point;
++point;
up = *point;
if (down && north) *kp = down - nsize;
else *kp = 0;
++kp;
if (down && west) *kp = down - 1;
else *kp = 0;
++kp;
if (down && east) *kp = down + 1;
else *kp = 0;
++kp;
if (down && south) *kp = down + nsize;
else *kp = 0;
++kp;
if (north && west) *kp = north - 1;
else *kp = 0;
++kp;
if (north && east) *kp = north + 1;
else *kp = 0;
++kp;
if (south && west) *kp = south - 1;
else *kp = 0;
++kp;
if (south && east) *kp = south + 1;
else *kp = 0;
++kp;
if (up && north) *kp = up - nsize;
else *kp = 0;
++kp;
if (up && west) *kp = up - 1;
else *kp = 0;
++kp;
if (up && east) *kp = up + 1;
else *kp = 0;
++kp;
if (up && south) *kp = up + nsize;
else *kp = 0;
}
#else /* 2.5D universal but slow ... suitable for 2D and 3D too */
void diags(unsigned index, unsigned *diagp)
{
unsigned *kp, *point1, *point2;
unsigned i, j, value, jndex, kndex;
unsigned list, listp;
list = xtinsert(0, 0);
listp = list;
kp = diagp;
for (i=1; i<=NDIAGS; ++i) {
*kp = 0;
++kp;
}
point1 = NEWS(index);
for (i=1; i<=NLIBS; ++i) {
jndex = *point1;
if (jndex) {
point2 = NEWS(jndex);
for (j=1; j<=NLIBS; ++j) {
kndex = *point2;
if (kndex) {
listp = xtlocate(kndex, listp);
if (!xtmember(kndex, listp)) {
listp = xtinsert(kndex, listp);
poke(listp, LEVEL, 1);
}
else {
value = peek(listp, LEVEL);
++value;
poke(listp, LEVEL, value);
}
}
++point2;
}
}
++point1;
}
listp = peek(list, NEXTL);
kp = diagp;
if (listp) {
do {
jndex = peek(listp, LOC);
value = peek(listp, LEVEL);
if (value > 1) {
if (jndex != index) {
*kp = jndex;
++kp;
}
}
listp = peek(listp, NEXTL);
} while (listp);
}
xtfreelist(list);
}
#endif
#endif
#if ((!DONUT)&&(!DDD))
void diags(unsigned index, unsigned *diagp)
{
unsigned *kp, *point;
unsigned north, east, west, south;
kp = diagp;
point = NEWS(index);
north = *point;
++point;
west = *point;
++point;
east = *point;
++point;
south = *point;
if (north && west) *kp = (north - 1);
else *kp = 0;
++kp;
if (north && east) *kp = (north + 1);
else *kp = 0;
++kp;
if (south && west) *kp = (south - 1);
else *kp = 0;
++kp;
if (south && east) *kp = (south + 1);
else *kp = 0;
}
#endif
#if DONUT
void diags(unsigned index, unsigned *diagp)
{
unsigned *kp, *point, *joint;
unsigned north, south;
kp = diagp;
point = NEWS(index);
north = *point;
++point; /* west */
++point; /* east */
++point;
south = *point;
joint = NEWS(north);
*kp = joint[1]; /* NWES == 0123 (North, West, East, South) */
++kp;
joint = NEWS(north);
*kp = joint[2];
++kp;
joint = NEWS(south);
*kp = joint[1];
++kp;
joint = NEWS(south);
*kp = joint[2];
}
#endif
void addstone(index, colour)
unsigned index;
unsigned colour;
{
unsigned *point;
unsigned i, jndex;
struct root *rooti, *rootp;
struct link *whrneib;
struct link *whrlib;
struct link *whrspc;
struct link *whrfrd;
struct link *whrnmy;
struct link *whrctc;
struct link *opponent;
point = NEWS(index);
for (i=1; i<=NLIBS; ++i) {
jndex = *point;
if (jndex) {
rootp = dir[jndex];
if (rootp) {
if (colour != rootp->clr) {
whrlib = (struct link *) locate(index, rootp->liberties);
if (member(index, whrlib)) {
whrlib = (struct link *) delete(whrlib);
--rootp->nlib;
}
whrctc = (struct link *)locate(index, rootp->contacts);
if (!member(index, whrctc)) {
whrctc = (struct link *) insert(index, whrctc);
}
}
}
}
++point;
}
}
void remstone(index, colour)
unsigned index;
unsigned colour;
{
unsigned *point;
unsigned i, jndex;
struct root *rooti, *rootp;
struct link *whrneib;
struct link *whrlib;
struct link *whrspc;
struct link *whrfrd;
struct link *whrnmy;
struct link *whrctc;
struct link *opponent;
point = NEWS(index);
for (i=1; i<=NLIBS; ++i) {
jndex = *point;
if (jndex) {
rootp = dir[jndex];
if (rootp) {
if (colour != rootp->clr) {
whrlib = (struct link *) locate(index, rootp->liberties);
if (!member(index, whrlib)) {
whrlib = (struct link *) insert(index, whrlib);
++rootp->nlib;
}
whrctc = (struct link *) locate(index, rootp->contacts);
if (member(index, whrctc)) {
whrctc = (struct link *) delete(whrctc);
}
}
}
}
++point;
}
}
void addextra(index, colour)
unsigned index;
unsigned colour;
{
unsigned *point;
unsigned diagvec[NDIAGS];
unsigned i, jndex;
struct root *rooti, *rootp;
struct link *whrneib;
struct link *whrlib;
struct link *whrspc;
struct link *whrfrd;
struct link *whrnmy;
struct link *whrctc;
struct link *opponent;
diags(index, diagvec);
point = diagvec;
for (i=1; i<=NDIAGS; ++i) {
jndex = *point;
if (jndex) {
rootp = dir[jndex];
if (rootp) {
whrspc = locate(index, rootp->spaces);
if (member(index, whrspc)) whrspc = delete(whrspc);
if (rootp->clr == colour) {
whrneib = locate(index, rootp->neighbs);
if (!member(index, whrneib)) {
if (dir[index] != rootp) {
whrfrd = locate(index, rootp->friends);
whrfrd = insert(index, whrfrd);
}
}
}
else {
whrctc = locate(index, rootp->contacts);
if (!member(index, whrctc)) {
whrnmy = locate(index, rootp->enemies);
whrnmy = insert(index, whrnmy);
}
}
}
}
++point;
}
}
void remextra(index, colour)
unsigned index;
unsigned colour;
{
unsigned *point;
unsigned diagvec[NDIAGS];
unsigned i, jndex;
struct root *rooti, *rootp;
struct link *whrneib;
struct link *whrlib;
struct link *whrspc;
struct link *whrfrd;
struct link *whrnmy;
struct link *whrctc;
struct link *opponent;
jndex = colour; /* useless */
diags(index, diagvec);
point = diagvec;
for (i=1; i<=NDIAGS; ++i) {
jndex = *point;
if (jndex) {
rootp = dir[jndex];
if (rootp) {
whrlib = locate(index, rootp->liberties);
if (!member(index, whrlib)) {
whrspc = locate(index, rootp->spaces);
whrspc = insert(index, whrspc);
}
whrfrd = locate(index, rootp->friends);
if (member(index, whrfrd)) whrfrd = delete(whrfrd);
whrctc = locate(index, rootp->contacts);
if (!member(index, whrctc)) {
whrnmy = locate(index, rootp->enemies);
if (member(index, whrnmy)) whrnmy = delete(whrnmy);
}
}
}
++point;
}
}
void envel(index,indexes)
unsigned index;
struct link *indexes;
{
struct root *rootp;
unsigned kount;
rootp = dir[index];
if (rootp) {
kount = 0;
kount += merge(indexes, rootp->liberties);
kount += merge(indexes, rootp->spaces);
}
}
/*
unsigned cthree(nel, netp, npart, partitions, index, jndex,
kndex, corny, abort)
unsigned nel, netp, npart, partitions, index, jndex, kndex, corny;
unsigned *abort;
{
unsigned inserted, where;
unsigned netstone;
unsigned rootxp;
struct root *rootp;
*abort = 0;
inserted = 0;
if (xtmember(index, xtlocate(index, partitions))) {
if (xtmember(jndex, xtlocate(jndex, partitions))) {
if (xtmember(kndex, xtlocate(kndex, partitions))) {
if (peek(xtlocate(kndex, partitions), LEVEL) == npart) {
where = xtlocate(corny, partitions);
if (!member(corny, where)) {
rootxp = peek(netp, ROOTS);
rootxp = peek(rootxp, NEXTL);
rootp = peek(rootxp, LOC);
netstone = rootp->ridx;
if (corny == netstone) *abort = 1;
if (!*abort) {
if (nel > 3) {
where = xtinsert(corny, where);
poke(where, LEVEL, npart);
inserted = corny;
}
}
}
}
}
}
}
return(inserted);
}
unsigned corner(nel, netp, npart, partitions, abort)
unsigned nel, netp, npart, partitions;
unsigned *abort;
{
unsigned inserted;
unsigned partp, partno, index, jndex, kndex, corny;
inserted = 0;
corny = 1;
index = 2;
jndex = nsize + 1;
kndex = nsize + 2;
inserted = cthree(nel, netp, npart, partitions, index, jndex, kndex, corny, abort);
if (!inserted && !*abort) {
corny = nsize;
index = nsize - 1;
jndex = nsize + nsize - 1;
kndex = nsize + nsize;
inserted = cthree(nel, netp, npart, partitions, index, jndex, kndex, corny, abort);
if (!inserted && !*abort) {
corny = nsize2 - nsize + 1;
index = corny - nsize;
jndex = index + 1;
kndex = corny + 1;
inserted = cthree(nel, netp, npart, partitions, index, jndex, kndex, corny, abort);
if (!inserted && !*abort) {
corny = nsize2;
index = corny - nsize - 1;
jndex = index + 1;
kndex = corny - 1;
inserted = cthree(nel, netp, npart, partitions, index, jndex, kndex, corny, abort);
}
}
}
return(inserted);
}
void deathshape(netp, npart, partitions, vitals)
unsigned netp, npart, partitions, vitals;
{
unsigned partp, partno, jndex, nelements, inserted;
unsigned index, kndex, death, dont;
int px, py, sumx, sumy, var, tempx, tempy, temp, min, n3, n5;
unsigned rootxes;
struct root *rootp;
partp = peek(partitions, NEXTL);
if (partp) {
nelements = 0;
do {
partno = peek(partp, LEVEL);
if (partno == npart) {
++nelements;
poke(partp, (LEVEL+2), 0); /* no death spots to start */
}
partp = peek(partp, NEXTL);
} while (partp);
dont = 0;
inserted = 0;
if ((nelements >= 3) && (nelements <= 5)) {
inserted = corner(nelements, netp, npart, partitions, &dont);
}
if (!dont) {
if (inserted) ++nelements;
death = 0;
if ((nelements >= 1) && (nelements <= 6)) {
sumx = 0;
sumy = 0;
partp = peek(partitions, NEXTL);
do {
partno = peek(partp, LEVEL);
if (partno == npart) {
jndex = peek(partp, LOC);
xy(jndex, &px, &py);
sumx += px;
sumy += py;
}
partp = peek(partp, NEXTL);
} while (partp);
var = 0;
partp = peek(partitions, NEXTL);
do {
partno = peek(partp, LEVEL);
if (partno == npart) {
jndex = peek(partp, LOC);
xy(jndex, &px, &py);
tempx = nelements * px - sumx;
tempx *= tempx;
tempy = nelements * py - sumy;
tempy *= tempy;
var += tempx * tempx + tempy * tempy;
}
partp = peek(partp, NEXTL);
} while (partp);
/*
newline();
printf("var n %d %d", var, nelements);
*/
/* first handle the 8 cases of rectangular six in corner */
if ((var == 872) && (nelements == 4)) {
n3 = 4 * nsize - 3;
n5 = n3 - 2;
if ((sumx == 7) && (sumy == 9)) {
index = 2;
if (!dir[index]) {
xtinsert(index, xtlocate(index, vitals));
death = 2;
}
}
else if ((sumx == 9) && (sumy == 7)) {
index = nsize + 1;
if (!dir[index]) {
xtinsert(index, xtlocate(index, vitals));
death = 2;
}
}
else if ((sumx == n3) && (sumy == 9)) {
index = (nsize - 1) * nsize + 2;
if (!dir[index]) {
xtinsert(index, xtlocate(index, vitals));
death = 2;
}
}
else if ((sumx == n5) && (sumy == 7)) {
index = (nsize - 2) * nsize + 1;
if (!dir[index]) {
xtinsert(index, xtlocate(index, vitals));
death = 2;
}
}
else if ((sumx == 7) && (sumy == n5)) {
index = nsize - 1;
if (!dir[index]) {
xtinsert(index, xtlocate(index, vitals));
death = 2;
}
}
else if ((sumx == 9) && (sumy == n3)) {
index = nsize + nsize;
if (!dir[index]) {
xtinsert(index, xtlocate(index, vitals));
death = 2;
}
}
else if ((sumx == n3) && (sumy == n5)) {
index = nsize2 - 1;
if (!dir[index]) {
xtinsert(index, xtlocate(index, vitals));
death = 2;
}
}
else if ((sumx == n5) && (sumy == n3)) {
index = nsize2 - nsize;
if (!dir[index]) {
xtinsert(index, xtlocate(index, vitals));
death = 2;
}
}
}
/* next take care of 4-in-a-row with opponent inside */
if (!death && (nelements==4)) {
if ((var==576) || (var==872) || (var==2624)) {
jndex = 0;
kndex = 0;
partp = peek(partitions, NEXTL);
do {
partno = peek(partp, LEVEL);
if (partno == npart) {
index = peek(partp, LOC);
xy(index, &px, &py);
tempx = nelements * px - sumx;
tempx *= tempx;
tempy = nelements * py - sumy;
tempy *= tempy;
temp = tempx * tempx + tempy * tempy;
if (temp <= 82) {
if (!jndex) jndex = index;
else kndex = index;
}
}
partp = peek(partp, NEXTL);
} while (partp);
/* first take care of bent four in corner */
temp = 0;
if (jndex == 1) temp = kndex;
if (jndex == nsize) temp = kndex;
if (jndex == (nsize2-nsize+1)) temp = kndex;
if (jndex == nsize2) temp = kndex;
if (!temp) {
if (kndex == 1) temp = jndex;
if (kndex == nsize) temp = jndex;
if (kndex == (nsize2-nsize+1)) temp = jndex;
if (kndex == nsize2) temp = jndex;
}
if (!temp) {
if (dir[jndex]) temp = kndex;
if (dir[kndex]) temp = jndex;
}
if (temp) {
death = 3;
xtinsert(temp, xtlocate(temp, vitals));
}
}
}
/* next take care of 5 with opponent inside */
if (!death && (nelements==5)) {
if ((var==3060) || (var==3910) || (var==6870)) {
jndex = 0;
kndex = 0;
partp = peek(partitions, NEXTL);
do {
partno = peek(partp, LEVEL);
if (partno == npart) {
index = peek(partp, LOC);
xy(index, &px, &py);
tempx = nelements * px - sumx;
tempx *= tempx;
tempy = nelements * py - sumy;
tempy *= tempy;
temp = tempx * tempx + tempy * tempy;
if (temp <= 256) {
if (!jndex) jndex = index;
else kndex = index;
}
}
partp = peek(partp, NEXTL);
} while (partp);
temp = 0;
if (dir[jndex]) temp = kndex;
if (dir[kndex]) temp = jndex;
if (temp) {
death = 3;
xtinsert(temp, xtlocate(temp, vitals));
}
}
}
if (nelements <= 2) death = 4;
if (nelements == 3) death = 1;
else if (nelements == 4) {
if (var==128) death = 2;
if (var==596) death = 1;
}
else if (nelements == 5) {
if ((var==2500) || (var==2020)) death = 1;
}
else if (nelements == 6) {
if (var == 7308) death = 1;
}
if (death == 1) {
index = 0;
min = 100;
partp = peek(partitions, NEXTL);
do {
partno = peek(partp, LEVEL);
if (partno == npart) {
jndex = peek(partp, LOC);
xy(jndex, &px, &py);
tempx = nelements * px - sumx;
tempx *= tempx;
tempy = nelements * py - sumy;
tempy *= tempy;
temp = tempx * tempx + tempy * tempy;
if (temp < min) {
index = jndex;
min = temp;
}
}
partp = peek(partp, NEXTL);
} while (partp);
if (!dir[index]) xtinsert(index, xtlocate(index, vitals));
}
}
if (death) {
partp = peek(partitions, NEXTL);
do {
partno = peek(partp, LEVEL);
if (partno == npart) {
++nelements;
poke(partp, (LEVEL+2), 1); /* partition contains death spot */
}
partp = peek(partp, NEXTL);
} while (partp);
}
}
if (inserted) {
xtdelete(xtlocate(inserted, partitions));
}
}
}
*/
unsigned edge(index)
unsigned index;
{
unsigned edgy;
unsigned xp, xm, yp, ym;
int x, y;
edgy = 0;
/*
if (index <= nsize) edgy = 1;
if ((((index-1)/nsize)*nsize) == index-1) edgy = 1;
if ((index/nsize)*nsize == index) edgy = 1;
if (index > nsize2-nsize) edgy = 1;
*/
/*xy(index, &x, &y);*/
x = X[index];
y = Y[index];
if (x == 1) edgy += 1;
if (x == nsize) edgy += 2;
if (y == 1) edgy += 4;
if (y == nsize) edgy += 8;
return(edgy);
}
void suifix(index)
unsigned index;
{
unsigned jndex;
struct link *suicapp, *stonep;
struct root *rootp;
index = index;
suicapp = movep->suicaps->nextl;
if (suicapp) {
do {
rootp = suicapp->loc;
stonep = rootp->neighbs->nextl;
do {
jndex = stonep->loc;
remstone(jndex, colour);
if (envon) remextra(jndex, colour);
stonep = stonep->nextl;
} while (stonep);
suicapp = suicapp->nextl;
} while (suicapp);
}
}
void unsuifix(index)
unsigned index;
{
unsigned jndex;
struct link *suicapp, *stonep;
struct root *rootp;
index = index;
suicapp = movep->suicaps->nextl;
if (suicapp) {
do {
rootp = suicapp->loc;
stonep = rootp->neighbs->nextl;
do {
jndex = stonep->loc;
addstone(jndex, colour);
if (envon) addextra(jndex, colour);
stonep = stonep->nextl;
} while (stonep);
suicapp = suicapp->nextl;
} while (suicapp);
}
}
void life(index)
unsigned index;
{
struct root *rootp, *rooti;
struct link *mergep, *capp;
struct link *stonep, *where;
struct link *whrneib;
struct link *whrlib;
struct link *whrspc;
struct link *whrfrd;
struct link *whrnmy;
struct link *whrctc;
struct link *opponent;
unsigned *point;
unsigned diagvec[NDIAGS];
unsigned i, jndex;
unsigned inenv, dia;
unsigned temp;
rooti = dir[index];
if (rooti) {
rooti->nsto = 0;
rooti->nlib = 0;
whrneib = rooti->neighbs;
whrlib = rooti->liberties;
whrspc = rooti->spaces;
whrfrd = rooti->friends;
whrnmy = rooti->enemies;
whrctc = rooti->contacts;
mergep = movep->merges->nextl;
if (mergep) {
if (!mergep->nextl && !movep->ncap && !movep->nsuicap) {
/* only one root merged - use incremental modification */
rootp = mergep->loc;
rooti->incmod = rootp;
rooti->nsto = rootp->nsto;
temp = rootp->neighbs;
rootp->neighbs = rooti->neighbs;
rooti->neighbs = temp;
whrneib = temp;
/* replace old stones by most recently played stone */
insert(rootp->ridx, locate(rootp->ridx, rootp->neighbs));
rooti->nlib = rootp->nlib;
temp = rootp->liberties;
rootp->liberties = rooti->liberties;
rooti->liberties = temp;
whrlib = temp;
merge(rooti->contacts, rootp->contacts);
}
else {
do {
rootp = mergep->loc;
rooti->nsto += merge(rooti->neighbs, rootp->neighbs);
rooti->nlib += merge(rooti->liberties, rootp->liberties);
merge(rooti->contacts, rootp->contacts);
mergep = mergep->nextl;
}
while (mergep);
}
}
whrneib = locate(index, whrneib);
whrneib = insert(index, whrneib);
++rooti->nsto;
addstone(index, rooti->clr);
capp = movep->caps->nextl;
if (capp) {
do {
rootp = capp->loc;
where = rootp->neighbs;
do {
jndex = where->loc;
if (jndex) {
remstone(jndex, rootp->clr);
}
where = where->nextl;
}
while (where);
capp = capp->nextl;
}
while (capp);
}
whrlib = locate(index, rooti->liberties);
if (member(index, whrlib)) {
whrlib = delete(whrlib);
--rooti->nlib;
}
point = NEWS(index);
for (i=1; i<=NLIBS; ++i) {
jndex = *point;
if (jndex) {
rootp = dir[jndex];
if (!rootp) {
whrlib = locate(jndex, whrlib);
if (!member(jndex, whrlib)) {
whrlib = insert(jndex, whrlib);
++rooti->nlib;
rootp = rooti->incmod;
if (rootp) {
insert(jndex, locate(jndex, rootp->liberties));
}
}
}
else if (rootp->clr != rooti->clr) {
whrctc = locate(jndex, whrctc);
whrctc = insert(jndex, whrctc);
}
}
++point;
}
if (!envon) return;
mergep = movep->merges->nextl;
if (mergep) {
do {
rootp = mergep->loc;
xmerge(rooti->friends, rootp->friends, rooti->neighbs);
xmerge(rooti->spaces, rootp->spaces, rooti->liberties);
xmerge(rooti->enemies, rootp->enemies, rooti->contacts);
mergep = mergep->nextl;
}
while (mergep);
}
whrneib = rooti->neighbs->nextl;
if (whrneib) {
do {
jndex = whrneib->loc;
whrfrd = locate(jndex, rooti->friends);
if (member(jndex, whrfrd)) whrfrd = delete(whrfrd);
whrneib = whrneib->nextl;
}
while (whrneib);
}
whrneib = rooti->neighbs;
addextra(index, rooti->clr);
capp = movep->caps->nextl;
if (capp) {
do {
rootp = capp->loc;
where = rootp->neighbs;
do {
jndex = where->loc;
if (jndex) {
remextra(jndex, rootp->clr);
}
where = where->nextl;
}
while (where);
capp = capp->nextl;
}
while (capp);
}
diags(index, diagvec);
point = diagvec;
for (i=1; i<=NDIAGS; ++i) {
jndex = *point;
if (jndex) {
rootp = dir[jndex];
if (!rootp) {
whrlib = locate(jndex, whrlib);
if (!member(jndex, whrlib)) {
whrspc = locate(jndex, whrspc);
whrspc = insert(jndex, whrspc);
}
}
else if (rootp->clr == rooti->clr) {
if (rooti != rootp) {
whrneib = locate(jndex, whrneib);
if (!member(jndex, whrneib)) {
whrfrd = locate(jndex, whrfrd);
whrfrd = insert(jndex, whrfrd);
}
}
}
else {
whrctc = locate(jndex, whrctc);
if (!member(jndex, whrctc)) {
whrnmy = locate(jndex, whrnmy);
whrnmy = insert(jndex, whrnmy);
}
}
}
++point;
}
}
else suifix(index);
}
void unlife(index)
unsigned index;
{
struct root *rootp, *rooti;
struct link *mergep, *capp;
struct link *stonep, *where;
struct link *whrneib;
struct link *whrlib;
struct link *whrspc;
struct link *whrfrd;
struct link *whrnmy;
struct link *whrctc;
struct link *opponent;
unsigned *point;
unsigned i, jndex;
unsigned inenv, dia;
struct link *temp;
rooti = dir[index];
if (rooti) {
rootp = rooti->incmod;
if (rootp) {
temp = (unsigned) rootp->neighbs;
rootp->neighbs = rooti->neighbs;
rooti->neighbs = temp;
where = locate(index, rootp->neighbs);
if (member(index, where)) where = delete(where);
temp = rootp->liberties;
rootp->liberties = rooti->liberties;
rooti->liberties = temp;
whrlib = rootp->liberties;
whrlib = insert(index, locate(index, whrlib));
where = rooti->liberties->nextl;
if (where) {
do {
jndex = where->loc;
whrlib = locate(jndex, whrlib);
if (member(jndex, whrlib)) whrlib = delete(whrlib);
where = where->nextl;
} while (where);
}
}
capp = movep->caps->nextl;
if (capp) {
do {
rootp = (struct root *)capp->loc;
where = rootp->neighbs;
do {
jndex = where->loc;
if (jndex) {
addstone(jndex, rootp->clr);
}
where = where->nextl;
}
while (where);
capp = capp->nextl;
}
while (capp);
}
remstone(index, rooti->clr);
if (envon) {
capp = movep->caps->nextl;
if (capp) {
do {
r