Looking for work? Check out our jobs area.

View \DOIT.C

C souce code for the game of Go

Submitted By: WEBMASTER
Rating: starstarstarhalf star (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"


#define TRACENETS 0

void addrootl(rootp)
struct root *rootp;
{
 struct link *linkp;
 linkp = (struct link *) locate(rootp, rootlist);
 linkp = (struct link *) insert(rootp, linkp);
 rootp->rootlp = linkp;
}

void uprootl(rootp)
struct root *rootp;
{
 struct link *linkp;
 linkp = rootp->rootlp;
 if(linkp->loc == rootp) linkp = (struct link *) delete(linkp);
}

void distinct(unsigned index, struct root *diff[])
{
 unsigned i, jndex, k, j, *point;
 struct root *rootp;
 point = NEWS(index);
 for (i=0; i<NLIBS;  ++i) {
  jndex = *point;
  if (jndex) diff[i] = dir[jndex];
  else diff[i] = 0;
  ++point;
 }
 for (i=1; i<NLIBS; ++i) { /* Hey, I meant to do that */
  rootp = diff[i];
  if (rootp) {
   k = i - 1;              /* because of this */
   for (j=0; j<=k; ++j) {
    point = (unsigned *) diff[j];
    if (rootp == (struct root *) point) diff[i] = 0;
   }
  }
 }
}

/* undo */

void untrans(unsigned trlistp)
{
 unsigned typ, ptr, *p, val, segptr, offset;
 if (peek(trlistp, NEXTL)) {
  trlistp = xttaillist(trlistp);
  do {
   typ = peek(trlistp, LEVEL);
   if (typ == 1) { /* transaction was add to list ... delete to undo */
    ptr = peek(trlistp, (LEVEL+2));
    xtdelete(ptr);
   }
   else if (typ == 2) { /* trans was delink from list ... relink to undo */
    ptr = peek(trlistp, (LEVEL+2));
    xtrelink(ptr);
   }
   else if (typ == 3) { /* trans was unsigned assign ... reassign to undo */
    p = peek(trlistp, (LEVEL+2));
    val = peek(trlistp, (LEVEL+4));
    *p = val;
   }
   else if (typ == 4) { /* trans was unsigned poke ... reassign to undo */
    segptr = peek(trlistp, (LEVEL+2));
    offset = peek(trlistp, (LEVEL+4));
    val = peek(trlistp, (LEVEL+6));
    poke(segptr, offset, val);
   }
   trlistp = peek(trlistp, PREVL);
  } while (peek(trlistp, PREVL));
 }
}

struct move *unmove(movep)
struct move *movep;
{
 struct move *freep;
 if (movep) {
  freelist(movep->caps);
  freelist(movep->merges);
  freelist(movep->suicaps);
  xtfreelist(movep->transact);
  freep = movep;
  movep = movep->prevm;
  freelarge(freep);
 }
 return (movep);
}

unsigned ndist(index)
unsigned index;
{
 unsigned number, i, *point;
 struct root *diff[NLIBS];
 number = 0;
 distinct(index, diff);
 point = (unsigned *) diff;
 for (i=1; i<=NLIBS; ++i) {
  if (*point) ++number;
  ++point;
 }
 return (number);
}

void unmergeroot(index)
unsigned index;
{
 struct root *rootp;
 struct link *mergep, *head, *stonep, *movelp, *libp;
 unsigned jndex;
 struct link *hmerge;
 jndex = index; /* useless */
 hmerge = movep->merges->nextl;
 if (hmerge) {
  mergep = taillist(movep->merges);
  do {
   rootp = mergep->loc;
   addrootl(rootp);
   stonep = rootp->neighbs;
   if (stonep) {
    do {
     jndex = stonep->loc;
     if (jndex) dir[jndex] = rootp;
     stonep = stonep->nextl;
    }
    while (stonep);
   }
   mergep = mergep->prevl;
   rootp = mergep->loc;
  }
  while (rootp);
 }
}

void uncreroot(index)
unsigned index;
{
 struct root *rootp;
 unsigned i;
 rootp = dir[index];
 uprootl(rootp);
 dir[index] = 0;
 freelist(rootp->neighbs);
 freelist(rootp->liberties);
 freelist(rootp->spaces);
 freelist(rootp->friends);
 freelist(rootp->enemies);
 freelist(rootp->contacts);
 freelarge(rootp);
}

void unremcap(index)
unsigned index;
{
 struct root *rootp, *head;
 struct link *ptr, *point, *listp, *stonep;
 unsigned jndex, i;
 jndex = index; /* useless */
 listp = movep->caps->nextl;
 if (listp) {
  do {
   rootp = listp->loc;
   addrootl(rootp);
   head = rootp;
   stonep = rootp->neighbs->nextl;
   if (stonep) {
    do {
     jndex = stonep->loc;
     dir[jndex] = head;
     colour = flip(colour);
     add(jndex);
     if (colour == BLK) ++bstones;
     else ++wstones;
     colour = flip(colour);
     stonep = stonep->nextl;
    }
    while (stonep);
   }
   listp = listp->nextl;
  }
  while (listp);
 }
 nopen -= movep->ncap;
 if (colour == BLK) {
  wcaps -= movep->ncap;
 }
 if (colour == WHT) {
  bcaps -= movep->ncap;
 }
}

void unchsui(index)
unsigned index;
{
 struct root *rootp, *head;
 struct link *ptr, *point, *listp, *stonep;
 unsigned jndex, i;
 jndex = index; /* useless */
 listp = movep->suicaps->nextl;
 if (listp) {
  do {
   rootp = listp->loc;
   addrootl(rootp);
   head = rootp;
   stonep = rootp->neighbs->nextl;
   if (stonep) {
    do {
     jndex = stonep->loc;
     dir[jndex] = head;
     add(jndex);
     stonep = stonep->nextl;
    }
    while (stonep);
   }
   listp = listp->nextl;
  }
  while (listp);
 }
 nopen -= movep->nsuicap - 1;
 if (colour == BLK) {
  bcaps -= movep->nsuicap;
  bstones += movep->nsuicap;
 }
 if (colour == WHT) {
  wcaps -= movep->nsuicap;
  wstones += movep->nsuicap;
 }
}


unsigned adjacent(unsigned index, unsigned jndex)
{
 unsigned adj;
 unsigned *point, i;
 adj = 0;
 point = NEWS(index);
 for (i=0; i<NLIBS;  ++i) {
  if (jndex == *point) adj = 1;
  ++point;
 }
 return(adj);
}

unsigned eyesteal(index, jndex)
unsigned index;
unsigned jndex;
{
 unsigned tesuji;
 unsigned ix, iy, jx, jy, kndex, lndex;
 tesuji = 0;
 xy(index, &ix, &iy);
 xy(jndex, &jx, &jy);
 kndex = fxy(ix, jy);
 if (!dir[kndex]) {
  lndex = fxy(jx, iy);
  if (!dir[lndex]) tesuji = 1;
 }
 return(tesuji);
}

unsigned evaleye(index, bw)
unsigned index, bw;
{
 unsigned num;
 unsigned *point;
 unsigned i, jndex, poked;
 unsigned diagvec[NDIAGS];
 num = 0;
 poked = 0;
 if (dir[index]) {
  /*if (dir[index]->clr == bw) */
  poked = 1;
 }
 if (!poked) {
  point = NEWS(index);
  for (i=0; i<NLIBS; ++i) {
   jndex = *point;
   if (jndex) {
    if (dir[jndex]) {
     if (dir[jndex]->clr == bw) ++num;
     else poked = 1;
    }
   }
   ++point;
  }
 }
 if (!poked) {
  diags(index, diagvec);
  point = diagvec;
  for (i=0; i<NDIAGS; ++i) {
   jndex = *point;
   if (jndex) {
    if (dir[jndex]) {
     if (dir[jndex]->clr != bw) {
      if (eyesteal(index, jndex)) poked = 1;
     }
    }
   }
   ++point;
  }
 }
 if (poked) num = 0;
 return(num);
}

void freroot(rootp)
struct root *rootp;
{
 unsigned jndex;
 if (rootp) {
  freelist(rootp->neighbs);
  freelist(rootp->liberties);
  freelist(rootp->spaces);
  freelist(rootp->friends);
  freelist(rootp->enemies);
  freelist(rootp->contacts);
  freelarge(rootp);
 }
}

void freroots(listr)
struct link *listr;
{
 struct root *rootp;
 struct link *listp;
 if (listr) {
  listp = listr;
  do {
   rootp = listp->loc;
   freroot(rootp);
   listp = listp->nextl;
  }
  while (listp);
 }
}

void fretrans(unsigned trlistp)
{
 unsigned typ, ptr;
 if (peek(trlistp, NEXTL)) {
  trlistp = xttaillist(trlistp);
  do {
   typ = peek(trlistp, LEVEL);
   ptr = peek(trlistp, (LEVEL+2));
   if (typ == 2) { /* trans was delink from list ... free to forget */
    freeextra(ptr);
   }
   trlistp = peek(trlistp, PREVL);
  } while (peek(trlistp, PREVL));
 }
}

void forget(n)
unsigned n;
{
 struct move *ptr, *fmove;
 unsigned i;
 fmove = movep;
 for (i = 1;  i <= n;  ++i) {
  if (fmove) fmove = fmove->prevm;
 }
 if (fmove) {
  ptr = fmove;
  fmove = fmove->prevm;
  if (fmove) {
   /*freenets(fmove);*/
   freroots(fmove->suicaps);
   freroots(fmove->caps);
   freroots(fmove->merges);
   fretrans(fmove->transact);
   fmove = unmove(fmove);
   ptr->prevm = 0;
  }
 }
}

void chinsui(index)
unsigned index;
{
 struct root *rootp;
 unsigned *point;
 struct link *stonep, *capp;
 unsigned i, jndex;
 movep->nsuicap = 1;
 point = NEWS(index);
 for (i=1; i<=NLIBS; ++i) {
  jndex = *point;
  if (jndex) {
   rootp = dir[jndex];
   if (rootp) {
    if (rootp->clr == colour) {
     if (rootp->nlib == 1) {
      uprootl(rootp);
      movep->nsuicap += rootp->nsto;
      nopen += rootp->nsto;
      capp = (struct link *) locate(rootp, movep->suicaps);
      capp = (struct link *) insert(rootp, capp);
      stonep = rootp->neighbs->nextl;
      if (stonep) {
       do {
        jndex = stonep->loc;
        dir[jndex] = 0;
        del(jndex);
        stonep = stonep->nextl;
       } while (stonep);
      }
     }
    }
   }
  }
  ++point;
 }
 if (colour == WHT) {
  wcaps += movep->nsuicap;
  wstones -= movep->nsuicap;
 }
 if (colour == BLK) {
  bcaps += movep->nsuicap;
  bstones -= movep->nsuicap;
 }
 scrindex = index;
}

unsigned suichk(index)
unsigned index;
{
 unsigned sui;
 struct root *rootp;
 unsigned *point;
 unsigned ratp;
 unsigned i, immedlib, caplib, conlib, jndex, alone;
 sui = 0;
 /* immedlib true for immediate liberties */
 immedlib = 0;
 point = NEWS(index);
 for (i=1; i<=NLIBS; ++i) {
  jndex = *point;
  if (jndex) {
   immedlib |= (dir[jndex] == 0);
  }
  ++point;
 }
 if (!immedlib) {     /* no immediate liberties */
  /*                caplib true if there will be captures */
  caplib = 0;
  point = NEWS(index);
  for (i=1; i<=NLIBS; ++i) {
   jndex = *point;
   if (jndex) {
    rootp = dir[jndex];
    if (rootp) {
     if (rootp->clr != colour) {
      if (rootp->nlib == 1) caplib |= 1;
     }
    }
   }
   ++point;
  }
  if (!caplib) {    /* no liberties by making capture */
   /*  conlib true if friends with nlib > 1 */
   alone = 1;
   point = NEWS(index);
   conlib = 0;
   for (i=1; i<=NLIBS; ++i) {
    jndex = *point;
    if (jndex) {
     rootp = dir[jndex];
     if (rootp) {
      if (rootp->clr == colour) {
       alone = 0;
       conlib |= (rootp->nlib > 1);
      }
     }
    }
    ++point;
   }
   sui = !conlib;
   if (sui && chinese && !alone && suilegal) {
    sui = 0;
    chinsui(index);
    del(index);
   }
  }    /* endif !caplib   */
 }     /* endif !immedlib */
 return (sui);
}

struct move *addmove(movep, index)
struct move *movep;
unsigned index;
{
 struct move *lastmove;
 if (movep) {
  lastmove = movep;
  movep = (struct move *) allolarge();
  if (movep) {
   movep->nextm = 0;
   lastmove->nextm = movep;
   movep->prevm = lastmove;
  }
 }
 else {
  movep = (struct move *) allolarge();
  if (movep) {
   movep->nextm = 0;
   movep->prevm = 0;
  }
 }
 if (movep) {
  movep->midx = index;
  movep->ncap = 0;
  movep->caps = (struct link *) insert(0, 0);
  movep->merges = (struct link *) insert(0, 0);
  movep->komove = 0;
  movep->nsuicap = 0;
  movep->suicaps = (struct link *) insert(0, 0);
  movep->transact = xtinsert(0, 0);
  xthistp = xtlocate(kount, xthistp);
  xthistp = xtinsert(kount, xthistp);
  poke(xthistp, LEVEL, index);
 }
 return (movep);
}

unsigned kochk(index)
unsigned index;
{
 unsigned ko;
 struct move *ptr;
 ko = 0;
 if (movep) {
  ptr = movep->prevm;
  if (ptr) {
   ko = (ptr->komove == index);
  }
 }
 return (ko);
}

void kogen(index)
unsigned index;
{
 struct root *rootp;
 unsigned flag;
 rootp = dir[index];
 if (rootp) {
  flag = ((movep->ncap == 1) && (rootp->nlib == 1) && (rootp->nsto == 1));
  if (flag) {
   rootp = (struct root *) movep->caps->nextl->loc;
   movep->komove = rootp->neighbs->nextl->loc;
  }
 }
}

void merger(index)
unsigned index;
{
 struct root *rootp, *firstroot;
 struct link *mergep;
 unsigned *point;
 struct root *diff[NLIBS];
 unsigned i;
 distinct(index, diff);
 point = (unsigned *) diff;
 firstroot = dir[index];
 for (i = 1;  i <= NLIBS;  ++i) {
  rootp = (struct root *) *point;
  if (rootp) {
   if (rootp->clr == firstroot->clr) {
    mergep = (struct link *) locate(rootp, movep->merges);
    mergep = (struct link *) insert(rootp, mergep);
   }
  }
  ++point;
 }
}

void mergeroot(index)
unsigned index;
{
 struct root *rootp, *head;
 struct link *point, *mergep, *stonep;
 unsigned i, jndex;
 head = dir[index];
 merger(index);
 mergep = movep->merges->nextl;
 if (mergep) {
  do {
   rootp = (struct root *) mergep->loc;
   uprootl(rootp);
   jndex = rootp->ridx;
   stonep = rootp->neighbs->nextl;
   if (stonep) {
    do {
     jndex = stonep->loc;
     dir[jndex] = head;
     stonep = stonep->nextl;
    } while (stonep);
   }
   mergep = mergep->nextl;
  } while (mergep);
 }
}

void remcap(index)
unsigned index;
{
 struct root *rootp;
 unsigned *point;
 struct link *stonep, *capp;
 unsigned i, jndex;
 point = NEWS(index);
 for (i=1; i<=NLIBS; ++i) {
  jndex = *point;
  if (jndex) {
   rootp = dir[jndex];
   if (rootp) {
    if (rootp->clr != colour) {
     if (rootp->nlib == 1) {
      uprootl(rootp);
      movep->ncap += rootp->nsto;
      nopen += rootp->nsto;
      capp = (struct link *) locate(rootp, movep->caps);
      capp = (struct link *) insert(rootp, capp);
      stonep = rootp->neighbs->nextl;
      if (stonep) {
       do {
        jndex = stonep->loc;
        dir[jndex] = 0;
        del(jndex);
        if (colour == BLK) --wstones;
        else --bstones;
        stonep = stonep->nextl;
       } while (stonep);
      }
     }
    }
   }
  }
  ++point;
 }
 if (colour == WHT) bcaps += movep->ncap;
 if (colour == BLK) wcaps += movep->ncap;
}

void creroot(index)
unsigned index;
{
 struct root *rootp;
 struct link *point;
 unsigned i, jndex;
 rootp = (struct root *) allolarge();
 if (rootp) {
  dir[index] = rootp;
  rootp->neighbs = (struct link *) insert(0, 0);
  rootp->liberties = (struct link *) insert(0, 0);
  rootp->spaces = (struct link *) insert(0, 0);
  rootp->friends = (struct link *) insert(0, 0);
  rootp->enemies = (struct link *) insert(0, 0);
  rootp->contacts = (struct link *) insert(0, 0);
  rootp->clr = colour;
  rootp->nsto = 1;
  rootp->nlib = 0;
  rootp->ridx = index;
  rootp->incmod = 0;
  rootp->reallive = 1;
  rootp->realdead = 0;
  addrootl(rootp);
 }
}

unsigned doit(index)
unsigned index;
{
 unsigned valid;
 unsigned *ptr, indexok;
 unsigned time;
 ntrans = 0;
 valid = 0;
 occ = 0;
 sui = 0;
 ko = 0;
 keybreak(0);
 if (maxclk) if (*clkptr >= maxclk) timeattn = 999;
 if ((index >= 0) && (index <= nsize2)) {
  occ = (unsigned) dir[index];
  /*++kount;*/
  if (!occ) {
   movep = addmove(movep, index);
   if (index) {
    ko = kochk(index);
    if (!ko) {
     remcap(index);
     sui = suichk(index);
     if (!sui) {
      if (!movep->nsuicap) {
       --nopen;
       creroot(index);
       mergeroot(index);
      }
      life(index);
      add(index);
      /*countlibs();*/
      kogen(index);
      if (colour == BLK) ++bstones;
      else ++wstones;
      if (envon) {
       if (colour == BLK) {
        if (movep->ncap) wdead -= movep->ncap;
       }
       else {
        if (movep->ncap) bdead -= movep->ncap;
       }
       score();
      }
      if (timer) hundelay(timer);
     }
    }
   }
  }
  valid = !(occ || ko || sui);
  if (sui || ko) {
   if (index) {
    del(index);
    /*if (kount) {*/
     xthistp = xtlocate(kount, xthistp);
     if (xtmember(kount, xthistp)) xthistp = xtdelete(xthistp);
    /*}*/
    movep = (struct move *) unmove(movep);
   }
  }
  /*if (!valid) --kount;*/
  if (valid) {
   /*if (kount > 1) {*/ /* does this do anything? */
    mkeyes(index);
    mkspans(index);
    mksphere(index);
   /*}*/
   if (index) scrindex = index;
   ++kount;
   colour = flip(colour);
   ++ndoits;
  }
 }
 return (valid);
}

unsigned undoit()
{
 unsigned index;
 unsigned time;
 keybreak(0);
 index = 0;
 if (movep) {
  if(movep->prevm) colour = flip(colour);
  index = movep->midx;
  if (index && movep->prevm) {
   if (colour == BLK) --bstones;
   else --wstones;
   if (envon) {
    /*unlinkjz(index);*/
    if (colour == BLK) {
     if (movep->ncap) wdead += movep->ncap;
    }
    else {
     if (movep->ncap) bdead += movep->ncap;
    }
   }
   untrans(movep->transact);
   /*uneyes(index);*/
   unlife(index);
   /*uncountlibs();*/
   if (!movep->nsuicap) {
    unmergeroot(index);
    uncreroot(index);
    unremcap(index);
    del(index);
    ++nopen;
   }
   if (movep->nsuicap) {
    unchsui(index);
   }
   score();
  }
  if (movep->prevm) {
   --kount;
   xthistp = xtlocate(kount, xthistp);
   if (xtmember(kount, xthistp)) xthistp = xtdelete(xthistp);
   movep = unmove(movep);
   if (timer) hundelay(timer);
  }
 }
 if (movep->midx) scrindex = movep->midx;
 return (index);
}

corner