]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - gomoku/makemove.c
1 /* $NetBSD: makemove.c,v 1.10 2009/06/04 05:43:29 dholland Exp $ */
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include <sys/cdefs.h>
38 static char sccsid
[] = "@(#)makemove.c 8.2 (Berkeley) 5/3/95";
40 __RCSID("$NetBSD: makemove.c,v 1.10 2009/06/04 05:43:29 dholland Exp $");
46 /* direction deltas */
48 MRIGHT
, MRIGHT
+MDOWN
, MDOWN
, MDOWN
+MLEFT
51 const int weight
[5] = { 0, 1, 7, 22, 100 };
55 * MOVEOK everything is OK.
56 * RESIGN Player resigned.
57 * ILLEGAL Illegal move.
58 * WIN The winning move was just played.
59 * TIE The game is a tie.
62 makemove(int us
, int mv
)
64 struct spotstr
*sp
, *fsp
;
67 struct combostr
*cbp
, *cbp1
;
70 int space
, val
, bmask
;
72 /* check for end of game */
76 /* check for illegal move */
78 if (sp
->s_occ
!= EMPTY
)
83 movelog
[movenum
- 1] = mv
;
84 if (++movenum
== BSZ
* BSZ
)
87 /* compute new frame values */
90 for (r
= 4; --r
>= 0; ) { /* for each direction */
94 for (f
= 5; --f
>= 0; fsp
-= d
) { /* for each frame */
95 if (fsp
->s_occ
== BORDER
)
97 if (fsp
->s_flags
& bmask
)
100 /* remove this frame from the sorted list of frames */
101 cbp
= fsp
->s_frame
[r
];
103 if (sortframes
[BLACK
] == cbp
)
104 sortframes
[BLACK
] = cbp
->c_next
;
105 if (sortframes
[WHITE
] == cbp
)
106 sortframes
[WHITE
] = cbp
->c_next
;
107 cbp
->c_next
->c_prev
= cbp
->c_prev
;
108 cbp
->c_prev
->c_next
= cbp
->c_next
;
111 /* compute old weight value for this frame */
112 cp
= &fsp
->s_fval
[BLACK
][r
];
114 val
= weight
[5 - cp
->c
.a
- cp
->c
.b
];
117 cp
= &fsp
->s_fval
[WHITE
][r
];
119 val
+= weight
[5 - cp
->c
.a
- cp
->c
.b
];
121 /* compute new combo value for this frame */
123 space
= sp
->s_occ
== EMPTY
;
125 for (i
= 5; --i
>= 0; sp
+= d
) { /* for each spot */
128 else if (sp
->s_occ
== EMPTY
)
131 /* this frame is now blocked, adjust values */
132 fsp
->s_flags
|= bmask
;
133 fsp
->s_fval
[BLACK
][r
].s
= MAXCOMBO
;
134 fsp
->s_fval
[WHITE
][r
].s
= MAXCOMBO
;
137 if (sp
->s_occ
== EMPTY
)
144 /* check for game over */
148 /* compute new value & combo number for this frame & color */
149 fsp
->s_fval
[!us
][r
].s
= MAXCOMBO
;
150 cp
= &fsp
->s_fval
[us
][r
];
151 /* both ends open? */
152 if (space
&& sp
->s_occ
== EMPTY
) {
161 for (i
= 5; --i
>= 0; sp
+= d
) /* for each spot */
162 if (sp
->s_occ
== EMPTY
)
165 /* add this frame to the sorted list of frames by combo value */
166 cbp1
= sortframes
[us
];
168 sortframes
[us
] = cbp
->c_next
= cbp
->c_prev
= cbp
;
170 cp1
= &board
[cbp1
->c_vertex
].s_fval
[us
][cbp1
->c_dir
];
171 if (cp
->s
<= cp1
->s
) {
172 /* insert at the head of the list */
173 sortframes
[us
] = cbp
;
177 cp1
= &board
[cbp1
->c_vertex
].s_fval
[us
][cbp1
->c_dir
];
180 } while (cbp1
!= sortframes
[us
]);
183 cbp
->c_prev
= cbp1
->c_prev
;
184 cbp1
->c_prev
->c_next
= cbp
;
192 /* both ends open? */
193 if (fsp
->s_occ
== EMPTY
) {
194 cp
= &fsp
->s_fval
[BLACK
][r
];
199 cp
= &fsp
->s_fval
[WHITE
][r
];
216 * fix up the overlap array due to updating spot osp.
219 update_overlap(struct spotstr
*osp
)
221 struct spotstr
*sp
, *sp1
, *sp2
;
222 int i
, f
, r
, r1
, d
, d1
, n
;
223 int a
, b
, bmask
, bmask1
;
228 for (r
= 4; --r
>= 0; ) { /* for each direction */
232 for (f
= 0; f
< 6; f
++, sp1
-= d
) { /* for each frame */
233 if (sp1
->s_occ
== BORDER
)
235 if (sp1
->s_flags
& bmask
)
238 * Update all other frames that intersect the current one
239 * to indicate whether they still overlap or not.
240 * Since F1 overlap F2 == F2 overlap F1, we only need to
241 * do the rows 0 <= r1 <= r. The r1 == r case is special
242 * since the two frames can overlap at more than one point.
244 str
= &overlap
[(a
= sp1
->s_frame
[r
] - frames
) * FAREA
];
246 for (i
= f
+ 1; i
< 6; i
++, sp2
-= d
) {
247 if (sp2
->s_occ
== BORDER
)
249 if (sp2
->s_flags
& bmask
)
252 * count the number of empty spots to see if there is
257 for (b
= i
- f
; b
< 5; b
++, sp
+= d
) {
258 if (sp
->s_occ
== EMPTY
) {
259 esp
= sp
; /* save the intersection point */
263 b
= sp2
->s_frame
[r
] - frames
;
265 if (sp
->s_occ
== EMPTY
) {
267 overlap
[b
* FAREA
+ a
] &= 0xC;
268 intersect
[a
* FAREA
+ b
] = n
= sp
- board
;
269 intersect
[b
* FAREA
+ a
] = n
;
272 overlap
[b
* FAREA
+ a
] = 0;
275 if (sp
->s_occ
== EMPTY
) {
277 overlap
[b
* FAREA
+ a
] &= 0xCF;
280 overlap
[b
* FAREA
+ a
] &= 0xF;
282 intersect
[a
* FAREA
+ b
] = n
= esp
- board
;
283 intersect
[b
* FAREA
+ a
] = n
;
285 /* else no change, still multiple overlap */
288 /* the other directions can only intersect at spot osp */
289 for (r1
= r
; --r1
>= 0; ) {
291 bmask1
= BFLAG
<< r1
;
293 for (i
= 6; --i
>= 0; sp
-= d1
) { /* for each spot */
294 if (sp
->s_occ
== BORDER
)
296 if (sp
->s_flags
& bmask1
)
298 b
= sp
->s_frame
[r1
] - frames
;
300 overlap
[b
* FAREA
+ a
] = 0;