C souce code for the game of Go
Submitted By:
WEBMASTER
Rating:





(
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 */