Do you receive the Programmer's Heaven newsletter? If not, why not subscribe?

View \SPHERE.C

C souce code for the game of Go

Submitted By: WEBMASTER
Rating: starstarstarhalf star (Rate It)


/* Spheres of influence */
#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"

void glom(unsigned i); /* prototype */

void glom(unsigned i)
{
 unsigned j, jndex, *point;
 struct root *rootp;
 rootp = dir[i];
 if (!rootp) ++pinfo[2];
 else {
  ++pinfo[3];
  if (!rootp->realdead) pinfo[0] = 0;
  if (rootp->reallive) pinfo[1] = 1;
 }
 gloparts[i] = npart;
 point = NEWS(i);
 for (j=0; j<NLIBS; ++j) {
  jndex = *point;
  if (jndex) {
   if (!gloparts[jndex]) {
    if (gbw == (whose[jndex] >> 8)) {
     glom(jndex);
    }
   }
  }
  ++point;
 }
}

unsigned neutral(unsigned index)
{
 unsigned bw; /* ownership of neutral point  0 if no owner */
 unsigned i, jndex, *point, jbw, jinfo, partno;
 unsigned  deadp[3], livep[3];
 deadp[BLK] = 1;
 deadp[WHT] = 1;
 livep[BLK] = 0;
 livep[WHT] = 0;
 point = NEWS(index);
 for (i=0; i<NLIBS; ++i) {
  jndex = *point;
  if (jndex) {
   partno = gloparts[jndex];
   if (partno) {
    jinfo = partinfo[partno];
    jbw = jinfo >> 8;
    if (jbw) {
     if (!(jinfo & 1)) deadp[jbw] = 0;
     if (jinfo & 2) livep[jbw] = 1;
    }
   }
  }
  ++point;
 }
 if (deadp[WHT] && livep[BLK]) bw = BLK;
 else if (deadp[BLK] && livep[WHT]) bw = WHT;
 else bw = 0;
 return(bw);
}

void rescale()
{
 /* this sets scale for spans */
 unsigned i, max, dist;
 max = 0;
 for (i=1; i<=nsize2; ++i) {
  dist = whose[i] & 255;
  if (dist > max) max = dist;
 }
 newline();
 printf(" rescale dist %d", max);
}
 
void evaluate()  /* global partitioning */
{
 unsigned i, value, bw;
 npart = 0;
 for (i=1; i<=nsize2; ++i) gloparts[i] = 0;
 for (i=1; i<=nsize2; ++i) {
  gbw = 0;
  if (!gloparts[i]) {
   gbw = whose[i] >> 8;
   if (gbw) {
    pinfo[0] = 1; /* dead: false if any root not realdead */
    pinfo[1] = 0; /* live: true if any root realdead */
    pinfo[2] = 0; /* nvac: count number of vacant points */
    pinfo[3] = 0; /* nocc: count number of occupied points */
    ++npart;
    glom(i);
    value = (gbw << 8) + pinfo[0] + (pinfo[1] << 1);
    partinfo[npart] = value;
    partnvac[npart] = pinfo[2];
    partnocc[npart] = pinfo[3];
    partindx[npart] = i;
   }
  }
 }
 numparts = npart;
 /* first compute score without considering neutral points */
 sphscore[BLK] = wcaps; /* black counts whites removed from board by capture */
 sphscore[WHT] = bcaps;
 for (i=1; i<=numparts; ++i) {
  bw = partinfo[i] >> 8;
  if (partinfo[i] & 2) sphscore[bw] += partnvac[i];
  if (partinfo[i] & 1) sphscore[flip(bw)] += partnvac[i] + 2 * partnocc[i];
 }
 /* now account for ownership of neutral points */
 for (i=1; i<=nsize2; ++i) {
  if (!(whose[i]>>8)) {
   bw = neutral(i);
   if (bw) {
    ++sphscore[bw];
    gloparts[i] |= bw << 8; /* put owner of neutral point in high byte */
   }
  }
 }
}

unsigned scandist(unsigned index, unsigned bw)
{
 unsigned dist;
 unsigned indexes;
 dist = 1;
 indexes = xtinsert(0, 0);
 do {
  ++dist;
  cring(index, dist, indexes, bw);
 } while ((dist < MAXSCALE) && !peek(indexes, NEXTL));
 xtfreelist(indexes);
 return(dist);
}

void mksphere(unsigned index)
{
 struct link *frontier, *fp;
 struct link *interior, *ip;
 /*struct link *domicile, *dp;*/
 struct link *libs, *lp;
 struct link *capp, *neighbp;
 struct root *rootp;
 unsigned jndex, kndex;
 unsigned *point, i;
 unsigned jclr, ojclr; /* new and old assessment of whose point */
 unsigned jdst, ojdst; /* new and old assessment of dist to point */
 unsigned change; /* 1 if possession of point has changed */
 unsigned alter; /* 1 if whose[] needs to be updated */
 if (!sphron) return; /* return if not selected */
 /*if (!index) return;  /* if pass, nothing changes */*/
 /* Chinese suicide not supported */
 /* first change dist of captured stones to 255 using uzgvmod */
 /* to make sure that change gets undone */
 capp = movep->caps->nextl;
 if (capp) {
  do {
   rootp = (struct root *) capp->loc;
   neighbp = rootp->neighbs->nextl;
   do {
    jndex = neighbp->loc;
    jclr = flip(whose[jndex] >> 8);
    uzgvmod(&whose[jndex], (jclr<<8)+scandist(jndex, jclr));
    neighbp = neighbp->nextl;
   } while (neighbp);
   capp = capp->nextl;
  } while (capp);
 }
 frontier = insert(0, 0);
 interior = insert(0, 0);
 /*domicile = insert(0, 0);*/
 /* start with frontier as stone just played */
 insert(index, frontier);
 ojclr = whose[index] >> 8/* get old possessor */
 jclr = colour;           /* potential new possessor */
 uzgvmod(&whose[index], (jclr<<8)); /* indicate possession of index */
 do {
  /* go through frontier and accumulate lib positions in libs */
  libs = insert(0, 0); /* store all libs of frontier here */
  lp = libs;
  fp = frontier->nextl;
  if (fp) {
   do {
    jndex = fp->loc;     /* jndex is point on the frontier */
    point = NEWS(jndex); /* pointer to liberty positions */
    for (i=0; i<NLIBS; ++i) {
     kndex = *point;      /* kndex is in lib posn of jndex */
     if (kndex) {         /* ensure point on board */
      if (!dir[kndex]) {  /* must be empty (no stone) */
       lp = locate(kndex, lp); /* put it in libs */
       lp = insert(kndex, lp);
      }
     }
     ++point;
    }
    fp = fp->nextl;
   } while (fp);
  }
  /* put frontier in interior */
  ip = interior;
  fp = frontier->nextl;
  if (fp) {
   do {
    jndex = fp->loc;        /* from frontier */
    ip = locate(jndex, ip);
    ip = insert(jndex, ip); /* to interior */
    fp = fp->nextl;
   } while (fp);
  }
  freelist(frontier);      /* a bit of a swap here */
  frontier = insert(0, 0); /* new (empty) frontier */
  /*dp = domicile;*/
  ip = interior;
  fp = frontier;
  /* test libs not in interior for change */
  lp = libs->nextl;
  if (lp) {
   do {
    jndex = lp->loc; /* jndex of lib of old frontier */
    ip = locate(jndex, ip);
    if (!member(jndex, ip)) { /* no good if in interior */
     /* has possession of point jndex changed due to index? */
     change = 0;
     alter = 0;
     ojclr = whose[jndex] >> 8/* get old possessor */
     ojdst = whose[jndex] & 255; /* get old distance */
     jclr = colour;  /* may be set neutral later */
     jdst = howfar(index, jndex); /* dist to index */
     if (!ojclr && (ojdst == jdst)) jclr = 0; /* stay neutral */
     if (jdst < ojdst) {
      if (jclr != ojclr) change = 1;
      alter = 1;
     }
     if (jdst == ojdst) {
      if (jclr != ojclr) {
       change = 1;
       alter = 1;
       jclr = 0;
      }
     }
     if (alter || change) {
      fp = locate(jndex, fp); /* put change in new frontier */
      fp = insert(jndex, fp);
      /*
      if (jclr == colour) {
       dp = locate(jndex, dp); /* extent of influence of index */

       dp = insert(jndex, dp);
      }
      */
     }
     if (alter) uzgvmod(&whose[jndex], (jclr<<8)+jdst);
     if (!change) {
      ip = locate(jndex, ip); /* if no change then interior */
      ip = insert(jndex, ip);
     }
    }
    lp = lp->nextl;
   } while (lp);
  }
  freelist(libs);
 } while (frontier->nextl);
 freelist(interior);
 freelist(frontier);
}

void evaperim()
{
 unsigned i, index, jndex, *point, bw, whoj;
 for (index=1; index<=nsize2; ++index) {
  perisphr[index] = 0;
  if (!dir[index]) {
   bw = whose[index] >> 8;
   if (!bw) perisphr[index] = 1;
   else {
    point = NEWS(index);
    for (i=0; i<NLIBS; ++i) {
     jndex = *point;
     if (jndex) {
      whoj = whose[jndex] >> 8;
      if (whoj) {
       if (whoj != bw) {
        perisphr[index] = 1;
        break;
       }
      }
     }
     ++point;
    }
   }
  }
 }
}

unsigned owner(unsigned index)
{
 unsigned bw;
 unsigned numpart;
 bw = whose[index] >> 8;
 if (bw) {
  numpart = gloparts[index] & 255;
  if (partinfo[numpart]&1) bw = flip(bw);
  if (!((partinfo[numpart]&2) || (partinfo[numpart]&1))) bw = 0;
 }
 else bw = gloparts[index] >> 8;
 return(bw);
}

unsigned alive(unsigned index)
{
 unsigned bw;
 unsigned numpart;
 bw = whose[index] >> 8;
 if (bw) {
  numpart = gloparts[index] & 255;
  if (!(partinfo[numpart]&2)) bw = 0;
 }
 else bw = gloparts[index] >> 8;
 return(bw);
}

unsigned dead(unsigned index)
{
 unsigned bw;
 unsigned numpart;
 bw = whose[index] >> 8;
 if (bw) {
  numpart = gloparts[index] & 255;
  if (partinfo[numpart]&1) bw = 0;
 }
 else bw = gloparts[index] >> 8;
 return(!bw);
}

corner
© 1996-2008. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Publisher: Lars Hagelin.
bootstrapLabs Logo A bootstrapLabs project.