Got something to write about? Check out our Article Builder.

View \GOH.C

C souce code for the game of Go

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


/* file: goh.c */
/* use medium memory model to compile */

#define UNS unsigned

#define DONUT 0 /* 1 for isotropic board on torus with no edges */
#define DDD 0  /* 3 for 3D cube version, 2 for 2D surface of cube */
/* DONUT, DDD select type of board */
/* DONUT=0 DDD=0 for ordinary board */
/* DONUT=1 DDD=0 for wrap-around board (edgeless torus) */
/* DONUT=0 DDD=3 for 3-D solid cube */
/* DONUT=0 DDD=2 for surface of 3-D cube (incomplete) */

#if DDD                                                   /* 2.5D or 3D */
 #if DDD == 3                                             /* 3D */
 #define NLIBS 6   /* DNWESU */
 #define NDIAGS 12 /* DN DW DE DS NW NE SW SE UN UW UE US */
 #define NSIZE 7
 #define DIRSIZE NSIZE*NSIZE*NSIZE+1
 #else                                                    /* 2.5 D */
 #define NLIBS 4   /* N W E S */
 #define NDIAGS 4  /* NW NE SW SE */
 #define NSIZE 3
 #define DIRSIZE 6*NSIZE*NSIZE+1
 #endif
#else                                                     /* normal 2D */
#define NLIBS 4   /* N W E S */
#define NDIAGS 4  /* NW NE SW SE */
#define NSIZE 19
#define DIRSIZE NSIZE*NSIZE+1
#endif


#define BLK 1 /* used in loops... for(bw=BLK; bw<=WHT; ++bw) */
#define WHT 2

#define BCHAR 'O'  /* ASCII represention of live stones on board */
#define WCHAR 0x4

#define BSEKI 0xe9  /* ASCII represention of semi-live stones */
#define WSEKI 0x3

#define BDEAD 0x1  /* ASCII represention of realdead stones */
#define WDEAD 0x2


/* there are 3 dynamic memory systems based on LARGE, SMALL and EXTRA pages */
/* LARGE and SMALL pages use near pointers */
/* EXTRA pages are 16 bytes referenced by segment only (offset is 0) */
/* each system has an organization table of pointers to pages */
/* first 2 bytes of each page contain index to organization table */
/* pages are allocated by taking the next available page in table */
/* pages are freed by swapping pointers with the last page used */
/* see file "list.c" to search, insert and remove dynamic lists */

#define LARGE 28        /* +2=30 bytes/page  root,move structures */
#define SMALL 6         /* +2=8 bytes/page  sorted lists */
#define EXTRA 14      /* +2=16 bytes/page  pointer to segment only */

/*
#define MAXSCALE 12   /* fast access to rings provided by rings[] */

*/
#define MAXSCALE 46   /* fast access to rings provided by rings[] */


#define NEGINF 0      /* for score..() */
#define POSINF 19999
#define BIAS 10000

/* *********    keyboard codes     ********** */
/* key codes returned by solkey(), getkey() */
/* 7-bit ascii has upper byte zeroed */
#define LF     0x000a
#define CR     0x1c00 /* separate CR and Ctrl-M */
#define BACKSP 0x0e00 /* separate Backspace and Ctrl-H */
#define TAB    0x0f00 /* separate Tab and Ctrl-I */
/* IBM extended key code if lower byte zero */
#define F1     0x3b00
#define F2     0x3c00
#define F3     0x3d00
#define F4     0x3e00
#define F5     0x3f00
#define ESC    0x001b
#define INSERT 0x5200
#define DELETE 0x5300
#define HOME   0x4700
#define END    0x4f00
#define PGUP   0x4900
#define PGDN   0x5100
#define LEFT   0x4b00
#define RIGHT  0x4d00
#define UP     0x4800
#define DOWN   0x5000
#define CLEFT  0x7300
#define CRIGHT 0x7400
/* 128 special shift codes: 0x0080+n (0<=n<=0x7f) above 7-bit ascii */
#define SLEFT  0x0080
#define SRIGHT 0x0081
#define SUP    0x0082
#define SDOWN  0x0083





/* *********    structures     ********** */

/*
sorted lists are supported for SMALL and EXTRA memory page sizes:
   - a list always has at least one element
   - loc for first element of list is always zero
   - sorted by loc (loc>0)
   - level is context dependent
*/


struct link        /* links are SMALL */
{
 struct link *prevl, *nextl;
 unsigned loc;
} ;

struct root       /* roots are LARGE */
{
 unsigned clr;           /* BLK or WHT */
 unsigned nsto;          /* number of stones in root */
 unsigned nlib;          /* number of liberties of root */
 unsigned ridx;          /* index of last stone played in root */
 struct link *rootlp;    /* locates root in rootlist */
 struct link *neighbs;   /* connected stones (root) */
 struct link *liberties; /* empty liberty points */
 struct link *spaces;    /* empty diagonal points */
 struct link *friends;   /* friendly diagonal stones */
 struct link *enemies;   /* enemy diagonal stones */
 struct link *contacts;  /* enemy stone in liberty point*/
 unsigned incmod; /* rootp of old root if incrementally modified */
 unsigned reallive; /* 0 if dead, 1 if has 2 non-adjacent eyes */
 unsigned realdead; /* 1 if dead and all contacts are live */
} ;

struct move    /* moves are LARGE */
{
 struct move *prevm, *nextm;
 unsigned midx;        /* index of stone played */
 unsigned komove;      /* keep track of ko */
 unsigned ncap;        /* number of stones captured this play */
 struct link *caps;    /* pointers to captured roots */
 struct link *merges;  /* pointers to merged roots */
 unsigned nsuicap;     /* number captured by Chinese suicide */
 struct link *suicaps; /* pointers to roots of Chinese suicide */
 unsigned transact; /* xtlist of insertions and deletions */
} ;


/* "struct" xtlink list */   /* linkages EXTRA (pointers to segments) */
/* first two bytes taken up by the organization table reference */
#define PREVL 2      /* common for all xtlink list "structs" */
#define NEXTL 4      /*  "  */
#define LOC 6        /* usually sorted by this (board position) */
#define LEVEL 8      /* can also be sorted by this (score) */
#define ELVIS 10     /* hardly used */
#define PREVS 12  /* extra pointers maintain list sorted by LEVEL:LOC */
#define NEXTS 14  /* see functions max/minsort */




/*****  in the module containing main() global variables are  *****/
/*****   declared normally as c declarations by  #defining    *****/
/*****               #define EXTCDECL                         *****/
/*****    before     #include "GOH.H"                         *****/
/*****                                                        *****/
/***** in the other modules global variables are declared     *****/
/***** as extern by  #define EXTCDECL extern                  *****/
/***** before        #include "GOH.H"                         *****/


/* **********   global arrays   *********** */


EXTCDECL struct root *dir[DIRSIZE];
/* array for pointers to roots */
/* dir[index] == 0 implies index is open */

#if DDD
 #if DDD == 3
 EXTCDECL unsigned bors[NSIZE*NSIZE*NSIZE*6]; /* up, down for 3D */
 #else
 EXTCDECL unsigned bors[6*NSIZE*NSIZE*4]; /* for 2.5D */
 #endif
#else
EXTCDECL unsigned bors[NSIZE*NSIZE*4]; /* for normal 2D */
#endif
/* storage for indexes of 4 neighbors: north, west, east, south */


/*EXTCDECL unsigned *news[DIRSIZE];*/
/* pointers to bors  ---- NEWS macro instead */

#define NEWS(index) (bors + ((index)-1) * NLIBS)



EXTCDECL unsigned whose[DIRSIZE]; /* sphere of influence by distance */
/* low order byte contains distance */
/* high order byte contains 0/BLK/WHT identity of possessor */
/* maintained by uzgvmod and activated by sphron */


EXTCDECL char perisphr[DIRSIZE]; /* perimeter by sphere of influence */
/* 1 if point on perimeter, 0 otherwise */

/* low byte of gloparts is partition number */
/* high byte is owner of point if no partition (neutral) */
EXTCDECL unsigned gloparts[DIRSIZE]; /* global partitions */
EXTCDECL unsigned newparts[DIRSIZE]; /* temporary partitions */

EXTCDECL unsigned sphscore[3]; /* score by partitions and life */

#define NUMPARTS 50
EXTCDECL unsigned numparts; /* number of partitions */
EXTCDECL unsigned gbw; /* used with glom() to identify partition */
EXTCDECL unsigned npart; /* used with glom() to identify partition */
EXTCDECL unsigned pinfo[4]; /* used with glom() to identify partition */
EXTCDECL unsigned partinfo[51]; /* high byte colour - low b1=live b0=dead */
EXTCDECL unsigned partnvac[51]; /* number of vacant points in partition */
EXTCDECL unsigned partnocc[51]; /* number of occupied points */
EXTCDECL unsigned partindx[51]; /* location of first point in partition */

EXTCDECL unsigned char edgedist[DIRSIZE]; /* howfar() to edge (edge is 0) */

EXTCDECL unsigned char ownctrl[DIRSIZE]; /* 1 if point under own control */
EXTCDECL unsigned char owniz[DIRSIZE]; /* stones until eye: 0 means eye */



EXTCDECL char invid[DIRSIZE]; /* 1 if inverse video point */


EXTCDECL unsigned rings[MAXSCALE+1]; /* lists of rings for fast distance */
EXTCDECL unsigned hrings[MAXSCALE+1]; /* lists of halfrings */
/* dist=2..MAXSCALE  rings[dist] is segptr to xtlist of vectors to ring */
/* LOC = sequential number */
/* LEVEL = (int) dx */
/* (LEVEL+2) = (int) dy */



EXTCDECL unsigned hits[121]; /* used for probability of connection */
EXTCDECL unsigned location[121]; /* used to locate pathpoints */
EXTCDECL unsigned binary[20]; /* connection counter */
EXTCDECL unsigned path[20]; /* actual positions of a connection */


/* **********   lists for both players   *********** */

EXTCDECL unsigned nodes[3]; /* xtlist LOC=index of stone nodes[0,BLK,WHT] */
EXTCDECL unsigned spans[3]; /* xtlist LOC=index LEVEL=ptr to jndexes */
EXTCDECL unsigned areas[3]; /* xtlist LOC=index ... more levels */


/* for check, these contain global versions of nodes, spans */
EXTCDECL unsigned gnodes[3]; /* xtlist loc=index of stone nodes[0,BLK,WHT] */
EXTCDECL unsigned gspans[3]; /* xtlist loc=seqno level=p (level+2)=q */



/* **********   other globals   *********** */

EXTCDECL unsigned ntrans; /* to order movep->transact transactions */
EXTCDECL unsigned player; /* BLK or WHT machine's identity for score */
EXTCDECL unsigned opponent; /* BLK or WHT opponent of player */
EXTCDECL unsigned dbglevel;/* 0 for none, 1,2 for debug att/def (fight.c) */
EXTCDECL unsigned chinese;/* 1 for Chinese rules,  0 for Japanese */
EXTCDECL unsigned condition;/* Manhattan distance to opponent */
EXTCDECL unsigned atari;/* klatu? */
EXTCDECL unsigned timer;/* 0 is fast */
EXTCDECL unsigned inform;/* = 1 to tell about occ,sui,ko */
EXTCDECL unsigned hide;/* 1 to inhibit display */
EXTCDECL unsigned hidelook;/* user control to inhibit display */
EXTCDECL unsigned curhide;/* 1 to forget cursor in add and del */
EXTCDECL unsigned nvalrow;/* force pass if repeated invalid */
EXTCDECL unsigned bauto, wauto;/* 1 to compute the next b/w move */
EXTCDECL unsigned windex;/* 1..361  location of present move
                           index = i + (j-1) * 19
                           where i,j = 1..19 locate move */

EXTCDECL unsigned colour; /* black or white for present move */
EXTCDECL unsigned valid; /* !valid = occ | sui | ko  */
EXTCDECL unsigned occ, sui, ko; /* occupied, suicide, ko */
EXTCDECL unsigned suilegal; /* =0 to prune chinese suicide moves */


EXTCDECL unsigned bcaps;/* number of black stones captured */
EXTCDECL unsigned wcaps;/* number of white stones captured */
EXTCDECL unsigned bstones;/* number of black stones on board */
EXTCDECL unsigned wstones;/* white stones on board */
EXTCDECL unsigned bter;/* black territory (not including stones) */
EXTCDECL unsigned wter;/* white territory */
EXTCDECL unsigned bdead;/* number of dead black stones on board */
EXTCDECL unsigned wdead;/* dead white stones */
EXTCDECL unsigned bscore;/* black score (scores depend on rules) */
EXTCDECL unsigned wscore;/* white score */

EXTCDECL unsigned sekisto[3]; /* number of dead stones for b/w */
EXTCDECL unsigned eyeterr[3]; /* number of eyes using mkeyes() */
EXTCDECL unsigned deadsto[3]; /* number of stones of real dead roots */
EXTCDECL unsigned deadlib[3]; /* number of libs of real dead roots */
EXTCDECL int eyescore[3];/* score using eye info (not depend on rules) */

EXTCDECL unsigned triterr[3]; /* area using mkspans() */
EXTCDECL unsigned triscore[3];/* score as area using eyes and mkspans() */



EXTCDECL unsigned ndoits;/* number of moves examined */
EXTCDECL unsigned npdoits;/* for prompt() printout */
EXTCDECL unsigned nopen;/* number of possible moves available */

EXTCDECL unsigned col80;/* true if 80 columns */



/*EXTCDECL struct link *env;/* common envelope structure */*/




EXTCDECL char nline;/* controls print position using "typeset" */
EXTCDECL char nchar;/* controls print position using "typeset" */

EXTCDECL unsigned nsize2;/* nsize squared --- maximum index */
EXTCDECL unsigned nsize21;/* nsize squared --- maximum index +1 */
EXTCDECL unsigned nsize;/* 19 max */

EXTCDECL unsigned kount;  /* kount number of moves */
EXTCDECL unsigned nowkount;  /* kount before lookahead occurs */
EXTCDECL unsigned fixhead; /* to fix lookahead (see headjob()) */




EXTCDECL unsigned maxlizard; /* max lookahead for att/def (a/d) */
EXTCDECL unsigned maxcounter; /* max kount for counter att/def a/d */
EXTCDECL unsigned max3;  /* max kount for attacking roots with 3 libs a/d */
EXTCDECL unsigned maxgeta;  /* max kount for diagonal attacks a/d */
EXTCDECL unsigned maxfork;  /* max kount for dilemmas a/d */
EXTCDECL unsigned maxenv; /* max kount for envelope (use with geta) */
EXTCDECL unsigned maxeyes; /* max kount for eyeson */
EXTCDECL unsigned maxspan; /* max kount for eyeson */
EXTCDECL unsigned bugcheck; /* max viral lookahead */


EXTCDECL unsigned gameover;
EXTCDECL unsigned nforget; /* able to retract nforget moves */

EXTCDECL unsigned xdist;/* max dist for probabilistic connection */

EXTCDECL unsigned char ic, jc, kc; /* ? */


EXTCDECL struct move *movep;/* pointer to move structures */
EXTCDECL struct link *rootlist;/* maintain list of roots */
EXTCDECL unsigned treelist; /* doubly sorted list of doubly sorted lists */
EXTCDECL unsigned treep; /* (LEVEL+2) has pointer to next list */

EXTCDECL unsigned amount;/* bytes of memory to be allocated (small) */
EXTCDECL unsigned *lastused;/* for memory allocation - allosmall */
EXTCDECL unsigned *avail;/* for memory allocation - freesmall */
EXTCDECL unsigned npage;/* current number of pages in use */
EXTCDECL unsigned maxpage;/* maximum number of pages used so far */
EXTCDECL unsigned allomax;/* maximum possible number of pages */
EXTCDECL unsigned *first;/* location of allocation region */
EXTCDECL unsigned *last;/* top of available region - initsmall */

EXTCDECL unsigned amtlg;/* bytes of memory to be allocated (large) */
EXTCDECL unsigned *lastlg;/* for memory allocation */
EXTCDECL unsigned *avlg;/* for memory allocation */
EXTCDECL unsigned nplg;/* current number of pages in use */
EXTCDECL unsigned mxlg;/* maximum number of pages used so far */
EXTCDECL unsigned almxlg;/* maximum possible number of pages */
EXTCDECL unsigned *flg;/* location of allocation region */
EXTCDECL unsigned *llg;/* top of available region */

EXTCDECL unsigned amtxt;/* bytes of memory to be allocated (extra) */
EXTCDECL unsigned lastxt;/* for memory allocation */
EXTCDECL unsigned avxt;/* for memory allocation */
EXTCDECL unsigned npxt;/* current number of pages in use */
EXTCDECL unsigned mxxt;/* maximum number of pages used so far */
EXTCDECL unsigned almxxt;/* maximum possible number of pages */
EXTCDECL unsigned fxt;/* location of allocation region (seg only) */
EXTCDECL unsigned lxt;/* top of available region */
EXTCDECL void far *farxt;/* far ptr for farmalloc and farfree */

EXTCDECL long far *clkptr; /* BIOS clock ticks count since midnight */
EXTCDECL long far maxclk; /* 1092 per minute, or  zero, set timeattn in doit */
EXTCDECL unsigned numticks; /* number of ticks per move */
EXTCDECL unsigned timeattn;/* use as timer interrupt with numticks in doit */

EXTCDECL void far *lib;/* bw lib .. 1 if root lib (see get/setlib) (1bit) */
EXTCDECL void far *eye;/* bw eye .. 0 if deadeye (see get/seteye) (3bits) */
EXTCDECL void far *coneye;/* bw conflicting (see get/setceye) (1bit) */
EXTCDECL void far *oneeye;/* bw one eye info (see get/setoeye) (1bit) */
EXTCDECL void far *gudeye;/* bw good eye (see get/setgeye) (1bit) */

EXTCDECL void far *farndir;/* bw node directory (see get/setnode) */

EXTCDECL unsigned far *X;/* far vector X[index] is x coordinate of index */
EXTCDECL unsigned far *Y;/* far vector Y[index] is y .. replaces xy() */

EXTCDECL unsigned *minstk;/* min stack so far */
EXTCDECL unsigned *pminstk;/* print min stack only when necessary */

EXTCDECL unsigned scrindex;/* screen index (board cursor) */
EXTCDECL unsigned linum;/* current line number in scrolling area */
EXTCDECL unsigned attn;/* keybreak uses this as interrupt */
EXTCDECL unsigned mask;/* mask out keyboard from o/s for keybreak */

EXTCDECL unsigned vdadd; /* vdm memory address */

EXTCDECL unsigned xthistory; /* maintain all moves played */
EXTCDECL unsigned xthistp;  /* pointer for above list */


EXTCDECL unsigned char tmin,thour,thund,tsec; /* cput cpu timer */


EXTCDECL unsigned maxarea; /* max dist for measurement of triangular area */

EXTCDECL unsigned maxscale; /* max min group to group distance */
EXTCDECL unsigned maxdist; /* max dist to empty pt from occupied */


/* envon=1   =>  make envelope around root */
/* envon=0   =>  just keep stones and liberties */
EXTCDECL unsigned envon; /* off faster than envon on - off not used in *.c */
EXTCDECL unsigned eyeson; /* =1 to keep track of simple eyes */
EXTCDECL unsigned obseye; /* =1 to keep track of simple eyes the slow way */
EXTCDECL unsigned edgeon; /* =1 to allow edge nodes */
EXTCDECL unsigned spanon; /* =1 to allow spans */
EXTCDECL unsigned areaon; /* =1 to compute area using eyes and spans */
EXTCDECL unsigned sphron; /* =1 to allow sphere of influence */
EXTCDECL unsigned parton; /* =1 for partitions with envon,eyeson,sphron */

EXTCDECL unsigned nbeyes; /* number of potential eyes in beyes[] */
EXTCDECL unsigned nweyes; /* number of potential eyes in weyes[] */



EXTCDECL unsigned cyclops; /* =1 for one-eyed life */


EXTCDECL unsigned dizzy; /* rotation control of north(), south.. */

EXTCDECL unsigned xrad;  /* x 'radius' of graphic stone */
EXTCDECL unsigned yrad;  /* y 'radius' (stone elliptical) */
EXTCDECL int npersp; /* max (abs) persp */
EXTCDECL int persp; /* 0 for square  +n or -n for perspective */
EXTCDECL unsigned twister; /* 0,1,2,3 to rotate board */

#if DDD == 3
EXTCDECL unsigned zinc; /* y increment for z-axis display */
#endif

#if DONUT
EXTCDECL int xdonut; /* offset to recenter board */
EXTCDECL int ydonut; /* offset to recenter board */
#endif

EXTCDECL int graphmode;  /* save for mode switching */
EXTCDECL int visipage;  /* supported by Herc, EGA, VGA */

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.