home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-06-20 | 88.7 KB | 2,408 lines |
- 18-Jun-88 14:51:33-MDT,93237;000000000000
- Return-Path: <u-lchoqu%sunset@cs.utah.edu>
- Received: from cs.utah.edu by SIMTEL20.ARPA with TCP; Sat, 18 Jun 88 14:49:36 MDT
- Received: by cs.utah.edu (5.54/utah-2.0-cs)
- id AA22730; Sat, 18 Jun 88 14:49:32 MDT
- Received: by sunset.utah.edu (5.54/utah-2.0-leaf)
- id AA24857; Sat, 18 Jun 88 14:49:25 MDT
- Date: Sat, 18 Jun 88 14:49:25 MDT
- From: u-lchoqu%sunset@cs.utah.edu (Lee Choquette)
- Message-Id: <8806182049.AA24857@sunset.utah.edu>
- To: rthum@simtel20.arpa
- Subject: go.c.shar
-
- #! /bin/sh
- #
- # This is a shell archive. Save this into a file, edit it
- # and delete all lines above this comment. Then give this
- # file to sh by executing the command "sh file". The files
- # will be extracted into the current directory owned by
- # you with default permissions.
- #
- # The files contained herein are:
- #
- # 17 README
- # 12 go.c
- # 5 gofile.c
- # 10 gomain.c
- # 11 gomoves.c
- # 1 gomoves.h
- # 28 goprocs.c
- # 3 goprocs.h
- #
- echo 'Extracting README'
- if test -f README; then echo 'shar: will not overwrite README'; else
- sed 's/^X//' << '________This_Is_The_END________' > README
- XThis directory contains 1 document file and 7 files of source code for
- Xthe Go program posted 24 Feb 86, as promised. The programs were written
- Xfor Megamax C.
- X
- XThe core programs (in goprocs.c) have been through extensive testing,
- Xeverything else is in the process of conceptualization and development.
- X
- XThese programs are provided as a simple skeleton go program. Some code was
- Xremoved from the 'bestmoves' routine for this posting, to keep it simple.
- XSince code was removed, the following programs will not play as well as the
- Xexecutable version that was posted 24 Feb 1986.
- X
- XThis is not to be taken as an example of great coding technique - this is a
- Xfirst effort.
- X
- XKnown problems: The last time that I adjusted the weights in the
- Xmove selection routine (bestmoves) to play a better game against Nemesis I
- Xmade a mistake, so presently the executable version of the program will
- Xattempt an illegal move in some situations.
- X
- XAlso, I do not have access to a Mac XL, so I can not insure that the
- Xprogram runs properly there. As far as I know, the code follows the
- Xtoolbox interface conventions - nothing tricky there.
- X
- XWill this kind posting create more interest in Programs that play go?
- XOr will it set the programming of go back ten years by undermining support
- Xfor more professional efforts? Other?
- X
- XThanks to those of you who have responded with problems and suggestions!
- XCorrespondence and gratuities of any kind (verbal, code, financial, ...)
- Xcan be sent to:
- X
- XLynn Beus & Jim Logan
- XBYU Computer Science
- X232 TMCB
- XProvo, Utah 84602
- X
- Xor email: loganj@byuvax.bitnet
- X
- XPhone: (801) 378-3617
- X___________________________________________________________________________
- X
- X26 February 1986
- X
- XGo Utility Programs Description
- X
- XDeveloper: James R. Logan Jr. (BYU)
- XAdvisor: Dr. Lynn H. Beus (BYU)
- XBYU Computer Science
- X232 TMCB
- XProvo, Utah 84602
- Xemail address: loganj@byuvax.bitnet
- Xphone: (801) 378-3617
- X
- XThis document describes procedures, variables, arrays, and structures
- Xthat maintain a 1-dimensional representation of the Oriental game of Go.
- XThe present implementation of the programs, for lack of development
- Xtime, has the following arbitrary limitations:
- X
- X - No count is maintained of the number of eyes that each army has
- X (an easy thing to implement?), but only the number of individual
- X liberties that each army has.
- X
- X - No count is maintained of the number of neighboring armies to an
- X army.
- X
- X - The maximum allowable board size is 19 by 19 lines, or 361 positions.
- X
- X - The maximum allowable number of armies is 362 (compile time
- X parameter).
- X
- X - The game board must be square.
- X
- XThe 'who' variable in the game structure (game.who) designates black's
- Xor white's turn to play, and is an input parameter to some of these
- Xprocedures. The user is required to set this variable to White or Black
- Xbefore each procedure call.
- X
- XAll 1-dimensional representations of the Go board are defined in C as
- Xchar [361]. The Go Programs consist of twelve main procedures. The
- Xcalling conventions and purpose of these twelve procedures is described
- Xas follows:
- X
- X-initialize
- XInitializes the specified game structure by clearing all stones from the
- Xvarious arrays and building the initial blank army. Initialize must be
- Xcalled for a newly allocated game structure. For example, to initialize
- Xa 5 by 5 game board the initialize routine should be called as follows:
- X
- X g->width = 5;
- X initialize(g);
- X where g is a game structure pointer previously allocated by the user.
- X
- X-addastone
- XAdds a stone of color g.who to the specified 1-dimensional position and
- Xupdates the specified game structure. If the specified position is
- Xalready occupied then no update occurs. For example, to add a stone to
- Xposition 9 the addastone routine should be called as follows:
- X
- X addastone(g,9);
- X where g is an initialized game structure pointer.
- X
- X-removeastone
- XRemoves the specified stone and updates the specified game structure.
- XIf the specified stone represents an unoccupied position then no update
- Xoccurs. For example, to remove a stone at position 9 the removeastone
- Xroutine should be called as follows:
- X
- X removeastone(g,9,status);
- X where g is a game structure pointer,
- X and status is a movestatus (mstatus) structure.
- X
- X-getneighbors
- XReturns the number of immediate non-blank neighbors to a position, and
- Xreturns the 1 dimensional board position of each non-blank neighbor in a
- Xstone[1..4] array sorted by army number. For example, to get all
- Xneighboring positions (white, black, and blank) to position 9 the
- Xgetneighbors routine should be called as follows:
- X
- X getneighbors(g,n,9);
- X where g is a game structure pointer,
- X and n is a nabor structure pointer.
- X
- XThe next two procedures will not normally be needed by the users program,
- Xbut they are included for completeness.
- X
- X-capture
- XRemoves the army represented by the specified stone and updates the
- Xappropriate data structures. If the specified stone represents a blank
- Xarmy then no update occurs. For example, to remove an army that
- Xcontains a stone at position 9 the capture routine should be called as
- Xfollows:
- X
- X capture(g,9);
- X where g is a game structure pointer.
- X
- X-uncapture
- XUncaptures the army represented by the specified position and updates
- Xthe appropriate data structures. If the specified postion is occupied
- Xthen no update occurs. For example, to uncapture an army that contains
- Xa stone at position 9 the uncapture routine should be called as follows:
- X
- X uncapture(g,9,color);
- X where g is a game structure pointer,
- X and color is the color of the army (White or Black) being uncaptured.
- X_________________________________________________________________________
- X
- XThe following routines print the values of game structures upside down
- Xfrom the game board displayed on the screen.
- X
- X-moveboard
- XThis procedure prints the game.board array on the screen, for debugging.
- XFor example, to display game.board call moveboard as follows:
- X
- X moveboard(g);
- X where g is a game structure pointer.
- X
- X-armyboard
- XThis procedure prints the game.armymen array on the screen, for debugging.
- XFor example, to display game.armymen call armyboard as follows:
- X
- X armyboard(g);
- X where g is a game structure pointer.
- X
- X-armyinfo
- XThis procedure prints the game.army structure on the screen, for debugging.
- XFor example, to display game.army call armyinfo as follows:
- X
- X armyinfo(g);
- X where g is a game structure pointer.
- X
- Xlinkinfo
- XThis procedure prints the game.armylnk array on the screen, for debugging.
- XFor example, to display game.armylnk call linkinfo as follows:
- X
- X linkinfo(g);
- X where g is a game structure pointer.
- X
- X-pictinfo
- XThis procedure prints the game.cpict and game.opict arrays on the screen
- Xin hex, for debugging. For example, to display game.cpict and
- Xgame.opict call pictinfo as follows:
- X
- X pictinfo(g);
- X where g is a game structure pointer.
- X
- X-neighborinfo
- XThis procedure prints the game.neibrd array on the screen in hex, for
- Xdebugging. For example, to display game.neibrd call neighborinfo as
- Xfollows:
- X
- X neighborinfo(g);
- X where g is a game structure pointer.
- X________________________________________________________________________
- X
- XThese Go Programs use one main data structure to represent a game of Go,
- Xas follows:
- X
- Xgame - This structure contains some basic structures for the analysis of
- Xa single board position.
- X
- XThe Game structure contains the following variables, arrays, and
- Xstructures:
- X
- Xwho - This variable represents the color of the player making the
- Xcurrent move, and is set to White for one player, and Black for the
- Xother player. This variable must be set before a call to the addastone
- Xprocedure, because the addastone procedure uses this variable to set the
- Xboard array value (stone color).
- X
- Xavail - This variable is the next available army number in a linked list
- Xof army numbers. Do not change this variable.
- X
- Xmaxstone - This variable indicates the 1-dimensional size of the game
- Xboard being used. It is computed by the initialize procedure. Do not
- Xchange this variable.
- X
- Xwidth - This variable indicates the width of the game board. The
- Xinitialize procedure sets this variable to the maximum column number.
- XDo not change this variable.
- X
- Xmovecount - This variable indicates the number of stones played in the
- Xgame structure. This variable is cleared by the initialize procedure,
- Xincremented by calls to the addastone procedure, and decremented by
- Xcalls to the removeastone and capture procedures. Do not change this
- Xvariable.
- X
- Xmovestatus - This structure contains ko information and capture
- Xinformation based on the last stone played on the board. This structure
- Xshould be pushed on the stack during tree searches, because it is used
- Xto remove a play and restore the previous game position. Do not change
- Xthe variables in this structure.
- X
- XThe ko position (movestatus.kospot) is set by the capture procedure to
- Xthe 1-dimensional position of a 1-man army that was just captured. If
- Xno army was captured by the last move then this variable is set to -1.
- XAlso if the size of the captured army is greater than one then this
- Xvariable is set to -1. The addastone procedure sets this variable to
- X-1, but the addastone procedure calls the capture procedure if a capture
- Xis made by a move.
- X
- XThe capture information (movestatus.captures) is set by the addastone
- Xprocedure to reflect which of the four possible armies surrounding the
- Xnew stone was captured. This variable type (movestatus.captures) is bit
- Xencoded, where the least significant 4 bits determine which direction an
- Xarmy was captured in (so that the army can be restored if the capturing
- Xstone is removed).
- X
- Xdebug - This BITSET variable represents various debug states. Bits 0-5
- Xare used in these programs, and bits 6-15 are available for any use.
- X
- Xboard - This 1-dimensional array contains the position of black and
- Xwhite stones on the Go Board. One player's stones are represented by a
- Xvalue of White, and opponent stones are represented by a value of Black.
- XDo not change this array.
- X
- Xrowbrd - This 1-dimensional array corresponds exactly to the board array
- Xabove and indicates the 2-dimensional row number of each position. Do
- Xnot change this array.
- X
- Xcolbrd - This 1-dimensional array corresponds exactly to the board array
- Xabove and indicates the 2-dimensional column number of each position.
- XDo not change this array.
- X
- Xarmymen - This 1-dimensional array corresponds exactly to the Board
- Xstructure (above). Each board position in this array contains the army
- Xnumber of the army that occupies this position. The army number is used
- Xto access information about the army.
- X
- Xarmylnk - This 1-dimensional array corresponds exactly to the Board
- Xstructure (above). Each position in this array contains the number of
- Xthe next man in the army. This array is used for processing every man
- Xin an army, which occurs when an army is being built, when an army is
- Xcaptured, and when army neighbors need to be counted.
- X
- Xwhitepats - This 1-dimensional array corresponds exactly to the Board
- Xstructure (above). Each position in this array contains a binary
- Xrepresentation of the white stones in a 5 by 5 diamond shape around the
- Xposition. This binary picture can be used to test for a specific
- Xgeometic arrangement of the white player's stones around a given
- Xposition. See the diagram below.
- X
- Xblackpats - This 1-dimensional array corresponds exactly to the Board
- Xstructure (above). Each position in this array contains a binary
- Xrepresentation of the black stones in a 5 by 5 diamond shape around the
- Xposition. This binary picture can be used to test for a specific
- Xgeometic arrangement of the black player's stones around a given
- Xposition. See the diagram below.
- X
- XWhitepats and blackpats (above) contain 32 bit values that represent
- Xstone patterns in a 5 by 5 diamond shape, centered around a given board
- Xposition (S). Only 29 bits are actually used, 25 bits for a 5 by 5
- Xsquare and 4 bits at the center of each outside edge. The area covered
- Xand bits represented are as follows:
- X
- X Shape Bit numbers
- X
- X * 28
- X * * * * * 5 4 3 2 1
- X * * * * * 10 9 8 7 6
- X* * * S * * * 27 15 14 13 12 11 26
- X * * * * * 20 19 18 17 16
- X * * * * * 25 24 23 22 21
- X * 29
- X
- Xneibrd - This 1-dimensional array corresponds exactly to the Board
- Xstructure (above). The purpose of this array is to test a 1-dimensional
- Xposition and determine if the position is on one edge or corner of the
- Xboard. This array can also be used to test for a position on row 1, 2,
- X3, or 4 from any side of the board.
- X
- Xarmy - This structure is indexed by army number, and contains
- Xinformation about each army such as size, color, first (first army man's
- Xboard position), last (last army man's board position), fp (forward
- Xpointer to the next army), bp (backward pointer to the previous army),
- Xlib (liberties), friend (number of bordering friendly stones), enemy
- X(number of bordering enemy stones), armies (number of neighboring
- Xnon-blank armies -- not implemented yet), and rollcall (scratchpad
- Xvariable). For blank armies the number of liberties is not used, the
- Xnumber of friendly stones is the number of neighboring white stones, and
- Xthe number of enemy stones is the number of neighboring black stones.
- XFor non-blank armies the number of friendly stones is not used.
- X________________________________________________________________________
- X
- XThe following additional data structures are used by these programs and
- Xalso made available for convenience, as follows:
- X
- Xneighbors - This structure contains the output of the getneighbors
- Xprocedure: the number and position of non-blank neighbors to a
- Xspecified 1-dimensional position, sorted by army number (which makes it
- Xeasier to tell if different neighbors are in the same army).
- X
- Xneighborcount - This array is used with the game.neibrd array to quickly
- Xdetermine how many valid neighboring positions there are to a given
- Xstone position. This array, neighborcount[0..15], merely translates a
- Xbinary number from 0 to 15 into the number of bits that are set in that
- Xbinary number.
- X
- Xmstatus - This structure contains ko information and capture information
- Xbased on the last stone played on the board.
- X
- XThe ko position (movestatus.kospot) is set by the capture procedure to
- Xthe 1-dimensional position of a 1-man army that was just captured. If
- Xno army was captured by the last move then this variable is set to -1.
- XAlso if the size of the captured army is greater than one then this
- Xvariable is set to -1. The addastone procedure sets this variable to
- X-1, but the addastone procedure calls the capture procedure if a capture
- Xis made by a move.
- X
- XThe capture information (movestatus.captures) is set by the addastone
- Xprocedure to reflect which of the four possible armies surrounding the
- Xnew stone was captured. This variable is bit encoded.
- X_________________________________________________________________________
- X
- XTo use all of the above utility programs and data structures the
- Xfollowing C code is necessary:
- X
- X#include <goprocs.h>
- X#include <gomoves.h>
- X
- XThe following C code creates/allocates a game structure called g at
- Xcompile time (this is the responsibility of the user):
- X
- X game g;
- X
- XBlack, White, and Blank are C parameters that define the only valid
- Xstates of a board position. Black and White define the only valid
- Xstone colors and player designations. The following C code changes
- Xthe designated player in the game structure pointed to by g:
- X
- X g->who = otherside[g->who];
- X
- XThe following C code will walk through all armies (black,white, and blank),
- Xgiven a game structure pointer (g):
- X
- X int armynumber;
- X armynumber = mygame.army[mygame.avail].bp; /* back pointer is first army */
- X while (armynumber > 0) {
- X if (mygame.army[armynumber].size > 0) {
- X (* code to process each army goes here *)
- X }
- X armynumber = mygame.army[armynumber].bp;
- X }
- X
- XThe following C code will walk through an army, given a game structure
- Xpointer (g) and the position of any stone in the army (s):
- X
- X int stone;
- X stone = g->army[g->armymen[s]].first; /* first man in army */
- X while (stone >= 0) {
- X (* code to process each army man goes here *)
- X stone = g->armylnk[stone]; /* next man in army */
- X }
- X
- XThe following C code will obtain the positions of the neighbors to a
- Xgiven stone position (s), given a game structure pointer (g) and visit
- Xeach of the non-blank neighboring positions in order of their army number:
- X
- X neighbors nabor; int n;
- X getneighbors(g,&nabor,s); /* get the neighbors */
- X for (n = 0; n < nabor.neis; n++) { /* go through neighbors */
- X if (g->board[s] != Blank) {
- X (* code to process non-blank neighbors to stone s goes here *)
- X } }
- ________This_Is_The_END________
- if test `wc -l < README` -ne 404; then
- echo 'shar: README was damaged during transit'
- echo ' (should have been 404 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'Extracting go.c'
- if test -f go.c; then echo 'shar: will not overwrite go.c'; else
- sed 's/^X//' << '________This_Is_The_END________' > go.c
- X/* File go.c
- X Developer: James R. Logan Jr. (BYU), Advisor: Dr. Lynn H. Beus (BYU)
- X email address: loganj@byuvax.bitnet
- X (801) 378-3617
- X
- X These routines and the routines in gomoves.c determine the strategy of
- X the go program. This code is not machine dependent.
- X*/
- X
- X#include <qd.h>
- X#include <pack.h>
- X#include <win.h>
- X#include <dialog.h>
- X#include <stdio.h>
- X#include <goprocs.h>
- X#include <gomoves.h>
- X
- Xextern char coltable[19];
- Xextern int activeplayer,blinkstone,looking,play,otherside[2];
- Xextern game mygame;
- Xextern int addastone();
- Xextern initialize(),removeastone(),capture(),uncapture(),
- X getneighbors(),allarmies(),linkarmies(),buildarmies(),
- X armymerge(),topicture(),frompicture(),moveboard(),
- X armyboard(),linkinfo(),armyinfo(),pictinfo(),neighborinfo();
- X
- Xoverlay "gamestuff"
- X
- X#define allyweight 4
- X#define blankweight 1
- X#define enemyweight 2
- X#define libertiesweight 1
- X#define squareweight 4
- X
- X#define edgevalue 1
- X#define openvalue 2 /* ordinary unoccupied square, not on edge */
- X#define cornervalue 10
- X#define connectvalue 3
- X#define midneivalue 6
- X#define midrowvalue 8
- X#define row3value 4
- X#define row5value 3
- X
- Xpattern greypat = {0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92};
- X
- Xrect screenrect;
- Xwindowrecord merecord,myrecord,drecord;
- Xwindowptr mewindow,mywindow = {0L},dummywindow;
- X
- Xsons root[maxlevs];
- X
- Xmstatus status;
- X
- Xint
- X init[maxstones],value[maxstones], /* initial position values */
- X color,stone,nextmove,passcount,
- X searchdepth = {1},searchwidth = {1},work;
- X
- Xinitgame(g) game *g; {
- Xint i,j,brdsze;
- Xchar dummyscreen[20000];
- X if (mywindow == 0L) {
- X/* calculate the size of the window for the game board, and display */
- X brdsze = 16 + 8 * (g->width - 1);
- X setrect(&screenrect,351-brdsze,181-brdsze,351+brdsze,181+brdsze);
- X mywindow = newwindow(&myrecord, &screenrect, "", 1, 2,
- X (long)-1, 0, (long)0);
- X dummywindow = newwindow(&drecord, &screenrect, "", 0, 2,
- X (long)-1, 1, (long)0);
- X drecord.port.portbits.baseaddr = &dummyscreen;
- X setrect(&screenrect, 0, 21, 188, 340);
- X mewindow = newwindow(&merecord, &screenrect, "", 1, 2,
- X (long)-1, 0, (long)0);
- X } else {
- X disposewindow(mywindow);
- X brdsze = 16 + 8 * (g->width - 1);
- X setrect(&screenrect,351-brdsze,181-brdsze,351+brdsze,181+brdsze);
- X mywindow = newwindow(&myrecord, &screenrect, "Go", 1, 3,
- X (long)-1, 0, (long)0);
- X }
- X if ((g->debug & 1) != 0) { printf("Initgame: \n"); }
- X setport(mywindow);
- X textmode(srcxor);
- X backpat(&greypat);
- X setorigin(-12,0);
- X brdsze = 4 + 16 * g->width;
- X setrect(&screenrect,0,0,400,brdsze);
- X eraserect(&screenrect);
- X setport(mewindow);
- X textsize(9);
- X initialize(g); /* initialize the game structure for the go procs */
- X g->who = Black; /* first move is black's */
- X passcount = 0; /* number of consecutive passes in the game */
- X blinkstone = -1; /* indicate no stone to blink yet */
- X/* set the initial value of each position, first the whole board */
- X for (i = firstelement; i < g->maxstone; i++) { init[i] = openvalue; }
- X/* set the initial value of the edges of the board */
- X j = firstelement;
- X for (i = firstelement; i < g->width; i++) {
- X init[j] = edgevalue; init[j+g->width-1] = edgevalue;
- X init[i] = edgevalue; init[g->maxstone-g->width+i] = edgevalue;
- X j = j + g->width;
- X }
- X/* Set the initial value for row 3 all around the board */
- X if (g->width >= 7) {
- X j = 2*g->width+3;
- X for (i = firstelement; i < g->width-6; i++) {
- X init[j] = row3value; init[g->maxstone-j-1] = row3value;
- X j = j + 1; }
- X j = 3*g->width+2;
- X for (i = firstelement; i < g->width-6; i++) {
- X init[j] = row3value; init[j+g->width-5] = row3value;
- X j = j + g->width; }
- X }
- X/* Set the value for the middle of row 3 around the edge of the board */
- X if (g->width >= 9) {
- X j = (2*g->width)+(g->width/2);
- X init[j] = midrowvalue;
- X init[g->maxstone-1-j] = midrowvalue;
- X j = ((g->width / 2) * g->width) + 2;
- X init[j] = midrowvalue;
- X init[g->maxstone-1-j] = midrowvalue;
- X }
- X/* Set the initial value for row 5 all around the board, but not in 5 corner */
- X if (g->width >= 11) {
- X j = 4*g->width+5;
- X for (i = firstelement; i < g->width-10; i++) {
- X init[j] = row5value; init[g->maxstone-j-1] = row5value;
- X j = j + 1; }
- X j = 5*g->width+4;
- X for (i = firstelement; i < g->width-10; i++) {
- X init[j] = row5value; init[j+g->width-9] = row5value;
- X j = j + g->width; }
- X }
- X/* Set the initial value for 3 rows in from each corner */
- X if (g->width >= 5) {
- X init[2*g->width+2] = cornervalue;
- X init[3*g->width-3] = cornervalue;
- X init[g->maxstone-2*g->width-3] = cornervalue;
- X init[g->maxstone-3*g->width+2] = cornervalue;
- X }
- X/* Set the initial value for 2 jump neighbors from mid row 3 */
- X if (g->width == 19) {
- X init[44] = midneivalue; init[50] = midneivalue;
- X init[116] = midneivalue; init[130] = midneivalue;
- X init[230] = midneivalue; init[244] = midneivalue;
- X init[310] = midneivalue; init[316] = midneivalue;
- X }
- X init[0] = 0; init[g->width-1] = 0;
- X init[g->maxstone-g->width] = 0; init[g->maxstone-1] = 0;
- X if ((g->debug & 1) != 0) { printf("Initgame end.\n"); }
- X}
- X
- Xint moves(g) game *g; {
- X/* This procedure receives control when the computer needs to make a move,
- X and returns the 1-dimensional position selected by the computer.
- X If g->who == White a move is computed for the computer, else a move is
- X computed for the opponent. A legal move is always added to the board */
- Xint s; sons *sonsp;
- X alphabeta(); /* look ahead for the best move */
- X if (nextmove >= 0) {
- X s = addastone(g,nextmove); /* add this move to the game board */
- X if (s >= 0) {
- X if (g->who == White) printf(" White to %c,%d\n",
- X coltable[g->colbrd[s]],g->rowbrd[s]);
- X else printf(" Black to %c,%d\n",
- X coltable[g->colbrd[s]],g->rowbrd[s]);
- X }
- X passcount = 0;
- X } else {
- X s = -1;
- X if (activeplayer == 1) passcount = passcount + 1;
- X if (g->who == White) printf(" White passes\n");
- X else printf(" Black passes\n");
- X }
- X g->who = otherside[g->who];
- X if ((activeplayer == 1) && (passcount >= 2)) {
- X play = 0;
- X printf(" Play stopped after two passes!\n");
- X }
- X return s;
- X}
- X
- Xalphabeta() {
- X/* This procedure is the top level of the alpha-beta cutoff look ahead
- X procedure. Alpha and beta are initialized here. */
- Xint a,b,dummy; int sonsp;
- X looking = 1; /* indicate look ahead in progress */
- X nextmove = -1; /* default next move is a pass */
- X sonsp = 0; /* point to root of tree */
- X a = -9999; b = 9999; /* alpha-beta initialization */
- X dummy = abcontrol (sonsp,a,b,mygame.who);
- X looking = 0;
- X}
- X
- Xint abcontrol (tr,a,b,wh) int tr,a,b,wh; {
- X/* This procedure performs the actual alpha-beta search. Inputs are
- X tree level, Alpha, Beta, and who's move it is. The present
- X implementation does not dynamically allocate the tree. */
- Xint ta,tb,ev,junk,r,c,v;
- X if (tr >= searchdepth) { /* last level of tree? */
- X ev = eval(searchdepth); /* yes, compute the position value */
- X if ((mygame.debug & 0xF) != 0) {
- X printf("\nabcontrol - level, node, value: %d %d %d\n",
- X searchdepth-1,root[searchdepth-1].nodepnt-1,ev);
- X }
- X return (ev); /* return the best position value */
- X } else if (wh == mygame.who) { /* for maximizing level */
- X bestmoves(&mygame,tr); /* fill in the best moves */
- X while ((root[tr].nodepnt < root[tr].nodecnt) && (a < b)) {
- X junk = addastone(&mygame,root[tr].nodes[root[tr].nodepnt].s);
- X root[tr].status = mygame.movestatus;
- X root[tr].nodepnt = root[tr].nodepnt + 1;
- X ta = abcontrol (tr + 1, a, b, otherside[wh]);
- X if (ta > a) {
- X a = ta; /* new alpha value */
- X if (tr <= 0) { nextmove = root[tr].nodes[root[tr].nodepnt-1].s; }
- X }
- X removeastone(&mygame,root[tr].nodes[root[tr].nodepnt-1].s,root[tr].status)
- X;
- X }
- X return (a);
- X } else { /* for minimizing level */
- X bestmoves(&mygame,tr); /* fill in the best moves */
- X while ((root[tr].nodepnt < root[tr].nodecnt) && (a < b)) {
- X mygame.who = wh; /* change sides */
- X junk = addastone(&mygame,root[tr].nodes[root[tr].nodepnt].s);
- X root[tr].status = mygame.movestatus;
- X mygame.who = otherside[mygame.who]; /* change sides back */
- X root[tr].nodepnt = root[tr].nodepnt + 1;
- X tb = abcontrol (tr + 1, a, b, otherside[wh]);
- X if (tb < b) { b = tb; } /* new beta value */
- X removeastone(&mygame,root[tr].nodes[root[tr].nodepnt-1].s,root[tr].status)
- X;
- X }
- X return (b);
- X }
- X}
- X
- Xint eval(sonsp) int sonsp; {
- X/* This procedure evaluates the worth of look ahead moves during the alpha
- X beta search - not a well defined process. Need a lot of work here!
- X The game structure fields don't seem to represent enough higher level
- X (human) abstractions to play a good game yet. The evaluation here
- X is based on the number of armies, eyes, and total number of liberties
- X for both sides. Variables beginning with an 'a' are ally values, 'e' are
- X enemy values. */
- Xint n,v,pv,allies,enemies,alibs,elibs,wh,tb;
- X if ((mygame.debug & 1) != 0) { printf("eval: \n"); }
- X pv = 0; allies = 0; enemies = 0; alibs = 0; elibs = 0;
- X wh = 1;
- X for (tb = 0; tb < sonsp; tb++) { /* traverse the tree */
- X pv = pv + root[tb].nodes[root[tb].nodepnt-1].pv * wh;
- X tb = tb + 1;
- X wh = -wh; /* switch players at each level of the tree */
- X }
- X n = mygame.army[mygame.avail].bp; /* visit each army */
- X while (n > 0) {
- X if (mygame.army[n].size > 0) {
- X if (mygame.army[n].color == Blank) { /* blank army is an eye? */
- X if (mygame.army[n].enemy <= 0) {
- X if (mygame.who == White) allies = allies + 1; /* ally eyes */
- X else enemies = enemies + 1; /* enemy eyes */
- X } else if (mygame.army[n].friend <= 0) {
- X if (mygame.who == White) enemies = enemies + 1;/* ally eyes */
- X else allies = allies + 1; /* enemy eyes */
- X }
- X } else if (mygame.army[n].color == mygame.who) {
- X alibs = alibs + mygame.army[n].lib;
- X } else {
- X elibs = elibs + mygame.army[n].lib;
- X }
- X }
- X n = mygame.army[n].bp;
- X }
- X v = allies * allyweight - enemies * enemyweight +
- X libertiesweight * alibs - libertiesweight * elibs +
- X pv * squareweight;
- X if ((mygame.debug & 1) != 0) { printf("eval.\n"); }
- X return (v);
- X}
- X
- Xboardsize(g) game *g; {
- X/* This procedure handles the game initialization dialog */
- Xint the_item,item_type,value;
- Xhandle item_handle;
- Xrect drect,item_box;
- Xchar item_text[64];
- Xdialogptr mydialog;
- X setrect(&drect,-16,28,440,200);
- X copybits(&mywindow->portbits,&dummywindow->portbits,
- X &drect,&drect,srccopy,(long)0);
- X mydialog = getnewdialog(9507,(long) 0,(long)-1);
- X getditem(mydialog,3,&item_type,&item_handle,&item_box);
- X sprintf(item_text,"%d",g->width);
- X setitext(item_handle,item_text);
- X getditem(mydialog,4,&item_type,&item_handle,&item_box);
- X sprintf(item_text,"%d",searchwidth);
- X setitext(item_handle,item_text);
- X getditem(mydialog,5,&item_type,&item_handle,&item_box);
- X sprintf(item_text,"%d",searchdepth);
- X setitext(item_handle,item_text);
- X do {
- X modaldialog((long) 0,&the_item);
- X if (the_item == 1) {
- X getditem(mydialog,3,&item_type,&item_handle,&item_box);
- X getitext(item_handle,&item_text);
- X sscanf(item_text,"%d",&value);
- X if ((value > 2) && (value < 20)) g->width = value;
- X getditem(mydialog,4,&item_type,&item_handle,&item_box);
- X getitext(item_handle,&item_text);
- X sscanf(item_text,"%d",&value);
- X if ((value > 0) && (value <= maxsons)) searchwidth = value;
- X getditem(mydialog,5,&item_type,&item_handle,&item_box);
- X getitext(item_handle,&item_text);
- X sscanf(item_text,"%d",&value);
- X if ((value > 0) && (value <= maxlevs)) searchdepth = value;
- X }
- X } while ((the_item != 1) && (the_item != 2));
- X closedialog(mydialog);
- X copybits(&dummywindow->portbits,&mywindow->portbits,
- X &drect,&drect,srccopy,(long)0);
- X if (the_item == 1) initgame(g);
- X}
- X
- Xvalueboard(g) game *g; {
- Xint i,s;
- X s = 0;
- X while (s < g->maxstone) {
- X for (i = firstelement; i < g->width; i++) { printf("%3d",value[s]); s = s +
- X1; }
- X printf("\n");
- X} }
- ________This_Is_The_END________
- if test `wc -l < go.c` -ne 333; then
- echo 'shar: go.c was damaged during transit'
- echo ' (should have been 333 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'Extracting gofile.c'
- if test -f gofile.c; then echo 'shar: will not overwrite gofile.c'; else
- sed 's/^X//' << '________This_Is_The_END________' > gofile.c
- X/* File gofile.c
- X Developer: James R. Logan Jr. (BYU), Advisor: Dr. Lynn H. Beus (BYU)
- X email address: loganj@byuvax.bitnet
- X (801) 378-3617
- X
- X These routines handle the disk I/O for the go program's log file and
- X replay feature. This code is not machine dependent.
- X*/
- X
- X#include <qd.h>
- X#include <pack.h>
- X#include <win.h>
- X#include <dialog.h>
- X#include <stdio.h>
- X#include <goprocs.h>
- X
- Xoverlay "filestuff"
- X
- Xchar prompt[2] = {' ','\0'},origname[2] = {' ','\0'},filename[32];
- Xrect drect;
- X
- Xextern FILE *fp,*gp;
- Xextern char coltable[19];
- Xextern int play;
- Xextern game mygame;
- Xextern windowptr mywindow, dummywindow;
- Xextern int addastone(),moves();
- X
- Xcreatefile() {
- X/* This procedure opens a log file for the game in progess */
- Xsfreply reply; point pt; char volname[30]; int i,j,tint; long tlong;
- X setrect(&drect,-16,28,440,200);
- X copybits(&mywindow->portbits,&dummywindow->portbits,&drect,&drect,srccopy,(lon
- Xg)0);
- X setpt(&pt, 190, 75);
- X sfputfile(&pt, &prompt[0], &origname[0], NULL, &reply);
- X copybits(&dummywindow->portbits,&mywindow->portbits,&drect,&drect,srccopy,(lon
- Xg)0);
- X if (reply.good) {
- X getvinfo(reply.vrefnum, volname, &tint, &tlong);
- X strcpy(filename, volname); strcat(filename, ":"); strcat(filename, reply.fna
- Xme);
- X if (fp != NULL) fclose(fp);
- X fp = fopen(filename,"w");
- X} }
- X
- Xreplay() {
- X/* This procedure opens a saved game and replays the game. The game file
- X can be modified by an editor to change the sequence of play. The first
- X letter of each line determines the function. Using log files is the
- X fastest way to set up a specific board position. */
- Xchar col,color,tline[128];
- Xint c,i,row,s,size,tint; long tlong;
- Xsfreply reply; point pt; char volname[30];
- X if (gp == 0) {
- X setrect(&drect,-16,28,440,200);
- X copybits(&mywindow->portbits,&dummywindow->portbits,
- X &drect,&drect,srccopy,(long)0);
- X setpt(&pt, 186, 75);
- X sfgetfile(&pt, NULL, NULL, 1, "TEXT", NULL, &reply);
- X copybits(&dummywindow->portbits,&mywindow->portbits,
- X &drect,&drect,srccopy,(long)0);
- X if (reply.good) {
- X getvinfo(reply.vrefnum, volname, &tint, &tlong);
- X strcpy(filename, volname); strcat(filename, ":"); strcat(filename, reply.f
- Xname);
- X gp = fopen(filename,"r");
- X }
- X } else {
- X c = NULL;
- X for (i=0; (i<128) && ((c = getc(gp)) != EOF) && (c != 10); i++) tline[i] = c
- X;
- X tline[i] = 0;
- X switch (tline[0]) {
- X case 'a': case 'A':
- X sscanf(tline,"%*s %c %c,%d",&color,&col,&row);
- X s = position(col,row);
- X if ((color == 'w') || (color == 'W')) mygame.who = White;
- X else if ((color == 'b') || (color == 'B')) mygame.who = Black;
- X if (s >= 0) s = addastone(&mygame,s);
- X break;
- X case 'b': case 'B': mygame.who = Black; break;
- X case 'c': case 'C':
- X sscanf(tline,"%*s %c,%d",&col,&row);
- X s = position(col,row);
- X if (s >= 0) capture(&mygame,s);
- X break;
- X case 'i': case 'I':
- X sscanf(tline,"%*s %d",&size);
- X if ((size > 2) && (size < 20)) {
- X mygame.width = size;
- X initgame(&mygame);
- X }
- X break;
- X case 'm': case 'M': s = moves(&mygame); break;
- X case 'r': case 'R':
- X sscanf(tline,"%*s %c,%d",&col,&row);
- X s = position(col,row);
- X if (s >= 0) removeastone(&mygame,s,mygame.movestatus);
- X break;
- X case 'u': case 'U':
- X sscanf(tline,"%*s %c,%d,%c",&col,&row,&color);
- X s = position(col,row);
- X if (s >= 0) {
- X if ((color == 'w') || (color == 'W')) uncapture(&mygame,s,White);
- X else if ((color == 'b') || (color == 'B')) uncapture(&mygame,s,Black);
- X
- X }
- X break;
- X case 'w': case 'W': mygame.who = White; break;
- X default:
- X }
- X if (c == EOF) { fclose(gp); gp = NULL; play = 0; }
- X} }
- X
- Xint position(col,row) char col; int row; {
- X/* This procedure converts from a 2-dimensional position used by the world,
- X to the 1-dimensional position used in the game structures */
- Xint i,s;
- X s = -1;
- X if ((row > 0) && (row <= mygame.width)) {
- X for (i = 0; i < mygame.width; i++) if (col == coltable[i]) s = i;
- X if ((s >= 0) && (s < mygame.width)) s = (row - 1) * mygame.width + s;
- X }
- X return(s);
- X}
- ________This_Is_The_END________
- if test `wc -l < gofile.c` -ne 126; then
- echo 'shar: gofile.c was damaged during transit'
- echo ' (should have been 126 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'Extracting gomain.c'
- if test -f gomain.c; then echo 'shar: will not overwrite gomain.c'; else
- sed 's/^X//' << '________This_Is_The_END________' > gomain.c
- X/* File gomain.c
- X Developer: James R. Logan Jr. (BYU), Advisor: Dr. Lynn H. Beus (BYU)
- X email address: loganj@byuvax.bitnet
- X (801) 378-3617
- X
- X This procedure provides the interface between the Mac and the operator.
- X This code is machine dependent.
- X*/
- X
- X#include <qd.h>
- X#include <win.h>
- X#include <menu.h>
- X#include <event.h>
- X#include <te.h>
- X#include <stdio.h>
- X#include <goprocs.h>
- X
- X#define lastmenu 5
- X#define applemenu 1
- X#define filemenu 256
- X#define gamemenu 257
- X#define playermenu 258
- X#define displaymenu 259
- X
- XFILE *fp,*gp;
- Xwindowptr whichwindow;
- Xmenuhandle mymenus[lastmenu+1];
- Xboolean doneflag,temp;
- Xeventrecord myevent;
- Xlong blinktime;
- Xint code,refnum;
- Xint themenu,theitem,
- X activeplayer,blinkstate,blinkcolor,blinkstone,drawnumber,
- X lookahead,play,playfile,stonestate;
- X
- Xgame mygame;
- X
- Xextern initgame();
- Xextern int addastone(),moves();
- Xextern char coltable[19];
- Xextern int otherside[2];
- Xextern windowptr mewindow,mywindow;
- X
- Xsetupmenus() {
- Xint i;
- Xchar appletitle[2];
- X initmenus();
- X appletitle[0] = applemark; appletitle[1] = 0;
- X mymenus[1] = newmenu(applemenu, appletitle);
- X addresmenu(mymenus[1], "DRVR");
- X mymenus[2] = newmenu(filemenu, "Directives");
- X appendmenu(mymenus[2], "Pass;Change Sides;Log to File;Play Log File;Quit");
- X mymenus[3] = newmenu(gamemenu, "Game");
- X appendmenu(mymenus[3], "Initialize;Begin or Resume;Pause");
- X mymenus[4] = newmenu(playermenu, "Players");
- X appendmenu(mymenus[4], "Computer Vs Computer;Computer Vs Human;Human Vs Human"
- X);
- X mymenus[5] = newmenu(displaymenu, "Display");
- X appendmenu(mymenus[5],
- X "Look Ahead Moves;Stone Numbers;Procedures;Stones;Stone Armies;Stone Links;S
- Xtone Patterns;Position Values;Army Info");
- X for (i=1; i<=lastmenu; i++) insertmenu(mymenus[i], 0);
- X drawmenubar();
- X drawnumber = 1;
- X checkitem(mymenus[5],2,1);
- X lookahead = 0;
- X activeplayer = 1;
- X checkitem(mymenus[4],activeplayer,1);
- X}
- X
- Xdocommand(themenu, theitem) int themenu, theitem; {
- Xchar name[256];
- Xint i;
- X switch (themenu) {
- X case applemenu:
- X getitem(mymenus[1], theitem, name);
- X refnum = opendeskacc(name);
- X break;
- X case filemenu:
- X switch (theitem) {
- X case 1: /* pass */
- X if (play == 0) {
- X if ((activeplayer == 2) || (activeplayer == 3)) {
- X mygame.who = otherside[mygame.who];
- X if (activeplayer == 2) {
- X play = 1;
- X } else {
- X if (mygame.who == White) printf(" White's turn ...\n");
- X else printf(" Black's turn ...\n");
- X }
- X }
- X }
- X break;
- X case 2: /* change sides */
- X mygame.who = otherside[mygame.who];
- X if (mygame.who == White) printf(" White's turn ...\n");
- X else printf(" Black's turn ...\n");
- X break;
- X case 3:
- X if (fp == NULL) {
- X checkitem(mymenus[2],3,1);
- X createfile();
- X } else {
- X checkitem(mymenus[2],3,0);
- X fclose(fp); fp = NULL;
- X }
- X break;
- X case 4:
- X if (gp == 0) {
- X if (activeplayer == 2) blinkoff();
- X replay();
- X if (gp != 0) {
- X checkitem(mymenus[2],4,1);
- X play = 1;
- X playfile = 1;
- X }
- X } else {
- X checkitem(mymenus[2],4,0);
- X if (gp != NULL) fclose(gp); gp = NULL;
- X play = 0;
- X playfile = 0;
- X mygame.who = otherside[mygame.who];
- X if (mygame.who == White) printf(" White's turn ...\n");
- X else printf(" Black's turn ...\n");
- X if (activeplayer == 2) blinkon();
- X }
- X break;
- X case 5:
- X if (fp != NULL) { fclose(fp); fp = NULL; }
- X if (gp != NULL) { fclose(gp); gp = NULL; }
- X doneflag = 1;
- X break;
- X }
- X break;
- X case gamemenu:
- X switch (theitem) {
- X case 1:
- X play = 0;
- X if (playfile != 0) {
- X checkitem(mymenus[2],4,0);
- X if (gp != NULL) fclose(gp); gp = NULL;
- X playfile = 0;
- X }
- X blinkoff();
- X boardsize(&mygame);
- X if (activeplayer == 1) {
- X if (mygame.who == White) printf(" White's turn ...\n");
- X else printf(" Black's turn ...\n");
- X } else if (activeplayer == 2) {
- X blinkon();
- X printf(" Your turn ...\n");
- X } else if (activeplayer == 3) printf(" Black's turn ...\n");
- X break;
- X case 2:
- X if ((playfile != 0) || (activeplayer == 1)) play = 1;
- X else if (activeplayer == 2) printf(" Your turn ...\n");
- X else if (mygame.who == White) printf(" White's turn ...\n");
- X else printf(" Black's turn ...\n");
- X break;
- X case 3: play = 0; break;
- X }
- X break;
- X case playermenu:
- X switch (theitem) {
- X case 1:
- X if (activeplayer == 2) blinkoff();
- X checkitem(mymenus[4],activeplayer,0);
- X activeplayer = 1;
- X checkitem(mymenus[4],activeplayer,1);
- X break;
- X case 2:
- X play = 0;
- X blinkstone = -1;
- X checkitem(mymenus[4],activeplayer,0);
- X activeplayer = 2;
- X checkitem(mymenus[4],activeplayer,1);
- X break;
- X case 3:
- X play = 0;
- X if (activeplayer == 2) blinkoff();
- X checkitem(mymenus[4],activeplayer,0);
- X activeplayer = 3;
- X checkitem(mymenus[4],activeplayer,1);
- X break;
- X }
- X break;
- X case displaymenu:
- X switch (theitem) {
- X case 1:
- X lookahead = 1 - lookahead;
- X checkitem(mymenus[5],1,lookahead);
- X break;
- X case 2:
- X drawnumber = 1 - drawnumber;
- X checkitem(mymenus[5],2,drawnumber);
- X break;
- X case 3:
- X if ((mygame.debug & 1) == 0) {
- X mygame.debug |= 1;
- X checkitem(mymenus[5],3,1);
- X } else {
- X mygame.debug &= ~1;
- X checkitem(mymenus[5],3,0);
- X }
- X break;
- X case 4: moveboard(&mygame); break;
- X case 5: armyboard(&mygame); break;
- X case 6: linkinfo(&mygame); break;
- X case 7: pictinfo(&mygame); break;
- X case 8: valueboard(&mygame); break;
- X case 9: armyinfo(&mygame); break;
- X } }
- X hilitemenu(0);
- X}
- X
- Xstoneon() {
- X if ((stonestate == 0) && (blinkstone >= 0))
- X drawstone(&mygame,blinkstone,blinkcolor);
- X stonestate = 1;
- X}
- X
- Xstoneoff() {
- X if ((stonestate != 0) && (blinkstone >= 0))
- X undrawstone(&mygame,blinkstone);
- X stonestate = 0;
- X}
- X
- Xblinkon() {
- X/* Turn on the blink'n blinker if no look ahead in progress. */
- X if (lookahead == 0) {
- X blinkstate = 1;
- X blinktime = tickcount();
- X} }
- X
- Xblinkoff() { blinkstate = 0; stoneon(); }
- X
- Xblink() {
- X/* This procedure does the actual blinking of the last stone played */
- Xlong now;
- X if (blinkstate != 0) {
- X now = tickcount();
- X if (now > blinktime + 20) {
- X if (stonestate != 0) stoneoff(); else stoneon();
- X blinktime = now;
- X} } }
- X
- Xmain() {
- X/* This procedure provides the interface between the Mac and the
- X operator */
- Xint i,s;
- Xextern struct qdvar { char dummy[202]; grafptr qdtheport;} qdvars;
- X#define theport (qdvars.qdtheport)
- X
- X openresfile("clock");
- X initgraf(&theport);
- X initfonts();
- X flushevents(everyevent, 0);
- X initwindows();
- X setupmenus();
- X initdialogs(0L);
- X initcursor();
- X
- X doneflag = 0; play = 0; playfile = 0; blinkstone = -1;
- X mygame.debug = 0;
- X mygame.width = 19;
- X fp = NULL; gp = NULL;
- X initgame(&mygame);
- X
- X do {
- X systemtask();
- X blink();
- X temp = getnextevent(everyevent, &myevent);
- X switch (myevent.what) {
- X case mousedown:
- X code = findwindow(&myevent.where, &whichwindow);
- X switch (code) {
- X case inmenubar:
- X docommand(menuselect(&myevent.where)); break;
- X case insyswindow:
- X systemclick(&myevent, whichwindow); break;
- X case indrag:
- X break;
- X case ingrow:
- X case incontent:
- X if ((play == 0) &&
- X ((playfile != 0) || (activeplayer == 2) || (activeplayer == 3))) {
- X if (whichwindow == mywindow) {
- X blinkoff();
- X setport(mywindow);
- X globaltolocal(&myevent.where);
- X setport(mewindow);
- X/* place a stone on the board */
- X s = (mygame.width - 1 - ((myevent.where.a.v - 2) / 16));
- X if (s < 0) s = 0;
- X if (s >= mygame.width) s = mygame.width - 1;
- X s = s * mygame.width;
- X i = (myevent.where.a.h - 2) / 16;
- X if (i < 0) i = 0;
- X if (i >= mygame.width) i = mygame.width - 1;
- X s = s + i;
- X s = addastone(&mygame,s);
- X if (s >= 0) {
- X if (mygame.who == White) printf(" White to %c,%d\n",
- X coltable[mygame.colbrd[s]],mygame.rowbrd[s]);
- X else printf(" Black to %c,%d\n",
- X coltable[mygame.colbrd[s]],mygame.rowbrd[s]);
- X if (activeplayer == 2) play = 1;
- X mygame.who = otherside[mygame.who];
- X if (mygame.who == White) printf(" White's turn ...\n");
- X else printf(" Black's turn ...\n");
- X } else {
- X if (mygame.who == White) printf(" Still White's turn ...\n");
- X else printf(" Still Black's turn ...\n");
- X }
- X }
- X }
- X break;
- X/* goaway box is on the modify window only, so save the changes to the
- X letter being modified and take down the modify window */
- X case ingoaway: break;
- X }
- X break;
- X case mouseup: break;
- X case keydown:
- X case autokey:
- X/* draw_text((char) (255 & myevent.message)); */
- X break;
- X case activateevt: break;
- X case updateevt:
- X/* setport(mywindow);
- X beginupdate(mywindow);
- X endupdate(mywindow);*/
- X break;
- X }
- X if (doneflag == 0) {
- X if (gp == NULL) {
- X if (playfile != 0) {
- X playfile = 0;
- X checkitem(mymenus[2],4,0);
- X }
- X if (((activeplayer == 1) || (activeplayer == 2)) && (play != 0)) {
- X blinkcolor = mygame.who;
- X blinkstone = moves(&mygame);
- X if (mygame.who == White) printf(" White's turn ...\n");
- X else printf(" Black's turn ...\n");
- X if (activeplayer == 2) {
- X play = 0;
- X blinkon();
- X } }
- X } else if (play != 0) replay();
- X }
- X } while (doneflag == 0);
- X}
- ________This_Is_The_END________
- if test `wc -l < gomain.c` -ne 353; then
- echo 'shar: gomain.c was damaged during transit'
- echo ' (should have been 353 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'Extracting gomoves.c'
- if test -f gomoves.c; then echo 'shar: will not overwrite gomoves.c'; else
- sed 's/^X//' << '________This_Is_The_END________' > gomoves.c
- X/* File gomoves.c
- X Developer: James R. Logan Jr. (BYU), Advisor: Dr. Lynn H. Beus (BYU)
- X email address: loganj@byuvax.bitnet
- X (801) 378-3617
- X
- X This routine determines the best n moves available when a move is
- X being selected by the computer. This code is not machine dependent.
- X*/
- X
- X#include <goprocs.h>
- X#include <gomoves.h>
- X
- X#define maxsons 5
- X#define maxlevs 5 /* must be odd, maximizing level for best odds */
- X
- X#define allyweight 4
- X#define blankweight 1
- X#define enemyweight 2
- X#define libertiesweight 1
- X#define squareweight 4
- X
- X/* The following 32 bit values represent patterns in a 5 by 5 diamond shape,
- X centered around a given board position (s). Only 29 bits are actually
- X used, 25 bits for a 5 by 5 square and 4 bits at the center of each
- X outside edge. The area covered and bits represented are as follows:
- X
- X * 28
- X * * * * * 5 4 3 2 1
- X * * * * * 10 9 8 7 6
- X* * * S * * * 27 15 14 13 12 11 26
- X * * * * * 20 19 18 17 16
- X * * * * * 25 24 23 22 21
- X * 29
- X*/
- X#define square3 0x739C0L
- X#define square5 0x0E8C62EL
- X#define diamond5 0x477DC4L
- X#define circle7 0x1F100011L
- X
- X#define firstmoves 17 /* number of moves before middle game */
- X
- X#define attackvalue 14
- X#define circle7value 2
- X#define edgevalue 1
- X#define edgecutvalue 10
- X#define edgejoinvalue 16
- X#define openvalue 2 /* ordinary unoccupied square, not on edge */
- X#define capturevalue 24
- X#define cornervalue 10
- X#define connectvalue 3
- X#define cutvalue 3
- X#define hitarivalue 18
- X#define invadevalue 20 /* must be 4 less than capture value */
- X#define midneivalue 6
- X
- X#define midrowvalue 8
- X#define protvalue 24
- X#define retreatsize 18
- X#define row3value 4
- X#define row5value 3
- X#define square5value 1
- X#define runtoedgevalue 12
- X#define territoryvalue 4
- X
- Xextern sons root[maxlevs];
- Xextern int
- X otherside[2],
- X init[maxstones],value[maxstones], /* initial position values */
- X searchdepth,searchwidth;
- X
- Xbestmoves(g,sonsp) game *g; int sonsp; {
- X/* This procedure determines the best n moves available using a point
- X scheme with weights for different patterns and situations. This
- X routine does not explicitly check the validity of each move (bad
- X moves are possible if the weights are not properly set. */
- Xchar *enmcount,*fricount;
- Xint a1,a2,blankfris,blankenms,frilibs,lastus,lastthem,
- X ha,pa,snapstone,snaplibs,i,n,s,s1,us,them,
- X captsize,protsize,totallibs,hitarisize,hitarisave,neiarms,neienms,node;
- Xlong fripats,enmpats,neipats;
- Xneighbors nabor,nextnabor;
- X/* First initialize all the best moves to pass */
- X if ((g->debug & 1) != 0) { printf("bestmoves: \n"); }
- X root[sonsp].nodecnt = 0; root[sonsp].nodepnt = 0;
- X for (node = firstelement; node < searchwidth; node++) {
- X root[sonsp].nodes[node].pv = 0;
- X root[sonsp].nodes[node].s = -1; /* default is to pass */
- X }
- X/* Evaluate each square of the board and assign a value to it */
- X for (i = firstelement; i < g->maxstone; i++) {
- X value[i] = 0; /* default is not blank, so no value */
- X if ((g->board[i] == Blank) && (i != g->movestatus.kospot)) {
- X neipats = g->neibrd[i];
- X a1 = g->armymen[i]; /* blank army number */
- X if (g->who == White) {
- X fricount = &g->whitecount[0]; enmcount = &g->blackcount[0];
- X fripats = g->whitepats[i]; enmpats = g->blackpats[i];
- X blankfris = g->army[a1].friend; blankenms = g->army[a1].enemy;
- X } else {
- X fricount = &g->blackcount[0]; enmcount = &g->whitecount[0];
- X fripats = g->blackpats[i]; enmpats = g->whitepats[i];
- X blankfris = g->army[a1].enemy; blankenms = g->army[a1].friend;
- X }
- X getneighbors(g,&nabor,i); /* get the neighbors */
- X if ((g->army[a1].size > g->maxstone-4) ||
- X ((blankfris > 0) && (blankenms > 0))) {
- X if ((init[i] > openvalue) &&
- X (((fripats & square3) != 0) || ((enmpats & square3) != 0)) ) {
- X value[i] = openvalue;
- X } else {
- X value[i] = init[i]; /* default value */
- X }
- X }
- X/* territory value, more territory value for empty diamonds
- X some code was removed here too */
- X if (((fripats & diamond5) == 0) &&
- X ((enmpats & diamond5) == 0) &&
- X ((neipats & 0x0F0) == 0x0F0)) {
- X value[i] = value[i] + territoryvalue;
- X } else {
- X us = 0; them = 0; captsize = 0; protsize = 0;
- X lastus = -1; lastthem = -1; totallibs = g->army[a1].size - 1;
- X frilibs = 0; hitarisize = 0; hitarisave = 0;
- X neiarms = 0; neienms = 0; ha = -1; pa = -1;
- X for (n = firstelement; n < nabor.neis; n++) { /* count new army neighbor
- Xs */
- X s = nabor.stone[n]; /* neighbors row & column */
- X a2 = g->armymen[s]; /* neighbor army number */
- X if (g->board[s] == Blank) {
- X frilibs = frilibs + 1;
- X } else {
- X if (g->army[a2].color == g->who) {
- X frilibs = frilibs + g->army[a2].lib - 1;
- X totallibs = totallibs + g->army[a2].lib - 1;
- X }
- X if (g->army[a2].lib == 1) {
- X if (g->army[a2].color == g->who) {
- X protsize = protsize + g->army[a2].size;
- X pa = a2;
- X } else {
- X captsize = captsize + g->army[a2].size;
- X }
- X/* Check for hitari ...
- X If the enemy can be hitari'd add in the points, if we can be hitari'd
- X add in the points if we can protect against hitari without using up
- X our eyes and if the blank army has more of our stones as neighbors */
- X } else if (g->army[a2].lib == 2) {
- X if (g->army[a2].color == otherside[g->who]) {
- X hitarisize = hitarisize + g->army[a2].size;
- X } else if ((g->army[a2].color == g->who) &&
- X (g->army[a1].enemy > 0) && (blankfris > 1)) {
- X hitarisave = hitarisave + g->army[a2].size;
- X ha = a2;
- X }
- X }
- X/* Don't count neighbors in the same amry more than once in neiarms,
- X and don't count armies in trouble */
- X if (g->board[s] == g->who) {
- X us = us + 1;
- X if (((lastus < 0) || (a2 != lastus)) &&
- X (a2 != ha)) {
- X neiarms = neiarms + 1;
- X lastus = a2;
- X }
- X } else {
- X them = them + 1;
- X if ((lastthem < 0) || (a2 != lastthem)) {
- X neienms = neienms + 1;
- X lastthem = a2;
- X }
- X }
- X }
- X }
- X/* This is the place! I cut lots of strategic code from here. If you want
- X to improve the ability of this program to play go, this is the place to
- X do it. */
- X
- X
- X/* lower the value of a square controlled */
- X if (((neipats & 0xF00) != 0xF00) && /* row 3 test */
- X ((neipats & 0x0F0) == 0x0F0) &&
- X (them > 0) && ((fripats & diamond5) == 0)) value[i] = 0;
- X if ((us > 2) && (them <= 0)) { value[i] = 0; }
- X if ((us > 1) && (neiarms < us)) { value[i] = 0; }
- X if ((them > 2) && (us <= 0)) { value[i] = 0; }
- X/* lower the value of a square that can be hitari'd on the next move */
- X if ((us <= 0) && (them >= nabor.neis-2)) {
- X value[i] = (value[i] / 2) - 1;
- X }
- X/* increase the value of a position that protects us from hitari, unless
- X that position is already controlled by us */
- X if ((hitarisave > 0) && (nabor.neis > 3) && (frilibs > 1) &&
- X ((us < 3) || (them > 0))) {
- X value[i] = value[i] + hitarisave + retreatsize + neiarms - us;
- X }
- X/* increase the value of a square that hitari's the enemy */
- X if (hitarisize > 0) {
- X if (frilibs > 1) {
- X value[i] = value[i] + hitarisize - us;
- X if (nabor.neis > 3) {
- X value[i] = value[i] + hitarivalue;
- X }
- X } else if ((snaplibs > 0) && (snaplibs < 3)) {
- X value[i] = value[i] + hitarisize + capturevalue +
- X hitarivalue + neiarms + snaplibs;
- X } }
- X/* protect if we pick up at least 3 liberties, or 2 liberties without
- X having to move on the edge of the board and without having to move
- X into our eyes */
- X if ((protsize > 0) && (blankfris > 1) &&
- X ((frilibs > 2) || ((frilibs > 1) && (nabor.neis > 3)))) {
- X value[i] = value[i] + protsize + protvalue - us;
- X }
- X/* don't move to the edge unless someone else is there */
- X if (((fripats & square3) == 0) && (nabor.neis < 4)) { value[i] = 0; }
- X/* lower the value of a square we are next to if the enemy is not near */
- X if (((enmpats & square3) == 0) && ((fripats & square3) != 0)) {
- X if (nabor.neis > 3) value[i] = value[i] / 2; else value[i] = 0;
- X }
- X/* Increase the value of moves that extend influence into unoccupied territory *
- X/
- X if ((g->movecount >= firstmoves) &&
- X ((fripats & square3) == 0) && ((enmpats & square3) == 0)) {
- X if (((fripats & square5) != 0) && ((enmpats & square5) != 0)) {
- X value[i] = value[i] + square5value;
- X } else if (((fripats & square5) == 0) && ((enmpats & square5) == 0)) {
- X if (((fripats & circle7) != 0) && ((enmpats & circle7) != 0))
- X value[i] = value[i] + circle7value;
- X } }
- X/* don't move to a square surrounded by enemy unless we have a capture */
- X if (captsize > 0) {
- X value[i] = value[i] + capturevalue + captsize;
- X } else if (them >= nabor.neis) {
- X value[i] = 0;
- X }
- X }
- X/* There are three situations we move into: 1 is during the first
- X moves of the game when a large blank army occupies most of the
- X board; 2 is into a blank army that borders on computer and enemy
- X stones; 3 is into an eye if the value high enough to indicate a
- X capture or protection required, if not a KO situation. */
- X if (value[i] > 0) {
- X if ((i != g->movestatus.kospot) &&
- X ((g->army[a1].size > g->maxstone-4) ||
- X ((blankfris > 0) && (blankenms > 0)) ||
- X (value[i] > invadevalue))) {
- X s = i; node = firstelement;
- X while ((node < searchwidth) && (s >= 0)) {
- X if (value[s] > root[sonsp].nodes[node].pv) {
- X root[sonsp].nodes[node].pv = value[s];
- X s1 = root[sonsp].nodes[node].s; /* save the old value */
- X root[sonsp].nodes[node].s = s; /* use the better value */
- X s = s1; /* continue with old value */
- X }
- X node = node + 1;
- X }
- X root[sonsp].nodecnt = root[sonsp].nodecnt + 1;
- X }
- X }
- X }
- X }
- X if (root[sonsp].nodecnt > searchwidth) { root[sonsp].nodecnt = searchwidth; }
- X if ((g->debug & 1) != 0) { printf("bestmoves end.\n"); }
- X}
- ________This_Is_The_END________
- if test `wc -l < gomoves.c` -ne 264; then
- echo 'shar: gomoves.c was damaged during transit'
- echo ' (should have been 264 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'Extracting gomoves.h'
- if test -f gomoves.h; then echo 'shar: will not overwrite gomoves.h'; else
- sed 's/^X//' << '________This_Is_The_END________' > gomoves.h
- X/* File gomoves.h
- X Developer: James R. Logan Jr. (BYU), Advisor: Dr. Lynn H. Beus (BYU)
- X email address: loganj@byuvax.bitnet
- X (801) 378-3617
- X*/
- X
- X#define maxsons 5 /* maximum depth of alpha-beta tree */
- X#define maxlevs 5 /* must be odd, maximizing level for best odds? */
- X
- Xtypedef struct {
- X int s,pv; /* alpha beta stone position and board value */
- X} nodestruct;
- X
- Xtypedef struct { /* children of node in alpha-beta tree */
- X int nodepnt,nodecnt;
- X mstatus status; /* board status resulting from stone */
- X nodestruct nodes[maxsons];
- X} sons;
- ________This_Is_The_END________
- if test `wc -l < gomoves.h` -ne 18; then
- echo 'shar: gomoves.h was damaged during transit'
- echo ' (should have been 18 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'Extracting goprocs.c'
- if test -f goprocs.c; then echo 'shar: will not overwrite goprocs.c'; else
- sed 's/^X//' << '________This_Is_The_END________' > goprocs.c
- X/* File goprocs.c
- X Developer: James R. Logan Jr. (BYU), Advisor: Dr. Lynn H. Beus (BYU)
- X BYU Computer Science
- X 232 TMCB
- X Provo, Utah 84602
- X email address: loganj@byuvax.bitnet
- X (801) 378-3617
- X
- X These procedures are go playing utility procedures that can be used by
- X a go playing progam to do all the house keeping during a game of go.
- X These procedures a based on a 1-dimensional representation of the game.
- X This code is not machine dependent, except for the drawing routines at
- X the end.
- X*/
- X
- X#include <qd.h>
- X#include <win.h>
- X#include <stdio.h>
- X#include <goprocs.h>
- X
- X#define patwidth 5
- X
- Xextern FILE *fp;
- Xextern int drawnumber,lookahead,otherside[2];
- Xextern windowptr mewindow,mywindow;
- X
- Xoverlay "gostuff"
- X
- Xchar coltable[19] = {'A','B','C','D','E','F','G','H','J','K','L','M','N','O','P'
- X,'Q','R','S','T'};
- Xint picset[29] =
- X {0x50,0x41,0x40,0x42,0x60,
- X 0x14,0x05,0x04,0x06,0x24,
- X 0x10,0x01,0x00,0x02,0x20,
- X 0x18,0x09,0x08,0x0A,0x28,
- X 0x90,0x81,0x80,0x82,0xA0,
- X 0x100,0x200,0x400,0x800};
- Xpattern whitepat = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
- Xpattern blackpat = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
- X
- Xint looking,stonenumber,otherside[2],
- X wrkbrd[maxstones];
- X
- Xinitialize (g) game *g; {
- X/* This procedure initializes the game structure supplied by the caller */
- Xint i,j,r1,c1,w1,w2,w3,w4,w5,w6,w7,w8;
- X if ((g->debug & 1) != 0) printf("initializing, board size %d.\n",g->width);
- X/* initialize other side table */
- X otherside[White] = Black; otherside[Black] = White;
- X/* initialize game parameters */
- X g->movecount = 0;
- X g->deadwhite = 0; g->deadblack = 0;
- X w1 = g->width; w2 = w1 + w1; w3 = w2 + w1; w4 = w3 + w1;
- X w5 = w4 + w1; w6 = w5 + w1; w7 = w6 + 1; w8 = w7 + 1;
- X g->maxstone = w1 * w1; g->movestatus.kospot = -1;
- X/* initialize the neighbor board */
- X for (i = firstelement; i < g->maxstone; i++) g->neibrd[i] = 0x0FFFFFFFFL;
- X j = firstelement;
- X for (i = firstelement; i < g->width; i++) {
- X g->neibrd[j] = g->neibrd[j] & 0x0EEEEEEEEL;
- X g->neibrd[j+w1-1] = g->neibrd[j+w1-1] & 0x0DDDDDDDDL;
- X g->neibrd[i] = g->neibrd[i] & 0x0BBBBBBBBL;
- X g->neibrd[g->maxstone-w1+i] = g->neibrd[g->maxstone-w1+i] & 0x077777777L;
- X if (w1 > 1) {
- X g->neibrd[j+1] = g->neibrd[j+1] & 0x0EEEEEEEFL;
- X g->neibrd[j+w1-2] = g->neibrd[j+w1-2] & 0x0DDDDDDDFL;
- X g->neibrd[i+w1] = g->neibrd[i+w1] & 0x0BBBBBBBFL;
- X g->neibrd[g->maxstone-w2+i] = g->neibrd[g->maxstone-w2+i] & 0x07777777FL;
- X }
- X if (w1 > 2) {
- X g->neibrd[j+2] = g->neibrd[j+2] & 0x0EEEEEEFFL;
- X g->neibrd[j+w1-3] = g->neibrd[j+w1-3] & 0x0DDDDDDFFL;
- X g->neibrd[i+w2] = g->neibrd[i+w2] & 0x0BBBBBBFFL;
- X g->neibrd[g->maxstone-w3+i] = g->neibrd[g->maxstone-w3+i] & 0x0777777FFL;
- X }
- X if (w1 > 3) {
- X g->neibrd[j+3] = g->neibrd[j+3] & 0x0EEEEEFFFL;
- X g->neibrd[j+w1-4] = g->neibrd[j+w1-4] & 0x0DDDDDFFFL;
- X g->neibrd[i+w3] = g->neibrd[i+w3] & 0x0BBBBBFFFL;
- X g->neibrd[g->maxstone-w4+i] = g->neibrd[g->maxstone-w4+i] & 0x077777FFFL;
- X }
- X if (w1 > 4) {
- X g->neibrd[j+4] = g->neibrd[j+4] & 0x0EEEEFFFFL;
- X g->neibrd[j+w1-5] = g->neibrd[j+w1-5] & 0x0DDDDFFFFL;
- X g->neibrd[i+w4] = g->neibrd[i+w4] & 0x0BBBBFFFFL;
- X g->neibrd[g->maxstone-w5+i] = g->neibrd[g->maxstone-w5+i] & 0x07777FFFFL;
- X }
- X if (w1 > 5) {
- X g->neibrd[j+5] = g->neibrd[j+5] & 0x0EEEFFFFFL;
- X g->neibrd[j+w1-6] = g->neibrd[j+w1-6] & 0x0DDDFFFFFL;
- X g->neibrd[i+w5] = g->neibrd[i+w5] & 0x0BBBFFFFFL;
- X g->neibrd[g->maxstone-w6+i] = g->neibrd[g->maxstone-w6+i] & 0x0777FFFFFL;
- X }
- X if (w1 > 6) {
- X g->neibrd[j+6] = g->neibrd[j+6] & 0x0EEFFFFFFL;
- X g->neibrd[j+w1-7] = g->neibrd[j+w1-7] & 0x0DDFFFFFFL;
- X g->neibrd[i+w6] = g->neibrd[i+w6] & 0x0BBFFFFFFL;
- X g->neibrd[g->maxstone-w7+i] = g->neibrd[g->maxstone-w7+i] & 0x077FFFFFFL;
- X }
- X if (w1 > 7) {
- X g->neibrd[j+7] = g->neibrd[j+7] & 0x0EFFFFFFFL;
- X g->neibrd[j+w1-8] = g->neibrd[j+w1-8] & 0x0DFFFFFFFL;
- X g->neibrd[i+w7] = g->neibrd[i+w7] & 0x0BFFFFFFFL;
- X g->neibrd[g->maxstone-w8+i] = g->neibrd[g->maxstone-w8+i] & 0x07FFFFFFFL;
- X }
- X j = j + g->width;
- X }
- X/* initialize the row and column arrays */
- X i = 0;
- X r1 = 1;
- X while (i < g->maxstone) {
- X for (c1 = 0; c1 < g->width; c1++)
- X { g->rowbrd[i] = r1; g->colbrd[i] = c1; i = i + 1; }
- X r1 = r1 + 1;
- X }
- X for (i = firstelement; i < g->maxstone; i++) {
- X g->board[i] = Blank; g->whitepats[i] = 0; g->blackpats[i] = 0;
- X g->whitecount[i] = 0; g->blackcount[i] = 0;
- X }
- X allarmies(g); /* Create the armies */
- X drawboard(g); /* display the game board */
- X looking = 0; /* indicate not in look ahead now */
- X stonenumber = 0;
- X if ((g->debug & 1) != 0) printf("initialize end.\n");
- X}
- X
- Xint addastone(g,newstone) game *g; int newstone; {
- X/* Clear the blank army for rebuilding, update any neighboring enemy
- X armies directly, and do nothing for neighboring friendly armies.
- X Friendly armies are merged and updated by linkarmies at the end. */
- Xint a1,a2,first,playedstone,n,s; neighbors nabor; mstatus oldstatus;
- X playedstone = -1;
- X a2 = -1;
- X if ((newstone >= 0) && (newstone < g->maxstone) &&
- X (newstone != g->movestatus.kospot) && (g->board[newstone] == Blank)) {
- X g->movecount = g->movecount + 1;
- X if (looking == 0) stonenumber = stonenumber + 1;
- X oldstatus = g->movestatus; /* save the old status */
- X g->board[newstone] = g->who;
- X drawstone(g,newstone,g->who);
- X g->movestatus.kospot = -1; /* clear the ko position */
- X g->movestatus.captures = 0; /* clear captures */
- X topicture(g,newstone);
- X a1 = g->armymen[newstone]; /* old blank army number */
- X first = g->army[a1].first; /* create link list of armies to relink */
- X getneighbors(g,&nabor,newstone);
- X a2 = -1;
- X for (n = firstelement; n < nabor.neis; n++) {
- X s = nabor.stone[n];
- X if (g->board[s] != Blank) {
- X a1 = g->armymen[s];
- X if ((a1 != a2) && (g->army[a1].color == otherside[g->who])) {
- X g->army[a1].enemy = g->army[a1].enemy + 1;
- X g->army[a1].lib = g->army[a1].lib - 1;
- X if (g->army[a1].lib <= 0) {
- X capture(g,g->army[a1].first);
- X g->movestatus.captures = g->movestatus.captures | nabor.direction[n]
- X;
- X }
- X }
- X a2 = a1;
- X } }
- X linkarmies(g,first);
- X/* If the added stone was illegal for lack of liberties then remove it */
- X if (g->army[g->armymen[newstone]].lib <= 0) {
- X if (g->who == White) printf(" Bad add by white at %c,%d\n",
- X coltable[g->colbrd[newstone]],g->rowbrd[newstone]);
- X else printf(" Bad add by black at %c,%d\n",
- X coltable[g->colbrd[newstone]],g->rowbrd[newstone]);
- X removeastone(g,newstone,g->movestatus);
- X g->movestatus = oldstatus;
- X if (looking == 0) stonenumber = stonenumber - 1;
- X } else {
- X/* If the added stone merged into another army then there is no ko spot */
- X a1 = g->armymen[newstone]; /* old blank army number */
- X if (g->army[a1].size > 1) g->movestatus.kospot = -1;
- X if (looking == 0) {
- X playedstone = newstone;
- X if (fp != NULL) {
- X if (g->who == White) fprintf(fp,"add w %c,%d\n",
- X coltable[g->colbrd[newstone]],g->rowbrd[newstone]);
- X else fprintf(fp,"add b %c,%d\n",
- X coltable[g->colbrd[newstone]],g->rowbrd[newstone]);
- X } } }
- X } else {
- X if (g->who == White) printf(" Bad add by white at %c,%d\n",
- X coltable[g->colbrd[newstone]],g->rowbrd[newstone]);
- X else printf(" Bad add by black at %c,%d\n",
- X coltable[g->colbrd[newstone]],g->rowbrd[newstone]);
- X }
- X return playedstone;
- X}
- X
- Xremoveastone(g,newstone,status) game *g; int newstone; mstatus status; {
- X/* Clear the blank army for rebuilding, update any neighboring enemy
- X armies directly, and do nothing for neighboring friendly armies.
- X Friendly armies are merged and updated by linkarmies at the end. */
- Xint a1,a2,first,n,s,color,wh; neighbors nabor;
- X if ((g->debug & 1) != 0) printf("removeastone at: %d\n",newstone);
- X if ((newstone >= 0) && (newstone < g->maxstone) &&
- X (g->board[newstone] != Blank)) {
- X g->movecount = g->movecount - 1;
- X g->movestatus = status; /* set the new board status */
- X wh = g->board[newstone]; /* save the old color */
- X color = otherside[wh];
- X frompicture(g,newstone); /* remove stone from picture */
- X g->board[newstone] = Blank;/* remove the stone */
- X if (wh == White) g->deadwhite = g->deadwhite + 1;
- X else g->deadblack = g->deadblack + 1;
- X undrawstone(g,newstone);
- X a1 = g->armymen[newstone]; /* old army number */
- X first = g->army[a1].first; /* first man in army to be relinked */
- X getneighbors(g,&nabor,newstone);
- X a2 = 0;
- X for (n = firstelement; n < nabor.neis; n++) { /* for neighbors */
- X a1 = g->armymen[nabor.stone[n]];
- X if ((g->army[a1].color == Blank) &&
- X ((nabor.direction[n] & g->movestatus.captures) != 0)) {
- X uncapture(g,nabor.stone[n],color);
- X g->army[a1].lib = 1; /* set 1 liberty for the removed stone */
- X } else if ((a1 != a2) && (g->army[a1].color == otherside[wh])) {
- X g->army[a1].enemy = g->army[a1].enemy - 1;
- X g->army[a1].lib = g->army[a1].lib + 1;
- X }
- X a2 = a1;
- X }
- X linkarmies(g,first);
- X } else {
- X if (g->who == White) printf(" Bad remove by white at %c,%d\n",
- X coltable[g->colbrd[newstone]],g->rowbrd[newstone]);
- X else printf(" Bad remove by black at %c,%d\n",
- X coltable[g->colbrd[newstone]],g->rowbrd[newstone]);
- X }
- X if ((g->debug & 1) != 0) printf("removeastone, end.\n");
- X}
- X
- Xcapture(g,s) game *g; int s; {
- X/* Call this routine to remove an army that has been captured. The
- X army remains intact, just changes to a blank army. Neighboring
- X enemy armies have their liberties updated by buildarmies. */
- Xint a1,a2,s1,n,wh; neighbors nabor;
- X if ((g->debug & 1) != 0) printf("capture:\n");
- X if ((s >= 0) && (s < g->maxstone)) {
- X a1 = g->armymen[s]; /* get the army number */
- X if (g->army[a1].color != Blank) {
- X if (g->army[a1].size == 1) {
- X g->movestatus.kospot = g->army[a1].first;
- X } else {
- X g->movestatus.kospot = -1;
- X }
- X g->movecount = g->movecount - g->army[a1].size;
- X wh = g->army[a1].color; /* save the army color */
- X if (wh == White) g->deadwhite = g->deadwhite + g->army[a1].size;
- X else g->deadblack = g->deadblack + g->army[a1].size;
- X g->army[a1].color = Blank; /* change army color to blank */
- X g->army[a1].size = 0; /* causes army to be rebuilt by buildarmies */
- X s1 = g->army[a1].first; /* first man in army */
- X while (s1 >= 0) {
- X frompicture(g,s1); /* take out of picture */
- X undrawstone(g,s1);
- X g->board[s1] = Blank; /* change stone color to blank */
- X/* clear the size in neighboring enemy armies so they will be rebuilt */
- X getneighbors(g,&nabor,s1);
- X for (n = firstelement; n < nabor.neis; n++) { /* for neighbors */
- X a2 = g->armymen[nabor.stone[n]];
- X if (a2 > 0) {
- X if (g->army[a2].color == otherside[wh]) {
- X g->army[a2].size = 0; }
- X }
- X }
- X/* get the next man in the army */
- X s1 = g->armylnk[s1]; /* row link to next army man */
- X }
- X buildarmies(g);
- X } else {
- X printf(" Bad capture at: %c,%d\n",coltable[g->colbrd[s]],g->rowbrd[s]);
- X }
- X } else {
- X printf(" Bad capture at: %c,%d\n",coltable[g->colbrd[s]],g->rowbrd[s]);
- X }
- X if ((g->debug & 1) != 0) printf("capture, end.\n");
- X}
- X
- Xuncapture(g,s,wh) game *g; int s,wh; {
- X/* Call this routine to uncapture an army that had been captured. The
- X army remains intact, just changes to a non-blank army. Neighboring
- X enemy armies have their liberties updated by buildarmies. */
- Xint a1,a2,s1,n; neighbors nabor;
- X if ((g->debug & 1) != 0) printf("uncapture:\n");
- X if ((s >= 0) && (s < g->maxstone)) {
- X a1 = g->armymen[s]; /* get the army number */
- X if (g->army[a1].color == Blank) {
- X g->movecount = g->movecount + g->army[a1].size;
- X if (wh == White) g->deadwhite = g->deadwhite - g->army[a1].size;
- X else g->deadblack = g->deadblack - g->army[a1].size;
- X g->army[a1].color = wh; /* change army color to non-blank */
- X g->army[a1].size = 0; /* causes army to be rebuilt by buildarmies */
- X s1 = g->army[a1].first; /* first man in army */
- X while (s1 >= 0) {
- X g->board[s1] = wh; /* change stone color to non-blank */
- X drawstone(g,s1,wh);
- X topicture(g,s1); /* add to picture */
- X/* clear the size in neighboring enemy armies so they will be rebuilt */
- X getneighbors(g,&nabor,s1);
- X for (n = firstelement; n < nabor.neis; n++) { /* for neighbors */
- X a2 = g->armymen[nabor.stone[n]];
- X if (g->army[a2].color != wh) g->army[a2].size = 0;
- X }
- X/* get the next man in the army */
- X s1 = g->armylnk[s1]; /* row link to next army man */
- X }
- X buildarmies(g);
- X }
- X } else {
- X printf("Bad uncapture an army at: %c,%d\n",
- X coltable[g->colbrd[s]],g->rowbrd[s]);
- X }
- X if ((g->debug & 1) != 0) printf(" uncapture, end.\n");
- X}
- X
- Xgetneighbors(g,nabor,stone) game *g; neighbors *nabor; int stone; {
- Xint b,i,j,s;
- X/* Establish the number and position of neighbors to a stone. Gather
- X the stone numbers of neighboring positions into the nabor.stone
- X array sorted by army number. The purpose of the sort is
- X to group neighbors belonging to the same army together. */
- X nabor->neis = firstelement;
- X if ((g->neibrd[stone] & 1) != 0) {
- X nabor->stone[firstelement] = stone - 1;
- X nabor->direction[firstelement] = 1;
- X nabor->neis = nabor->neis + 1; }
- X if ((g->neibrd[stone] & 2) != 0) {
- X nabor->stone[nabor->neis] = stone + 1;
- X nabor->direction[nabor->neis] = 2;
- X nabor->neis = nabor->neis + 1; }
- X if ((g->neibrd[stone] & 4) != 0) {
- X nabor->stone[nabor->neis] = stone - g->width;
- X nabor->direction[nabor->neis] = 4;
- X nabor->neis = nabor->neis + 1; }
- X if ((g->neibrd[stone] & 8) != 0) {
- X nabor->stone[nabor->neis] = stone + g->width;
- X nabor->direction[nabor->neis] = 8;
- X nabor->neis = nabor->neis + 1; }
- X for (i = firstelement; i < nabor->neis-1; i++) {
- X for (j = i+1; j < nabor->neis; j++) {
- X if (g->armymen[nabor->stone[j]] < g->armymen[nabor->stone[i]]) {
- X s = nabor->stone[j];
- X nabor->stone[j] = nabor->stone[i]; nabor->stone[i] = s;
- X b = nabor->direction[j];
- X nabor->direction[j] = nabor->direction[i]; nabor->direction[i] = b;
- X} } } }
- X
- Xallarmies(g) game *g; {
- X/* Clear all army numbers in the army array, and call build armies */
- Xint n,s;
- X if ((g->debug & 1) != 0) printf("allarmies:\n");
- X g->avail = 1; /* next available army number */
- X g->army[1].bp = 0;
- X for (n = firstelement; n < maxarmies; n++) {
- X g->army[n].first = -1;
- X g->army[n].fp = n + 1; /* initialize armies forward links */
- X }
- X for (s = firstelement; s < g->maxstone; s++) {
- X g->armymen[s] = 0; g->armylnk[s] = s - 1;
- X }
- X linkarmies(g,g->maxstone-1);
- X if ((g->debug & 1) != 0) printf(" allarmies.\n");
- X}
- X
- Xlinkarmies(g,first) game *g; int first; {
- X/* Create a 1 man army for each square. Then look at neighboring squares,
- X and if any are the same color army then merge the new army into the
- X neighboring army */
- Xint n,s,s1,s2,new,old; neighbors nabor;
- X if ((g->debug & 1) != 0) printf("linkarmies:\n");
- X s = first;
- X old = g->armymen[s]; /* save old army number */
- X while (s >= 0) {
- X s1 = g->armylnk[s]; /* save link to next old army man */
- X new = g->avail; /* get next available army number */
- X g->avail = g->army[g->avail].fp;
- X g->army[g->avail].bp = new;
- X g->armymen[s] = new; /* set new army number */
- X g->armylnk[s] = -1;
- X g->army[new].size = 0; /* size is done by buildarmies */
- X g->army[new].color = g->board[s];
- X g->army[new].first = s; g->army[new].last = s;
- X getneighbors(g,&nabor,s); /* get the neighbors */
- X for (n = firstelement; n < nabor.neis; n++) { /* go through the neighbors *
- X/
- X s2 = nabor.stone[n];
- X if (g->armymen[s2] != old) { armymerge(g,s2,s); }
- X }
- X s = s1; /* next man to be linked */
- X }
- X/* make old army number available */
- X if (old > 0) {
- X if (g->army[old].fp != g->avail) {
- X if (g->army[old].bp > 0) {
- X g->army[g->army[old].bp].fp = g->army[old].fp; }
- X g->army[g->army[old].fp].bp = g->army[old].bp;
- X g->army[g->army[g->avail].bp].fp = old;
- X g->army[old].fp = g->avail;
- X g->army[old].bp = g->army[g->avail].bp;
- X g->army[g->avail].bp = old;
- X }
- X g->army[old].first = -1; g->avail = old;
- X }
- X buildarmies(g);
- X if ((g->debug & 1) != 0) printf(" linkarmies.\n");
- X}
- X
- Xbuildarmies(g) game *g; {
- X/* Add up the number of computer and opponent stones that border on
- X each army */
- Xint a1,a2,n,s,s1; neighbors nabor;
- X if ((g->debug & 1) != 0) printf("buildarmies:\n");
- X for (s = firstelement; s < g->maxstone; s++) wrkbrd[s] = 0;
- X a1 = g->army[g->avail].bp;
- X while (a1 > 0) { /* go through each active army */
- X if ((g->army[a1].size <= 0) && (g->army[a1].first >= 0)) {
- X g->army[a1].lib = 0;
- X g->army[a1].friend = 0;
- X g->army[a1].enemy = 0;
- X g->army[a1].armies = 0;
- X s = g->army[a1].first; /* first man in army */
- X while (s >= 0) {
- X g->army[a1].size = g->army[a1].size + 1;
- X getneighbors(g,&nabor,s); /* get the neighbors */
- X for (n = firstelement; n < nabor.neis; n++) { /* go through neighbors *
- X/
- X s1 = nabor.stone[n];
- X if (wrkbrd[s1] != a1) {
- X wrkbrd[s1] = a1; /* mark this neighbor counted */
- X if (g->board[s] != Blank) {
- X if (g->board[s1] == Blank) {
- X g->army[a1].lib = g->army[a1].lib + 1;
- X } else if (g->board[s1] != g->board[s]) {
- X g->army[a1].enemy = g->army[a1].enemy + 1;
- X }
- X } else {
- X if (g->board[s1] != Blank) {
- X if (g->board[s1] == White) {
- X g->army[a1].friend = g->army[a1].friend + 1;
- X } else {
- X g->army[a1].enemy = g->army[a1].enemy + 1;
- X }
- X }
- X }
- X }
- X }
- X s = g->armylnk[s]; /* link to next man */
- X }
- X }
- X a1 = g->army[a1].bp;
- X }
- X if ((g->debug & 1) != 0) printf(" buildarmies.\n");
- X}
- X
- Xarmymerge(g,s1,s2) game *g; int s1,s2; {
- X/* Merge two armies by merging the linked lists */
- Xint a1,a2,i,s,s3;
- X a1 = g->armymen[s1]; a2 = g->armymen[s2];
- X if ((a1 > 0) && (a1 != a2) && (g->board[s1] == g->board[s2])) {
- X/* Change a2 number to a1 for all the a2 armymen */
- X s = g->army[a2].first; /* first man in army */
- X while (s >= 0) { g->armymen[s] = a1; s = g->armylnk[s]; }
- X/* Link army a2 into army a1 */
- X g->armylnk[g->army[a2].last] = g->army[a1].first;
- X g->army[a1].first = g->army[a2].first;
- X g->army[a2].first = -1; /* delete army a2 */
- X g->army[a2].size = 0;
- X g->army[a1].size = 0; /* required for buildarmies */
- X if (g->army[a2].fp != g->avail) {
- X if (g->army[a2].bp > 0) {
- X g->army[g->army[a2].bp].fp = g->army[a2].fp; }
- X g->army[g->army[a2].fp].bp = g->army[a2].bp;
- X g->army[g->army[g->avail].bp].fp = a2;
- X g->army[a2].fp = g->avail;
- X g->army[a2].bp = g->army[g->avail].bp;
- X g->army[g->avail].bp = a2;
- X }
- X g->avail = a2;
- X} }
- X
- Xtopicture(g,s) game *g; int s; {
- X/* Add the specified stone to the bitmap of the stones in the 5 by 5
- X diamond centered about the specified stone */
- Xint i,s1,s2,s3,w3; long bit,*p; char *c;
- X i = - g->width - g->width - 2; bit = 1L; s1 = -1;
- X if (g->who == White) { p = &g->whitepats[s]; c = &g->whitecount[s]; }
- X else { p = &g->blackpats[s]; c = &g->blackcount[s]; }
- X for (s2 = 0; s2 < patwidth; s2++) {
- X for (s3 = 0; s3 < patwidth; s3++) {
- X s1 = s1 + 1;
- X if ((picset[s1] & g->neibrd[s]) == picset[s1])
- X { *(p+i) = *(p+i) | bit; *(c+i) = *(c+i) + 1; }
- X bit = bit + bit; i = i + 1;
- X } i = i + g->width - patwidth;
- X }
- X w3 = g->width + g->width + g->width;
- X if ((picset[25] & g->neibrd[s]) == picset[25])
- X { *(p-3) = *(p-3) | 0x2000000L; *(c-3) = *(c-3) + 1; }
- X if ((picset[26] & g->neibrd[s]) == picset[26])
- X { *(p+3) = *(p+3) | 0x4000000L; *(c+3) = *(c+3) + 1; }
- X if ((picset[27] & g->neibrd[s]) == picset[27])
- X { *(p-w3) = *(p-w3) | 0x8000000L; *(c-w3) = *(c-w3) + 1; }
- X if ((picset[28] & g->neibrd[s]) == picset[28])
- X { *(p+w3) = *(p+w3) | 0x10000000L; *(c+w3) = *(c+w3) + 1; }
- X}
- X
- Xfrompicture(g,s) game *g; int s; {
- X/* Remove the specified stone from the bitmap of the stones in the 5 by 5
- X diamond centered about the specified stone. */
- Xint i,s1,s2,s3,w3; long bit,*p; char *c;
- X i = - g->width - g->width - 2; bit = 1; s1 = -1;
- X if (g->who == White) { p = &g->whitepats[s]; c = &g->whitecount[s]; }
- X else { p = &g->blackpats[s]; c = &g->blackcount[s]; }
- X for (s2 = 0; s2 < patwidth; s2++) {
- X for (s3 = 0; s3 < patwidth; s3++) {
- X s1 = s1 + 1;
- X if ((picset[s1] & g->neibrd[s]) == picset[s1])
- X { *(p+i) = *(p+i) & ~bit; *(c+i) = *(c+i) - 1; }
- X bit = bit + bit; i = i + 1;
- X } i = i + g->width - patwidth;
- X }
- X w3 = g->width + g->width + g->width;
- X if ((picset[25] & g->neibrd[s]) == picset[25])
- X { *(p-3) = *(p-3) & ~0x2000000L; *(c-3) = *(c-3) - 1; }
- X if ((picset[26] & g->neibrd[s]) == picset[26])
- X { *(p+3) = *(p+3) & ~0x4000000L; *(c+3) = *(c+3) - 1; }
- X if ((picset[27] & g->neibrd[s]) == picset[27])
- X { *(p-w3) = *(p-w3) & ~0x8000000L; *(c-w3) = *(c-w3) - 1; }
- X if ((picset[28] & g->neibrd[s]) == picset[28])
- X { *(p+w3) = *(p+w3) & ~0x10000000L; *(c+w3) = *(c+w3) - 1; }
- X}
- X
- X/* The following routines provide output for debugging */
- X
- Xmoveboard(g) game *g; {
- Xint i,s;
- X s = 0;
- X while (s < g->maxstone) {
- X for (i = firstelement; i < g->width; i++) {
- X if (g->board[s] == White) printf(" 1");
- X else if (g->board[s] == Black) printf(" 2");
- X else printf(" 0");
- X s = s + 1;
- X }
- X printf("\n");
- X} }
- X
- Xarmyboard(g) game *g; {
- Xint i,s;
- X s = 0;
- X while (s < g->maxstone) {
- X for (i = firstelement; i < g->width; i++) { printf("%3d",g->armymen[s]); s =
- X s + 1; }
- X printf("\n");
- X} }
- X
- Xarmyinfo(g) game *g; {
- Xint i,n; char qkey;
- X qkey = 'g';
- X printf("Total stones: %d\nAvail: %d\n",g->movecount,g->avail);
- X n = 0;
- X i = g->army[g->avail].bp;
- X while (i > 0) { if (i > n) n = i; i = g->army[i].bp; }
- X printf("Highest army number: %d\n",n);
- X i = g->army[g->avail].bp;
- X while ((qkey != 'q') && (i > 0)) {
- X printf("Army %d\n",i);
- X if (g->army[i].first >= 0) {
- X printf("Color %d\nSize %d\nFirst %d\nLast %d\n",
- X g->army[i].color,g->army[i].size,g->army[i].first,g->army[i].last);
- X printf("FP %d\nBP %d\nLiberties %d\nFriends %d\nEnemies %d\n",
- X g->army[i].fp,g->army[i].bp,g->army[i].lib,g->army[i].friend,g->army[i].
- Xenemy);
- X }
- X i = g->army[i].bp;
- X printf("q return to quit, space to continue\n"); qkey = getchar();
- X }
- X}
- X
- Xlinkinfo(g) game *g; {
- Xint i,s;
- X s = firstelement;
- X while (s < g->maxstone) {
- X for (i = firstelement; i < g->width; i++) { printf("%d ",g->armylnk[s]); s =
- X s + 1; }
- X printf("\n");
- X }
- X}
- X
- Xpictinfo(g) game *g; {
- Xint i,s; char qkey;
- X s = 0; qkey = 'g';
- X printf("White stone patterns:\n");
- X while ((s < g->maxstone) && (qkey != 'q') && (qkey != 'n')) {
- X for (i = firstelement; i < g->width; i++)
- X { printf(" %lx\n",g->whitepats[s]); s = s + 1; }
- X printf("q return to quit, space to continue\n"); qkey = getchar();
- X } printf("Black stone patterns:\n");
- X s = 0;
- X while ((s < g->maxstone) && (qkey != 'q')) {
- X for (i = firstelement; i < g->width; i++)
- X { printf(" %lx\n",g->blackpats[s]); s = s + 1; }
- X printf("q return to quit, space to continue\n"); qkey = getchar();
- X }
- X}
- X
- Xneighborinfo(g) game *g; {
- Xint i,s;
- X s = 0;
- X while (s < g->maxstone) {
- X for (i = firstelement; i < g->width; i++)
- X { printf("%4x ",g->neibrd[s]); s = s + 1; }
- X printf("\n");
- X }
- X}
- X
- Xdrawboard(g) game *g; {
- Xint i,linelength; rect srect; char num[4];
- X setport(mywindow);
- X/* Draw the position letters and numbers */
- X textsize(9);
- X for (i = g->width; i > 0; i--) {
- X moveto(-12,14 + 16 * (g->width - i));
- X sprintf(num,"%2d", i);
- X drawstring(num);
- X }
- X for (i = 0; i < g->width; i++) {
- X moveto(7 + 16 * i,13 + 16 * g->width);
- X drawchar(coltable[i]);
- X }
- X/* Draw the board */
- X textsize(7);
- X linelength = 16 * (g->width - 1);
- X moveto(10,10);
- X for (i = 0; i < g->width; i++) {
- X line(linelength,0);
- X move(-linelength,16);
- X }
- X moveto(10,10);
- X for (i = 0; i < g->width; i++) {
- X line(0,linelength);
- X move(16,-linelength);
- X }
- X/* draw the handicap positions on a 19 X 19 board */
- X if (g->width == 19) {
- X/* first draw the corner handicap positions */
- X setrect(&srect, 55, 55, 61, 61); filloval(&srect,&blackpat);
- X setrect(&srect, 55, 247, 61, 253); filloval(&srect,&blackpat);
- X setrect(&srect, 247, 55, 253, 61); filloval(&srect,&blackpat);
- X setrect(&srect, 247, 247, 253, 253); filloval(&srect,&blackpat);
- X/* now draw the other row 3 handicap positions */
- X setrect(&srect, 55, 151, 61, 157); filloval(&srect,&blackpat);
- X setrect(&srect, 151, 55, 157, 61); filloval(&srect,&blackpat);
- X setrect(&srect, 247, 151, 253, 157); filloval(&srect,&blackpat);
- X setrect(&srect, 151, 247, 157, 253); filloval(&srect,&blackpat);
- X/* finally draw the center handicap position */
- X setrect(&srect, 151, 151, 157, 157); filloval(&srect,&blackpat);
- X }
- X setport(mewindow);
- X}
- X
- Xdrawstone(g,s,wh) game *g; int s,wh; {
- Xint w,x,y; rect srect; char num[8];
- X if ((looking == 0) || (lookahead != 0)) {
- X setport(mywindow);
- X x = 10 + 16 * (s % g->width);
- X y = 10 + 16 * ((g->maxstone - 1 - s) / g->width);
- X setrect(&srect, x-8, y-8, x+8, y+8);
- X if (wh == White) {
- X filloval(&srect,&whitepat);
- X } else {
- X filloval(&srect,&blackpat);
- X }
- X if ((drawnumber != 0) && (looking == 0)) {
- X sprintf(num,"%d",stonenumber);
- X w = stringwidth(num) >> 1;
- X moveto(x-w,y+3);
- X drawstring(num);
- X }
- X setport(mewindow);
- X }
- X}
- X
- Xundrawstone(g,s) game *g; int s; {
- Xint x,y; rect srect;
- X if ((looking == 0) || (lookahead != 0)) {
- X setport(mywindow);
- X x = 10 + 16 * (s % g->width);
- X y = 10 + 16 * ((g->maxstone - 1 - s) / g->width);
- X setrect(&srect, x-8, y-8, x+8, y+8);
- X eraseoval(&srect);
- X if ((g->neibrd[s] & 1) != 0) { moveto(x,y); line(-8,0); }
- X if ((g->neibrd[s] & 2) != 0) { moveto(x,y); line(8,0); }
- X if ((g->neibrd[s] & 4) != 0) { moveto(x,y); line(0,8); }
- X if ((g->neibrd[s] & 8) != 0) { moveto(x,y); line(0,-8); }
- X/* draw the handicap positions on a 19 X 19 board */
- X if (g->width == 19) {
- X/* first draw the corner handicap positions */
- X if (s == 60) {
- X setrect(&srect, 55, 247, 61, 253); filloval(&srect,&blackpat); }
- X if (s == 72) {
- X setrect(&srect, 247, 247, 253, 253); filloval(&srect,&blackpat); }
- X if (s == 288) {
- X setrect(&srect, 55, 55, 61, 61); filloval(&srect,&blackpat); }
- X if (s == 300) {
- X setrect(&srect, 247, 55, 253, 61); filloval(&srect,&blackpat); }
- X/* now draw the other row 3 handicap positions */
- X if (s == 174) {
- X setrect(&srect, 55, 151, 61, 157); filloval(&srect,&blackpat); }
- X if (s == 294) {
- X setrect(&srect, 151, 55, 157, 61); filloval(&srect,&blackpat); }
- X if (s == 186) {
- X setrect(&srect, 247, 151, 253, 157); filloval(&srect,&blackpat); }
- X if (s == 66) {
- X setrect(&srect, 151, 247, 157, 253); filloval(&srect,&blackpat); }
- X/* finally draw the center handicap position */
- X if (s == 180) {
- X setrect(&srect, 151, 151, 157, 157); filloval(&srect,&blackpat); }
- X }
- X setport(mewindow);
- X }
- X}
- ________This_Is_The_END________
- if test `wc -l < goprocs.c` -ne 727; then
- echo 'shar: goprocs.c was damaged during transit'
- echo ' (should have been 727 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'Extracting goprocs.h'
- if test -f goprocs.h; then echo 'shar: will not overwrite goprocs.h'; else
- sed 's/^X//' << '________This_Is_The_END________' > goprocs.h
- X/* File goprocs.h
- X Developer: James R. Logan Jr. (BYU), Advisor: Dr. Lynn H. Beus (BYU)
- X email address: loganj@byuvax.bitnet
- X (801) 378-3617
- X
- X Structures required by the go program utilities.
- X This code is not machine dependent.
- X*/
- X
- X#define firstelement 0
- X#define brdsize 19
- X#define maxstones 362
- X#define maxarmies 362
- X#define White 0
- X#define Black 1
- X#define Blank 2
- X
- Xtypedef struct {
- X int
- X color, /* army color */
- X size, /* army size */
- X first, /* first armyman's position */
- X last, /* last armyman's position */
- X fp, /* forward pointer to next army */
- X bp, /* backward pointer to last army */
- X lib, /* number of liberties, for nonblank armies only */
- X friend, /* number of neighboring White stones, for blank armies only */
- X enemy, /* number of enemy stones for nonblank armies, or Black stones */
- X armies, /* number of neighboring armies */
- X rollcall;/* scratch pad variable */
- X} armystruct;
- X
- Xtypedef struct {
- X int kospot; /* valid ko position, or -1, result of last move */
- X long captures; /* bit 1 is capture on the west (left)
- X bit 2 is capture on the east (right)
- X bit 3 is capture on the south (down)
- X bit 4 is capture on the north (up) */
- X} mstatus;
- X
- Xtypedef struct {
- X int
- X who, /* White for computer's level, Black for opponent */
- X avail, /* next available army number */
- X maxstone, /* size of 1-dimensional board */
- X width, /* width of 1-dimensional board */
- X movecount,/* number of stones played on the board */
- X deadwhite,/* number of captured white stones */
- X deadblack,/* number of captured black stones */
- X debug; /* debug flags */
- X char
- X board[maxstones], /* computer = White, opponent = Black */
- X rowbrd[maxstones], /* translates 1-dimension row to 2-dimension */
- X colbrd[maxstones], /* translates 1-dimension col to 2-dimension */
- X whitecount[maxstones],/* count of white stones in whitepats */
- X blackcount[maxstones];/* count of black stones in blackpats */
- X int
- X armymen[maxstones], /* men of same army have same num */
- X armylnk[maxstones]; /* link to next army member */
- X long
- X whitepats[maxstones],/* bit pattern of white stones in 5 by 5 square */
- X blackpats[maxstones],/* bit pattern of black stones in 5 by 5 square */
- X neibrd[maxstones]; /* n by n bit encoded valid neighbors array */
- X mstatus movestatus; /* ko position and capture info */
- X armystruct army[maxarmies];
- X} game;
- X
- Xtypedef struct {
- X int
- X neis,
- X stone[4],
- X direction[4];
- X /* bit 1 is neighbor on the west (left)
- X bit 2 is capture on the east (right)
- X bit 3 is capture on the south (down)
- X bit 4 is capture on the north (up) */
- X} neighbors;
- ________This_Is_The_END________
- if test `wc -l < goprocs.h` -ne 77; then
- echo 'shar: goprocs.h was damaged during transit'
- echo ' (should have been 77 bytes)'
- fi
- fi ; : end of overwriting check
- exit 0
-