1 /*
2  * src/gogame.h, part of Complete Goban (game program)
3  * Copyright (C) 1995-1997 William Shubert.
4  * See "configure.h.in" for more copyright information.
5  */
6 
7 
8 #ifndef  _GOGAME_H_
9 #define  _GOGAME_H_  1
10 
11 #ifndef  _GOHASH_H_
12 #include "goHash.h"
13 #endif
14 #ifndef  _GOBOARD_H_
15 #include "goBoard.h"
16 #endif
17 #ifndef  _GOTIME_H_
18 #include "goTime.h"
19 #endif
20 
21 
22 /**********************************************************************
23  * Constants
24  **********************************************************************/
25 #define  GOGAME_PASS  0
26 
27 
28 /**********************************************************************
29  * Data types
30  **********************************************************************/
31 
32 typedef enum  {
33   goRules_chinese, goRules_japanese, goRules_ing, goRules_aga,
34   goRules_nz, goRules_tibetan
35 } GoRules;
36 #define  goRules_num  ((int)goRules_tibetan + 1)
37 
38 
39 typedef enum  {
40   goRulesKo_japanese, goRulesKo_super, goRulesKo_tibetan
41     /*
42      * goRulesKo_ing is longer supported since it can't be implemented
43      *   accurately by a computer without lots of help from the players.
44      */
45 } GoRulesKo;
46 
47 
48 typedef enum  {
49   goGameState_play, goGameState_dispute,
50   goGameState_selectDead, goGameState_selectDisputed,
51   goGameState_done
52 } GoGameState;
53 
54 #define  GOGAMEFLAGS_DISPUTED      0x0001
55 #define  GOGAMEFLAGS_MARKDEAD      0x0002
56 #define  GOGAMEFLAGS_WANTDEAD      0x0004
57 #define  GOGAMEFLAGS_RESOLVEDEAD   0x0008
58 #define  GOGAMEFLAGS_RESOLVEALIVE  0x0010
59 #define  GOGAMEFLAGS_SEEWHITE      0x0020
60 #define  GOGAMEFLAGS_SEEBLACK      0x0040
61 #define  GOGAMEFLAGS_SEKI          0x0080
62 #define  GOGAMEFLAGS_NOSEKI        0x0100
63 #define  GOGAMEFLAGS_SPECIAL       0x0200  /* For seki detection. */
64 #define  GOGAMEFLAGS_EYE           0x0400  /* For seki detection. */
65 #define  GOGAMEFLAGS_FAKETEST      0x0800  /* For seki detection. */
66 #define  GOGAMEFLAGS_NOTFAKE       0x1000  /* For seki detection. */
67 
68 #define  GOGAMEFLAGS_RESOLVED  (GOGAMEFLAGS_RESOLVEDEAD| \
69                                 GOGAMEFLAGS_RESOLVEALIVE)
70 #define  GOGAMEFLAGS_SEEN  (GOGAMEFLAGS_SEEBLACK|GOGAMEFLAGS_SEEWHITE)
71 #define  goGameFlags_see(s)  (GOGAMEFLAGS_SEEWHITE << (s))
72 
73 
74 typedef struct GoGameMove_struct  {
75   int  move;
76   GoStone  color;
77   GoHash  hash;  /* Hash value at the beginning of this move. */
78   GoTimer  time;  /* Time left at this move. */
79 } GoGameMove;
80 
81 
82 typedef struct  {
83   int  size;
84   GoRules  rules;
85 
86   /*
87    * Passive and forcePlay are somewhat redundant.  I should clean them up.
88    *   But basically, passive means it is controlled by the SGF, and
89    *   forcePlay means go server.  Yuck.
90    */
91   bool  passive;
92   bool  forcePlay;
93 
94   float  komi;
95   GoTime  time;
96   int  moveNum, maxMoves, handicap, passCount;
97   GoGameMove  *moves;
98   int  movesLen;
99   bool  noLastMove;
100   GoStone  whoseMove;
101 
102   GoBoard  *board;
103   GoBoard  *tmpBoard;  /* Used for superko rule and seki checks. */
104   uint  *flags;
105   bool  flagsCleared;
106   int  *hotMoves;
107   int  cooloff;  /* The last move that cleared the kos. */
108   GoGameState  state;
109 
110   bool  disputeAlive;
111   int  setWhoseMoveNum;
112   GoStone  setWhoseMoveColor;
113   int  disputedLoc;
114 
115   MAGIC_STRUCT
116 } GoGame;
117 
118 /**********************************************************************
119  * Global variables
120  **********************************************************************/
121 extern const bool  goRules_freeHandicaps[goRules_num];
122 extern const GoRulesKo  goRules_ko[goRules_num];
123 extern const bool  goRules_suicide[goRules_num];
124 extern const bool  goRules_dispute[goRules_num];
125 extern const bool  goRules_scoreKills[goRules_num];
126 
127 /**********************************************************************
128  * Functions
129  **********************************************************************/
130 extern GoGame  *goGame_create(int size, GoRules rules, int handicap,
131 			      float komi, const GoTime *time, bool passive);
132 extern void  goGame_destroy(GoGame *game);
133 
134 /*
135  * Valid in the play or dispute states.
136  */
137 /*
138  * goGame_move() returns TRUE if the move caused the game's state to change.
139  * Possible changes:
140  *   play --> selectDead
141  *   dispute --> selectDead
142  *   play, dispute --> done (for time-out losses only, move will not be made)
143  */
144 extern bool  goGame_move(GoGame *game, GoStone color, int move,
145 			 GoTimer *currentTime);
146 extern void  goGame_setBoard(GoGame *game, GoStone color, int loc);
147 #define  goGame_pass(g, color, t)  goGame_move((g), color, GOGAME_PASS, t)
148 #define  goGame_isHot(g, l)  ((g)->hotMoves[l] >= (g)->cooloff)
149 #define  goGame_whoseMove(g)  ((g)->whoseMove)
150 extern GoStone  goGame_whoseTurnOnMove(GoGame *game, int moveNum);
151 extern const GoTimer  *goGame_getTimer(const GoGame *game, GoStone color);
152 
153 /*
154  * Valid in play, dispute, or done states.  Returns TRUE if the game's state
155  *   has changed, just like goGame_move.
156  * Possible changes:
157  *   play --> done
158  *   done --> play
159  */
160 extern bool  goGame_moveTo(GoGame *game, int moveNum);
161 
162 /*
163  * Valid in the selectDead state.
164  */
165 extern void  goGame_markDead(GoGame *game, int loc);
166 /*
167  * resume() will change state from selectDead to play.
168  */
169 extern void  goGame_resume(GoGame *game);
170 /*
171  * done() will change state from selectDead to done.
172  */
173 extern void  goGame_done(GoGame *game);
174 /*
175  * selectDisputed() will change state from selectDead to selectDisputed.
176  */
177 #define  goGame_selectDisputed(g)  ((g)->state = goGameState_selectDisputed)
178 
179 /*
180  * dispute() will change state from selectDisputed to dispute.
181  */
182 extern void  goGame_dispute(GoGame *game, int loc);
183 
184 /*
185  * Always valid.
186  */
187 extern bool  goGame_isLegal(GoGame *game, GoStone moveColor, int move);
188 #define  goGame_caps(g, s)  goBoard_caps((g)->board, (s))
189 extern int  goGame_lastMove(GoGame *g);
190 #define  goGame_noLastMove(g)  ((g)->noLastMove = TRUE)
191 
192 #endif  /* _GOGAME_H_ */
193