#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	Makefile
#	README
#	basics.c
#	godefs.h
#	set.c
#	set.h
#	test.c
# This archive created: Thu Dec 20 18:55:52 1990
export PATH; PATH=/bin:$PATH
echo shar: extracting "'Makefile'" '(100 characters)'
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
XCFLAGS = -g
XCC=gcc
X
XOBJS = basics.o set.o test.o
X
Xgo: $(OBJS)
X	gcc -o go $(OBJS) -lcurses -ltermcap
SHAR_EOF
if test 100 -ne "`wc -c < 'Makefile'`"
then
	echo shar: error transmitting "'Makefile'" '(should have been 100 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'README'" '(1262 characters)'
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
XThese files forms a (very basic) part of a computer go players perseption.
XThe functions and structures implements the go board while keeping track
Xof rules (though with a simple ko-rule), block (sometimes called strings
Xor groups) and with the possibility of undoing any number of moves.
XIt should be possible (so says B. Wilcox) to build a tactian with
Xjust this simple view of the board.
X
XThe representation of blocks is designed for incremental update. The
Xreason for the possibly inactive status of some block is easy undo.
X
XAll this code is in an early state, but i wanted to get it out while
Xthe water was boiling in rec.games.go. I have implemented David Bensons
Xunconditional life algorithm and is halfway though with a FAST pattern-
Xmatcher (actually, I didn't think anything good of pattern matching,
Xbut a friend of mine and myself happend to fall over a very good idea).
X
XIncluded just for fun is a test program which borrows much from Jeff
XRosenfeld (thank you, jeff!).
X
XIt is hereby placed in the public domain, Tommy Thorn Dec 1990
X-----------------------------------------------------------------------
XTommy Thorn                       email: tthorn@daimi.aau.dk
XComputer Science Department       I SPEAK FOR MYSELF!
XAarhus University 
XDENMARK
SHAR_EOF
if test 1262 -ne "`wc -c < 'README'`"
then
	echo shar: error transmitting "'README'" '(should have been 1262 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'basics.c'" '(9845 characters)'
if test -f 'basics.c'
then
	echo shar: will not over-write existing file "'basics.c'"
else
sed 's/^X//' << \SHAR_EOF > 'basics.c'
X/*
X * BASICS -- basic view of the go board
X *
X * created 7/12-90
X *
X * Tommy Thorn                       email: tthorn@daimi.aau.dk
X * Computer Science Department       I SPEAK FOR MYSELF!
X * Aarhus University 
X * DENMARK
X */
X
X#include <stdio.h>
X#include "godefs.h"
X
Xint dir[9][5]; /* dir[dirindex[s]] gives a zero terminated list */
X
Xblock *newblock(basicview *);
X
X#define push(bv, i) bv->undostack[bv->undosp++] = i
X#define pop(bv) bv->undostack[--bv->undosp]
X#define top(bv) bv->undostack[bv->undosp-1]
X
Xvoid init(basicview *bv, int w)
X{
X    int i, *n, k;
X    
X    /* initialise dir, nothing to do with bv */
X    
X    for (i = 0; i < 9; ++i) {
X        n = dir[i];
X        if (i >= 3) *n++ = -w;
X        if (i % 3 != 2) *n++ = 1;
X        if (i <= 5) *n++ = w;
X        if (i % 3 != 0) *n++ = -1;
X        *n = 0;
X    }
X    
X    bv->w = w;
X    bv->max = w*w-1;
X    bv->turn = 1;
X    bv->to_play = BLACK;
X    bv->passes = 0;
X    bv->ko_spot = -1;
X    bv->next_free_id = 0;
X    
X    for (i = w*w-1; 0 <= i; --i) {
X        bv->dirindex[i] = 4;
X        bv->color[i] = EMPTY;
X	bv->block_id[i] = -1;
X    }
X    
X    for (i = 1, k = (w-1)*w+1; i < w-1; ++i, ++k)
X      bv->dirindex[i] = 1, bv->dirindex[k] = 7;
X    for (i = 1; i < w-1; ++i)
X      bv->dirindex[i*w] = 3, bv->dirindex[i*w+w-1] = 5;
X    bv->dirindex[0] = 0; bv->dirindex[w-1] = 2;
X    bv->dirindex[w*w-w] = 6; bv->dirindex[w*w-1] = 8;
X    bv->undosp = 0;
X}
X
Xblock *newblock(basicview *bv)
X{
X    block *bp;
X    
X    bp = (block *) malloc(sizeof(block));
X    memset(bp, 0, sizeof(block));
X    bp->id = bv->next_free_id;
X    bv->block_ref[bv->next_free_id++] = bp;
X    return bp;
X}
X
Xrecycleblock(basicview *bv, block *bp)
X{
X    if (bp->id != bv->next_free_id-1)
X      fprintf(stderr, "What!\n"), exit(1);
X    
X    bv->next_free_id--;
X    bv->block_ref[bp->id] = NULL;
X    free(bp);
X}
X
Xint moveis(basicview *bv, int s)
X{
X    int n, friend, connecting, nlibs, captures;
X    
X    if (s == -1)
X      return MOVEIS_PASS;
X    if (s < 0 || s > bv->max)
X      return ERR_OUT_OF_BOARD;
X    if (bv->color[s] != EMPTY)
X      return ERR_OCCUPIED;
X    if (s == bv->ko_spot)
X      return ERR_KO_VIOLATION;
X    if (bv->passes == 2)
X      return ERR_GAME_OVER;
X    
X    nlibs = connecting = captures = 0;
X    friend = -1;
X    {
X	foreachneighbor(bv, s, n)
X	  if (bv->color[n] == EMPTY)
X	    ++nlibs;
X	  else if (bv->color[n] == bv->to_play) {
X	      if (friend != -1 && friend != bv->block_id[n])
X		connecting = YES;
X	      friend = bv->block_id[n];
X	      nlibs += bv->block_ref[friend]->nlibs - 1;
X	  }
X	  else if (bv->block_ref[bv->block_id[n]]->nlibs == 1)
X	    captures = MOVE_CAPTURES;
X    }
X    
X    /* note: nlibs may not be the correct number of liberties for the
X       resulting block, but it is zero in case of suicide */
X    if (nlibs == 0 && !captures)
X      return ERR_SUICIDE;
X    if (friend == -1)
X      return MOVEIS_NEW + captures;
X    if (connecting)
X      return MOVEIS_CONNECT + captures;
X    else
X      return MOVEIS_EXTEND + captures;
X}
X
Xblock *block_simple(basicview *bv, int s, int movetype)
X{
X    block *bp;
X    int n;
X    
X    bv->color[s] = bv->to_play;
X    if (movetype == MOVEIS_NEW || movetype == MOVEIS_NEW+MOVE_CAPTURES)
X      bp = newblock(bv), bp->color = bv->to_play;
X    else {
X	foreachneighbor(bv, s, n)
X	  if (bv->color[n] == bv->to_play) {
X	      bp = bv->block_ref[bv->block_id[n]];
X	      break;
X	  }
X    }
X    setadd(bp->stones, s);
X    if (movetype == MOVEIS_EXTEND || movetype == MOVEIS_EXTEND+MOVE_CAPTURES)
X      setremove(bp->libs, s), --bp->nlibs;
X    bv->block_id[s] = bp->id;
X    {
X	foreachneighbor(bv, s, n)
X	  if (bv->color[n] == EMPTY && !setisin(bp->libs, n))
X	    setadd(bp->libs, n), ++bp->nlibs;
X    } 
X    return bp;
X}
X
Xblock *block_connect(basicview *bv, int s)
X{
X    block *bp, *nbp;
X    int n;
X    
X    bv->color[s] = bv->to_play;
X    bp = newblock(bv);
X    bp->color = bv->to_play;
X    setadd(bp->stones, s);
X    {
X	foreachneighbor(bv, s, n)
X	  if (bv->color[n] == EMPTY)
X	    setadd(bp->libs, n);
X	  else if (bv->color[n] == bv->to_play && !setisin(bp->stones, n)) {
X	      nbp = bv->block_ref[bv->block_id[n]];
X	      
X	      setunion(bp->stones, bp->stones, nbp->stones);
X	      setunion(bp->libs, bp->libs, nbp->libs);
X	      nbp->status = BLOCK_INACTIVE;
X	      push(bv, nbp->id); /* push info for easy undo of connect */
X	  }
X    } 
X    setremove(bp->libs, s);
X    bp->nlibs = setsize(bp->libs);
X    {
X	setforeach(bp->stones, n)
X	  bv->block_id[n] = bp->id;
X    } 
X    return bp;
X}
X
Xint play(basicview *bv, int s)
X{
X    block *nbp;
X    int movetype, n, old_undosp = bv->undosp;
X    int old_ko = bv->ko_spot;
X    
X    switch (movetype = moveis(bv, s)) {
X      case ERR_OUT_OF_BOARD:
X      case ERR_OCCUPIED:
X      case ERR_KO_VIOLATION:
X      case ERR_SUICIDE:
X      case ERR_GAME_OVER:
X	return movetype;
X      case MOVEIS_PASS:
X	bv->passes++;
X	bv->to_play = OTHER(bv->to_play);
X	bv->turn++;
X	push(bv, bv->ko_spot);
X	push(bv, MOVEIS_PASS);
X	bv->ko_spot = -1;
X	
X	return MOVEIS_PASS;
X	
X	/* in the case of a good move, first update color, stones and libs */
X      case MOVEIS_NEW:
X      case MOVEIS_EXTEND:
X      case MOVEIS_NEW+MOVE_CAPTURES:
X      case MOVEIS_EXTEND+MOVE_CAPTURES:
X	block_simple(bv, s, movetype);
X	break;
X      case MOVEIS_CONNECT:
X      case MOVEIS_CONNECT+MOVE_CAPTURES:
X	block_connect(bv, s);
X	break;
X      default:
X	fprintf(stderr, "moveis returned %d in play\n", movetype), exit(1);
X    }
X    
X    /* now update my neighbors liberties and possibly capture them */
X    {
X	foreachneighbor(bv, s, n)
X	  if (bv->color[n] == OTHER(bv->to_play)) {
X	      nbp = bv->block_ref[bv->block_id[n]];
X	      if (setisin(nbp->libs, s)) {
X		  setremove(nbp->libs, s);
X		  --nbp->nlibs;
X		  if (nbp->nlibs == 0) {
X		      capture_block(bv, nbp);
X		      push(bv, nbp->id); /*push capturing info for easy undo*/
X		      if (setsize(nbp->stones) == 1)
X			bv->ko_spot = n; /* possibly a ko spot */
X		  }
X	      }
X	  }
X    } 
X    
X    if (bv->block_ref[bv->block_id[s]]->nlibs != 1
X	|| !(movetype & MOVE_CAPTURES))
X      bv->ko_spot = -1;
X    bv->turn++;
X    bv->to_play = OTHER(bv->to_play);
X    bv->passes = 0;
X    push(bv, old_ko);
X    n = bv->undosp - 1 - old_undosp;
X    push(bv, movetype + 8*n + 64 * s);
X    
X    return movetype;
X}
X
X/* run through every stone of the block, setting block_id[i] = -1
X *      for each neighbor if enemy and hasn't i as liberty
X *         get i as liberty and update nlibs
X */
X
Xcapture_block(basicview *bv, block *bp)
X{
X    int n, i, enemy = OTHER(bp->color);
X    block *nbp;
X    
X    bp->status = BLOCK_CAPTURED;
X    {
X	setforeach(bp->stones, i) {
X	    bv->block_id[i] = -1;
X	    bv->color[i] = EMPTY;
X	    {
X		foreachneighbor(bv, i, n) {
X		    if (bv->color[n] == enemy) {
X			nbp = bv->block_ref[bv->block_id[n]];
X			if (!setisin(nbp->libs, i)) {
X			    setadd(nbp->libs, i);
X			    ++nbp->nlibs;
X			}
X		    }
X		}
X	    } 
X	} 
X    }
X
X}
X
X/* run through every stone of the block, setting block_id[i] = bp->id
X *    for each neighbor if enemy and has i as lib
X *         remove i as lib ..
X */
X
Xuncapture_block(basicview *bv, block *bp)
X{
X    int n, i, enemy = OTHER(bp->color);
X    block *nbp;
X    
X    bp->status = BLOCK_ACTIVE;
X    {
X	setforeach(bp->stones, i) {
X	    
X	    bv->block_id[i] = bp->id;
X	    bv->color[i] = bp->color;
X	    {
X		foreachneighbor(bv, i, n)
X		  if (bv->color[n] == enemy) {
X		      nbp = bv->block_ref[bv->block_id[n]];
X		      if (setisin(nbp->libs, i)) {
X			  setremove(nbp->libs, i);
X			  --nbp->nlibs;
X		      }
X		  }
X	    } 
X	} 
X    }
X}
X
Xundo_simple(basicview *bv, int s, int movetype, block *bp)
X{
X    int n, nn;
X    
X    bv->color[s] = EMPTY;
X    bv->block_id[s] = -1;
X    if (movetype == MOVEIS_EXTEND || movetype == MOVEIS_EXTEND+MOVE_CAPTURES) {
X	foreachneighbor(bv, s, n)
X	  if (bv->color[n] == bv->to_play) {
X	      bp = bv->block_ref[bv->block_id[n]];
X	      break;
X	  }
X	
X	setremove(bp->stones, s);
X	setadd(bp->libs, s), ++bp->nlibs;
X	{
X	    foreachneighbor(bv, s, n)
X	      if (bv->color[n] == EMPTY) {
X
X		  /* have to check if this is still a liberty */
X		  foreachneighbor(bv, n, nn) {
X		      if (bv->block_id[nn] == bp->id)
X			goto ok;
X		  } 
X		  /* the liberty is gone */
X		  --bp->nlibs;
X		  setremove(bp->libs, n);
X		ok:;
X	      }
X	}
X    }
X    else
X      recycleblock(bv, bp);
X}
X
Xundo_connect(basicview *bv, int s, block *bp, int old_undosp)
X{
X    block *nbp;
X    int n;
X    
X    bv->color[s] = EMPTY;
X    bv->block_id[s] = -1;
X    while (bv->undosp != old_undosp) {
X	nbp = bv->block_ref[pop(bv)];
X	nbp->status = BLOCK_ACTIVE;
X	{
X	    setforeach(nbp->stones, n)
X	      bv->block_id[n] = nbp->id;
X	} 
X    }
X    
X    recycleblock(bv, bp);
X}
X
Xint undo(basicview *bv)
X{
X    int s, old_undosp, n, movetype;
X    block *bp, *nbp;
X    
X    if (bv->undosp <= 0)
X      return -1;
X    
X    n = pop(bv);
X    movetype = n % 8;
X    old_undosp = bv->undosp - 1 - (n /= 8) % 8;
X    s = n / 8;
X    bv->ko_spot = pop(bv);
X    bv->turn--;
X    bv->to_play = OTHER(bv->to_play);
X    bp = bv->block_ref[bv->block_id[s]];
X    
X    /* uncapture */
X    while (old_undosp != bv->undosp
X	   && bv->block_ref[top(bv)]->color == OTHER(bv->to_play))
X      uncapture_block(bv, bv->block_ref[pop(bv)]);
X    
X    
X    switch (movetype) {
X      case MOVEIS_PASS:
X	bv->passes--;
X	return MOVEIS_PASS;
X	
X      case MOVEIS_NEW:
X      case MOVEIS_EXTEND:
X      case MOVEIS_NEW+MOVE_CAPTURES:
X      case MOVEIS_EXTEND+MOVE_CAPTURES:
X	undo_simple(bv, s, movetype, bp);
X	break;
X      case MOVEIS_CONNECT:
X      case MOVEIS_CONNECT+MOVE_CAPTURES:
X	undo_connect(bv, s, bp, old_undosp);
X	break;
X    }
X    
X    
X    /* now update my neighbors liberties */
X    {
X	foreachneighbor(bv, s, n)
X	  if (bv->color[n] == OTHER(bv->to_play)) {
X	      nbp = bv->block_ref[bv->block_id[n]];
X	      if (!setisin(nbp->libs, s)) {
X		  setadd(nbp->libs, s);
X		  ++nbp->nlibs;
X	      }
X	  }
X    } 
X    
X    return 0;
X}
SHAR_EOF
if test 9845 -ne "`wc -c < 'basics.c'`"
then
	echo shar: error transmitting "'basics.c'" '(should have been 9845 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'godefs.h'" '(2693 characters)'
if test -f 'godefs.h'
then
	echo shar: will not over-write existing file "'godefs.h'"
else
sed 's/^X//' << \SHAR_EOF > 'godefs.h'
X/*
X * godefs.h -- GO definitions
X *
X * created 7/12-90
X *
X * Tommy Thorn                       email: tthorn@daimi.aau.dk
X * Computer Science Department       I SPEAK FOR MYSELF!
X * Aarhus University 
X * DENMARK
X */
X
X#define MAX 360 /* 19^2-1 */
X#ifndef SET_MAX
X# define SET_MAX MAX+1
X# include "set.h"
X#endif
X
X/* boolean values */
X
X#define YES 1
X#define NO 0
X
X/* color values */
X
X#define EMPTY 0
X#define BLACK 1
X#define WHITE 2
X
X#define OTHER(c) (3-c)
X
X/*
X * a block is a strongly connected collection of stones of the
X * same color.
X */
X
Xtypedef struct _block {
X    int id; /* unik block number */
X    int status;
X    int color;
X    set stones, libs;
X    int nlibs;
X} block;
X
X/* block status */
X
X#define BLOCK_ACTIVE	0
X#define BLOCK_INACTIVE	1
X#define BLOCK_CAPTURED	2
X
X/*
X * for each intersection there is an index into dir giving a zero-
X * terminated list of offset. usually this is only used by
X * foreachneighbor. IMPORTANT: foreach neighbor uses the locals
X * defined by set_localvars(), see set.h
X */
X
Xextern int dir[9][5];   /* dir[dirindex[s]] gives a zero terminated list */
X
X#define foreachneighbor(bv, s, n)                                          \
X    register *_ip;                                                         \
X    for (_ip = dir[bv->dirindex[s]], n = s + *_ip; *_ip; n = s + *++_ip)   
X	
Xtypedef struct _basicview {
X    int w;                         /* board width */
X    int max;                       /* w*w-1 */
X    int turn;
X    int to_play;                   /* next to play */
X    int passes;
X    int ko_spot;
X    int dirindex[MAX];
X    int color[MAX]; 
X    int block_id[MAX];             /* which block is on this intersec. */
X    block *block_ref[MAX];         /* maps block_id to a pointer */
X    int next_free_id;
X    int undostack[MAX*4];
X    int undosp;
X} basicview;
X
X/* top of undostack is movetype + 8 * (undoinfosize-2) + 64 * move 
X * followed by old ko spot
X */
X
X/* the error return code from play, legal and movetype */
X#define ERR_OUT_OF_BOARD  -1
X#define ERR_OCCUPIED      -2
X#define ERR_KO_VIOLATION  -3
X#define ERR_SUICIDE       -4
X#define ERR_GAME_OVER     -5
X
X/* movetypes respective to a block */
X#define MOVEIS_PASS        0
X#define MOVEIS_NEW         1       /* new block */
X#define MOVEIS_EXTEND      2       /* extending a block */
X#define MOVEIS_CONNECT     3       /* connecting blocks */
X#define MOVE_CAPTURES      4       /* is added on */
X
Xvoid init(basicview *, int w);
Xint moveis(basicview *, int s);    /* < 0 bad, > 0 good */
Xint play(basicview *, int s);      /* < 0 bad (not made), > 0 good */
Xint undo(basicview *);             /* < 0 couldn't undo, undostack empty */
X
X#ifdef __TURBOC__
Xvoid *malloc(unsigned);
X#endif
SHAR_EOF
if test 2693 -ne "`wc -c < 'godefs.h'`"
then
	echo shar: error transmitting "'godefs.h'" '(should have been 2693 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'set.c'" '(1318 characters)'
if test -f 'set.c'
then
	echo shar: will not over-write existing file "'set.c'"
else
sed 's/^X//' << \SHAR_EOF > 'set.c'
X/*
X * set.c - set rutines
X *
X * A set is a bitvector containing integers in the range 0..360
X *
X * created 18/5-90
X *
X * Tommy Thorn                       email: tthorn@daimi.aau.dk
X * Computer Science Department       I SPEAK FOR MYSELF!
X * Aarhus University 
X * DENMARK
X */
X
X#include "set.h"
X
X#ifdef SET_BIT
Xunsigned set_bit[INTW] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512,
X			    1024, 2048, 4096, 8192, 16384, -32768};
X#endif
X
Xsetinit(set s)
X{
X    register i;
X    for (i = 0; i < SET_LEN; ++i)
X      s[i] = 0;
X}
X
Xsetunion(set sd, set s1, set s2)
X{
X    register i;
X    
X    for (i = 0; i < SET_LEN; ++i)
X      sd[i] = s1[i] | s2[i];
X}
X
Xsetinter(set sd, set s1, set s2)
X{
X    register i;
X    
X    for (i = 0; i < SET_LEN; ++i)
X      sd[i] = s1[i] & s2[i];
X}
X
Xsetdiff(set sd, set s1, set s2)
X{
X    register i;
X    
X    for (i = 0; i < SET_LEN; ++i)
X      sd[i] = s1[i] & ~s2[i];
X}
X
Xint setsize(set s)
X{
X    register int i, n = 0;
X    register unsigned b;
X    
X    /* This could have been n = 0; foreach(s, i) n++
X       but I've got something better ... */
X    
X    for (i = 0; i < SET_LEN; ++i)
X      if (s[i]) {
X	  b = s[i];
X	  ++n;
X	  while (b = b & (b - 1)) ++n;
X      }
X    return n;
X}
X
Xint setisempty(set s)
X{
X    register int i;
X    
X    for (i = 0; i < SET_LEN; ++i)
X      if (s[i])
X	return 0;
X    return 1;
X}
SHAR_EOF
if test 1318 -ne "`wc -c < 'set.c'`"
then
	echo shar: error transmitting "'set.c'" '(should have been 1318 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'set.h'" '(1565 characters)'
if test -f 'set.h'
then
	echo shar: will not over-write existing file "'set.h'"
else
sed 's/^X//' << \SHAR_EOF > 'set.h'
X/*
X * set.h - headerfile for set rutines
X *
X * A set is a bitvector containing integers in the range 0..360
X *
X * created 18/5-90
X *
X * Tommy Thorn                       email: tthorn@daimi.aau.dk
X * Computer Science Department       I SPEAK FOR MYSELF!
X * Aarhus University 
X * DENMARK
X */
X
X#undef MAX
X#define MAX 361
X#define SET_LEN ((MAX-1)/8/sizeof(int))+1
X#define LONGW (8*sizeof(long))
X#define SET_MASK (LONGW-1)
X
X#define SHIFT 5
X
X
Xtypedef unsigned long set[SET_LEN];
X
X#ifdef SET_BIT
Xextern unsigned long set_bit[LONGW];
X#endif
X
X#ifdef SET_BIT
X#define setadd(s, e)	s[(unsigned long)e >> SHIFT] |= set_bit[e & SET_MASK]
X#define setremove(s, e)	s[(unsigned long)e >> SHIFT] &= ~set_bit[e & SET_MASK]
X#define setisin(s, e)	(s[(unsigned long)e >> SHIFT] & set_bit[e & SET_MASK])
X#else
X#define setadd(s, e)	s[(unsigned long)e >> SHIFT] |= 1 << (e & SET_MASK)
X#define setremove(s, e)	s[(unsigned long)e >> SHIFT] &= ~(1 << (e & SET_MASK))
X#define setisin(s, e)	(s[(unsigned long)e >> SHIFT] & (1 << (e & SET_MASK)))
X#endif
X
X/* must be in the beginning of a block */
X
X#define setforeach(s, i)                                                   \
X    register _j; register unsigned long _b;                                \
X    for (_j = 0; _j < SET_LEN; ++_j)					   \
X      if (s[_j])							   \
X        for (_b = s[_j], i = _j * LONGW; _b; _b >>= 1, ++i)                \
X	  if (_b & 1)
X
Xint setinit(set s);
Xint setunion(set sd, set s1, set s2);
Xint setinter(set sd, set s1, set s2);
Xint setdiff(set sd, set s1, set s2);
Xint setsize(set s);
Xint setisempty(set s);
X
SHAR_EOF
if test 1565 -ne "`wc -c < 'set.h'`"
then
	echo shar: error transmitting "'set.h'" '(should have been 1565 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'test.c'" '(3562 characters)'
if test -f 'test.c'
then
	echo shar: will not over-write existing file "'test.c'"
else
sed 's/^X//' << \SHAR_EOF > 'test.c'
X/*
X * Test BASICS -- basic view of the go board
X *
X * created 14/12-90
X *
X * Tommy Thorn                       email: tthorn@daimi.aau.dk
X * Computer Science Department       I SPEAK FOR MYSELF!
X * Aarhus University 
X * DENMARK
X */
X
X#include <stdio.h>
X#include "godefs.h"
X#include "curses.h"
X#include <signal.h>
X
X#ifdef __TURBOC__
Xunsigned _stklen = 20000;
X#endif
X
X/* initialize the curses package and display mode */
Xsetup()
X{
X    initscr();
X    crmode();
X    noecho();
X    move(3,7);
X}
X
X/* draws the current game board
X   the debug package might set the high bit on some stones to indicate
X   that those spots should be highlighted
X*/
X
Xdraw(basicview *bv)
X{
X    register int i,j;
X    int x,y;
X    getyx(stdscr,y,x);
X    mvaddstr(2,5,"|---------------------------------------|");
X    for (i=0; i<19; ++i) {
X	mvaddch(3+i,5,'|');
X	for (j=0; j<19; ++j) {
X	    addch(' ');
X	    switch(bv->color[j+i*19] & 0x7F) {
X	      case EMPTY:
X		addch('+');
X		break;
X	      case BLACK:
X		addch('@');
X		break;
X	      case WHITE:
X		addch('O');
X		break;
X	      default: addch('!'); break; /* ERROR! */
X	    }
X	}
X	addch(' '); addch('|');
X    }
X    mvaddstr(3+i,5,"|---------------------------------------|");
X    move(y,x);
X    refresh();
X}
X
Xstatic int lastpos = 0;
X
X/* relative cursor motion on a flat board with bounds-checking */
Xrup(int w, int o)
X{
X    lastpos = (lastpos + o + w*w) % (w*w);
X    move(lastpos/w+3, (lastpos%w)*2+7);
X    refresh();
X}
X
Xint fetchmove(basicview *bv)
X{
X    char s[80];
X    
X    int done = 0;
X    while (!done)
X      switch (getch()) {
X	case 'j': rup(bv->w,  bv->w); break;
X	case 'k': rup(bv->w, -bv->w); break;
X	case 'h': rup(bv->w, -1); break;
X	case 'l': rup(bv->w,  1); break;
X	  /*	  case 'y': rup(bv->w, -bv->w-1); break;
X		  case 'u': rup(bv->w, -bv->w+1); break;
X		  case 'b': rup(bv->w,  bv->w-1); break;
X		  case 'n': rup(bv->w,  bv->w+1); break;
X		  */
X	case 'p': return -1;
X	case 'L'&0x1F: draw(bv); break;
X	case '.':
X	case ' ': done=1; break;
X	case 'q': return -2;
X	case 'b': return -3;
X	case 'i':
X	  if (bv->block_id[lastpos] != -1) {
X	      sprintf(s, "Block #%d Libs %d",
X		      bv->block_id[lastpos],
X		      bv->block_ref[bv->block_id[lastpos]]->nlibs);
X	      comment(s);
X	  }
X	  break;
X	default: beep(); break;
X      }
X    return lastpos;
X}
X
Xbeep()
X{
X    write(2, "\007", 1);
X}
X
X/* the opposite of setup() */
Xcleanup()
X{
X    move(23,0);
X    refresh();
X    endwin();
X}
X
Xsigexit()
X{
X    cleanup();
X    exit(1);
X}
X
Xmain()
X{
X    basicview BasicView, *bv = &BasicView;
X    
X    init(bv, 19);
X    setup();
X    draw(bv);
X    do {
X        doturn(bv);
X    } while(bv->passes != 2);
X    cleanup();
X}
X
Xdoturn(basicview *bv)
X{
X    int i;
X    comment("Turn %d:%s to play.",bv->turn,bv->to_play==BLACK?"BLACK":"WHITE");
X    while (1) {
X	i  = fetchmove(bv);
X	if (i == -2)
X	  bv->passes = 2;
X	else if (i == -3)
X	  undo(bv);
X	else {
X	    switch (moveis(bv, i)) {
X	      case ERR_OUT_OF_BOARD:
X		comment("Out of board (??)");
X		continue;
X	      case ERR_OCCUPIED:
X		comment("That spot is occupied");
X		continue;
X	      case ERR_KO_VIOLATION:
X		comment("Oh no there is a ko");
X		continue;
X	      case ERR_SUICIDE:
X		comment("Do you want to commit suicide?");
X		continue;
X	      case ERR_GAME_OVER:
X		comment("The game is over");
X		continue;
X	    }
X	    play(bv, i);
X	}
X	break;
X    }
X    draw(bv);
X}
X
X/* display a message near the bottom of the screen */
Xcomment(fmt,a,b,c,d,e,f)
X     char *fmt;
X     int a,b,c,d,e,f;
X{
X    int x,y;
X    getyx(stdscr,y,x);
X    move(23,15);
X    printw(fmt,a,b,c,d,e,f);
X    clrtoeol();
X    move(y,x);
X    refresh();
X}
SHAR_EOF
if test 3562 -ne "`wc -c < 'test.c'`"
then
	echo shar: error transmitting "'test.c'" '(should have been 3562 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0

--
Tommy Thorn                       email: tthorn@daimi.aau.dk
Computer Science Department       I SPEAK FOR MYSELF!
Aarhus University 
DENMARK


