*/
If you have a PH account, you can customize your PH profile.
*/

View \FORMS.C

C souce code for the game of Go

Submitted By: WEBMASTER
Rating: starstarstarstar (Rate It)


#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