xref: /csrg-svn/games/gomoku/gomoku.h (revision 69196)
167562Smckusick /*
267562Smckusick  * Copyright (c) 1994
367562Smckusick  *	The Regents of the University of California.  All rights reserved.
467562Smckusick  *
567562Smckusick  * This code is derived from software contributed to Berkeley by
667562Smckusick  * Ralph Campbell.
767562Smckusick  *
867562Smckusick  * %sccs.include.redist.c%
967562Smckusick  *
10*69196Smckusick  *	@(#)gomoku.h	8.2 (Berkeley) 05/03/95
1167562Smckusick  */
1267562Smckusick 
1367562Smckusick #include <sys/types.h>
1467562Smckusick 
1567562Smckusick /* board dimensions */
1667562Smckusick #define BSZ	19
1767562Smckusick #define BSZ1	(BSZ+1)
1867562Smckusick #define BSZ2	(BSZ+2)
1967562Smckusick #define BAREA	(BSZ2*BSZ1+1)
2067562Smckusick 
2167562Smckusick /* frame dimentions (based on 5 in a row) */
2267562Smckusick #define FSZ1	BSZ
2367562Smckusick #define FSZ2	(BSZ-4)
2467562Smckusick #define FAREA	(FSZ1*FSZ2 + FSZ2*FSZ2 + FSZ1*FSZ2 + FSZ2*FSZ2)
2567562Smckusick 
2667562Smckusick #define MUP	(BSZ1)
2767562Smckusick #define MDOWN	(-BSZ1)
2867562Smckusick #define MLEFT	(-1)
2967562Smckusick #define MRIGHT	(1)
3067562Smckusick 
3167562Smckusick /* values for s_occ */
3267562Smckusick #define BLACK	0
3367562Smckusick #define WHITE	1
3467562Smckusick #define EMPTY	2
3567562Smckusick #define BORDER	3
3667562Smckusick 
3767562Smckusick /* return values for makemove() */
3867562Smckusick #define MOVEOK	0
3967562Smckusick #define RESIGN	1
4067562Smckusick #define ILLEGAL	2
4167562Smckusick #define WIN	3
4267562Smckusick #define TIE	4
4367562Smckusick #define SAVE	5
4467562Smckusick 
4567562Smckusick #define A 1
4667562Smckusick #define B 2
4767562Smckusick #define C 3
4867562Smckusick #define D 4
4967562Smckusick #define E 5
5067562Smckusick #define F 6
5167562Smckusick #define G 7
5267562Smckusick #define H 8
5367562Smckusick #define J 9
5467562Smckusick #define K 10
5567562Smckusick #define L 11
5667562Smckusick #define M 12
5767562Smckusick #define N 13
5867562Smckusick #define O 14
5967562Smckusick #define P 15
6067562Smckusick #define Q 16
6167562Smckusick #define R 17
6267562Smckusick #define S 18
6367562Smckusick #define T 19
6467562Smckusick 
6567562Smckusick #define PT(x,y)		((x) + BSZ1 * (y))
6667562Smckusick 
6767562Smckusick /*
6867562Smckusick  * A 'frame' is a group of five or six contiguous board locations.
6967562Smckusick  * An open ended frame is one with spaces on both ends; otherwise, its closed.
7067562Smckusick  * A 'combo' is a group of intersecting frames and consists of two numbers:
7167562Smckusick  * 'A' is the number of moves to make the combo non-blockable.
7267562Smckusick  * 'B' is the minimum number of moves needed to win once it can't be blocked.
7367562Smckusick  * A 'force' is a combo that is one move away from being non-blockable
7467562Smckusick  *
7567562Smckusick  * Single frame combo values:
7667562Smckusick  *     <A,B>	board values
7767562Smckusick  *	5,0	. . . . . O
7867562Smckusick  *	4,1	. . . . . .
7967562Smckusick  *	4,0	. . . . X O
8067562Smckusick  *	3,1	. . . . X .
8167562Smckusick  *	3,0	. . . X X O
8267562Smckusick  *	2,1	. . . X X .
8367562Smckusick  *	2,0	. . X X X O
8467562Smckusick  *	1,1	. . X X X .
8567562Smckusick  *	1,0	. X X X X O
8667562Smckusick  *	0,1	. X X X X .
8767562Smckusick  *	0,0	X X X X X O
8867562Smckusick  *
8967562Smckusick  * The rule for combining two combos (<A1,B1> <A2,B2>)
9067562Smckusick  * with V valid intersection points, is:
9167562Smckusick  *	A' = A1 + A2 - 2 - V
9267562Smckusick  *	B' = MIN(A1 + B1 - 1, A2 + B2 - 1)
9367562Smckusick  * Each time a frame is added to the combo, the number of moves to complete
9467562Smckusick  * the force is the number of moves needed to 'fill' the frame plus one at
9567562Smckusick  * the intersection point. The number of moves to win is the number of moves
9667562Smckusick  * to complete the best frame minus the last move to complete the force.
9767562Smckusick  * Note that it doesn't make sense to combine a <1,x> with anything since
9867562Smckusick  * it is already a force. Also, the frames have to be independent so a
9967562Smckusick  * single move doesn't affect more than one frame making up the combo.
10067562Smckusick  *
10167562Smckusick  * Rules for comparing which of two combos (<A1,B1> <A2,B2>) is better:
10267562Smckusick  * Both the same color:
10367562Smckusick  *	<A',B'> = (A1 < A2 || A1 == A2 && B1 <= B2) ? <A1,B1> : <A2,B2>
10467562Smckusick  *	We want to complete the force first, then the combo with the
10567562Smckusick  *	fewest moves to win.
10667562Smckusick  * Different colors, <A1,B1> is the combo for the player with the next move:
10767562Smckusick  *	<A',B'> = A2 <= 1 && (A1 > 1 || A2 + B2 < A1 + B1) ? <A2,B2> : <A1,B1>
10867562Smckusick  *	We want to block only if we have to (i.e., if they are one move away
10967562Smckusick  *	from completing a force and we don't have a force that we can
11067562Smckusick  *	complete which takes fewer or the same number of moves to win).
11167562Smckusick  */
11267562Smckusick 
11367562Smckusick #define MAXA		6
11467562Smckusick #define MAXB		2
11567562Smckusick #define MAXCOMBO	0x600
11667562Smckusick 
117*69196Smckusick union	comboval {
11867562Smckusick 	struct {
11967562Smckusick #if BYTE_ORDER == BIG_ENDIAN
12067562Smckusick 		u_char	a;	/* # moves to complete force */
12167562Smckusick 		u_char	b;	/* # moves to win */
12267562Smckusick #endif
12367562Smckusick #if BYTE_ORDER == LITTLE_ENDIAN
12467562Smckusick 		u_char	b;	/* # moves to win */
12567562Smckusick 		u_char	a;	/* # moves to complete force */
12667562Smckusick #endif
12767562Smckusick 	} c;
12867562Smckusick 	u_short	s;
12967562Smckusick };
13067562Smckusick 
13167562Smckusick /*
132*69196Smckusick  * This structure is used to record information about single frames (F) and
133*69196Smckusick  * combinations of two more frames (C).
134*69196Smckusick  * For combinations of two or more frames, there is an additional
135*69196Smckusick  * array of pointers to the frames of the combination which is sorted
136*69196Smckusick  * by the index into the frames[] array. This is used to prevent duplication
137*69196Smckusick  * since frame A combined with B is the same as B with A.
138*69196Smckusick  *	struct combostr *c_sort[size c_nframes];
139*69196Smckusick  * The leaves of the tree (frames) are numbered 0 (bottom, leftmost)
140*69196Smckusick  * to c_nframes - 1 (top, right). This is stored in c_frameindex and
141*69196Smckusick  * c_dir if C_LOOP is set.
14267562Smckusick  */
14367562Smckusick struct combostr {
14467562Smckusick 	struct combostr	*c_next;	/* list of combos at the same level */
14567562Smckusick 	struct combostr	*c_prev;	/* list of combos at the same level */
146*69196Smckusick 	struct combostr	*c_link[2];	/* C:previous level or F:NULL */
147*69196Smckusick 	union comboval	c_linkv[2];	/* C:combo value for link[0,1] */
148*69196Smckusick 	union comboval	c_combo;	/* C:combo value for this level */
149*69196Smckusick 	u_short		c_vertex;	/* C:intersection or F:frame head */
15067562Smckusick 	u_char		c_nframes;	/* number of frames in the combo */
151*69196Smckusick 	u_char		c_dir;		/* C:loop frame or F:frame direction */
152*69196Smckusick 	u_char		c_flg;		/* C:combo flags */
153*69196Smckusick 	u_char		c_frameindex;	/* C:intersection frame index */
154*69196Smckusick 	u_char		c_framecnt[2];	/* number of frames left to attach */
155*69196Smckusick 	u_char		c_emask[2];	/* C:bit mask of completion spots for
156*69196Smckusick 					 * link[0] and link[1] */
157*69196Smckusick 	u_char		c_voff[2];	/* C:vertex offset within frame */
15867562Smckusick };
15967562Smckusick 
160*69196Smckusick /* flag values for c_flg */
161*69196Smckusick #define C_OPEN_0	0x01		/* link[0] is an open ended frame */
162*69196Smckusick #define C_OPEN_1	0x02		/* link[1] is an open ended frame */
163*69196Smckusick #define C_LOOP		0x04		/* link[1] intersects previous frame */
164*69196Smckusick #define C_MARK		0x08		/* indicates combo processed */
16567562Smckusick 
166*69196Smckusick /*
167*69196Smckusick  * This structure is used for recording the completion points of
168*69196Smckusick  * multi frame combos.
169*69196Smckusick  */
17067562Smckusick struct	elist {
171*69196Smckusick 	struct elist	*e_next;	/* list of completion points */
172*69196Smckusick 	struct combostr	*e_combo;	/* the whole combo */
173*69196Smckusick 	u_char		e_off;		/* offset in frame of this empty spot */
174*69196Smckusick 	u_char		e_frameindex;	/* intersection frame index */
175*69196Smckusick 	u_char		e_framecnt;	/* number of frames left to attach */
176*69196Smckusick 	u_char		e_emask;	/* real value of the frame's emask */
177*69196Smckusick 	union comboval	e_fval;		/* frame combo value */
17867562Smckusick };
17967562Smckusick 
18067562Smckusick /*
18167562Smckusick  * One spot structure for each location on the board.
18267562Smckusick  * A frame consists of the combination for the current spot plus the five spots
18367562Smckusick  * 0: right, 1: right & down, 2: down, 3: down & left.
18467562Smckusick  */
18567562Smckusick struct	spotstr {
18667562Smckusick 	short		s_occ;		/* color of occupant */
18767562Smckusick 	short		s_wval;		/* weighted value */
18867562Smckusick 	int		s_flg;		/* flags for graph walks */
189*69196Smckusick 	struct combostr	*s_frame[4];	/* level 1 combo for frame[dir] */
190*69196Smckusick 	union comboval	s_fval[2][4];	/* combo value for [color][frame] */
191*69196Smckusick 	union comboval	s_combo[2];	/* minimum combo value for BLK & WHT */
19267562Smckusick 	u_char		s_level[2];	/* number of frames in the min combo */
19367562Smckusick 	u_char		s_nforce[2];	/* number of <1,x> combos */
194*69196Smckusick 	struct elist	*s_empty;	/* level n combo completion spots */
195*69196Smckusick 	struct elist	*s_nempty;	/* level n+1 combo completion spots */
196*69196Smckusick 	int		dummy[2];	/* XXX */
19767562Smckusick };
19867562Smckusick 
19967562Smckusick /* flag values for s_flg */
20067562Smckusick #define CFLAG		0x000001	/* frame is part of a combo */
20167562Smckusick #define CFLAGALL	0x00000F	/* all frame directions marked */
20267562Smckusick #define IFLAG		0x000010	/* legal intersection point */
20367562Smckusick #define IFLAGALL	0x0000F0	/* any intersection points? */
20467562Smckusick #define FFLAG		0x000100	/* frame is part of a <1,x> combo */
20567562Smckusick #define FFLAGALL	0x000F00	/* all force frames */
20667562Smckusick #define MFLAG		0x001000	/* frame has already been seen */
20767562Smckusick #define MFLAGALL	0x00F000	/* all frames seen */
20867562Smckusick #define BFLAG		0x010000	/* frame intersects border or dead */
20967562Smckusick #define BFLAGALL	0x0F0000	/* all frames dead */
21067562Smckusick 
211*69196Smckusick /*
212*69196Smckusick  * This structure is used to store overlap information between frames.
213*69196Smckusick  */
214*69196Smckusick struct	ovlp_info {
215*69196Smckusick 	int		o_intersect;	/* intersection spot */
216*69196Smckusick 	struct combostr	*o_fcombo;	/* the connecting combo */
217*69196Smckusick 	u_char		o_link;		/* which link to update (0 or 1) */
218*69196Smckusick 	u_char		o_off;		/* offset in frame of intersection */
219*69196Smckusick 	u_char		o_frameindex;	/* intersection frame index */
220*69196Smckusick };
221*69196Smckusick 
22267562Smckusick extern	char	*letters;
22367562Smckusick extern	char	fmtbuf[];
224*69196Smckusick extern	char	pdir[];
22567562Smckusick 
22667562Smckusick extern	int     dd[4];
22767562Smckusick extern	struct	spotstr	board[BAREA];		/* info for board */
228*69196Smckusick extern	struct	combostr frames[FAREA];		/* storage for single frames */
22967562Smckusick extern	struct	combostr *sortframes[2];	/* sorted, non-empty frames */
230*69196Smckusick extern	u_char	overlap[FAREA * FAREA];		/* frame [a][b] overlap */
23167562Smckusick extern	short	intersect[FAREA * FAREA];	/* frame [a][b] intersection */
23267562Smckusick extern	int	movelog[BSZ * BSZ];		/* history of moves */
23367562Smckusick extern	int	movenum;
23467562Smckusick extern	int	debug;
23567562Smckusick 
23667562Smckusick extern	char    *copy();
23767562Smckusick extern	char    *stoc();
23867562Smckusick extern	char    *tail();
23967562Smckusick 
24067562Smckusick #define ASSERT(x)
241