Import of 4.4BSD-Lite2 source
This commit is contained in:
parent
e16e1de8fd
commit
193cec78aa
10
games/gomoku/Makefile
Normal file
10
games/gomoku/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 7/24/94
|
||||
|
||||
PROG= gomoku
|
||||
SRCS= bdinit.c bdisp.c main.c makemove.c pickmove.c stoc.c
|
||||
MAN6= gomoku.0
|
||||
DPADD= ${LIBCURSES} ${LIBTERM}
|
||||
LDADD= -lcurses -ltermlib
|
||||
HIDEGAME=hidegame
|
||||
|
||||
.include <bsd.prog.mk>
|
246
games/gomoku/bdinit.c
Normal file
246
games/gomoku/bdinit.c
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ralph Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)bdinit.c 8.2 (Berkeley) 5/3/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <string.h>
|
||||
#include "gomoku.h"
|
||||
|
||||
bdinit(bp)
|
||||
struct spotstr *bp;
|
||||
{
|
||||
register int i, j, r;
|
||||
register struct spotstr *sp;
|
||||
register struct combostr *cbp;
|
||||
|
||||
movenum = 1;
|
||||
|
||||
/* mark the borders as such */
|
||||
sp = bp;
|
||||
for (i = BSZ2; --i >= 0; sp++) {
|
||||
sp->s_occ = BORDER; /* top border */
|
||||
sp->s_flg = BFLAGALL;
|
||||
}
|
||||
|
||||
/* fill entire board with EMPTY spots */
|
||||
memset(frames, 0, sizeof(frames));
|
||||
cbp = frames;
|
||||
for (j = 0; ++j < BSZ1; sp++) { /* for each row */
|
||||
for (i = 0; ++i < BSZ1; sp++) { /* for each column */
|
||||
sp->s_occ = EMPTY;
|
||||
sp->s_flg = 0;
|
||||
sp->s_wval = 0;
|
||||
if (j < 5) {
|
||||
/* directions 1, 2, 3 are blocked */
|
||||
sp->s_flg |= (BFLAG << 1) | (BFLAG << 2) |
|
||||
(BFLAG << 3);
|
||||
sp->s_fval[BLACK][1].s = MAXCOMBO;
|
||||
sp->s_fval[BLACK][2].s = MAXCOMBO;
|
||||
sp->s_fval[BLACK][3].s = MAXCOMBO;
|
||||
sp->s_fval[WHITE][1].s = MAXCOMBO;
|
||||
sp->s_fval[WHITE][2].s = MAXCOMBO;
|
||||
sp->s_fval[WHITE][3].s = MAXCOMBO;
|
||||
} else if (j == 5) {
|
||||
/* five spaces, blocked on one side */
|
||||
sp->s_fval[BLACK][1].s = 0x500;
|
||||
sp->s_fval[BLACK][2].s = 0x500;
|
||||
sp->s_fval[BLACK][3].s = 0x500;
|
||||
sp->s_fval[WHITE][1].s = 0x500;
|
||||
sp->s_fval[WHITE][2].s = 0x500;
|
||||
sp->s_fval[WHITE][3].s = 0x500;
|
||||
} else {
|
||||
/* six spaces, not blocked */
|
||||
sp->s_fval[BLACK][1].s = 0x401;
|
||||
sp->s_fval[BLACK][2].s = 0x401;
|
||||
sp->s_fval[BLACK][3].s = 0x401;
|
||||
sp->s_fval[WHITE][1].s = 0x401;
|
||||
sp->s_fval[WHITE][2].s = 0x401;
|
||||
sp->s_fval[WHITE][3].s = 0x401;
|
||||
}
|
||||
if (i > (BSZ - 4)) {
|
||||
/* directions 0, 1 are blocked */
|
||||
sp->s_flg |= BFLAG | (BFLAG << 1);
|
||||
sp->s_fval[BLACK][0].s = MAXCOMBO;
|
||||
sp->s_fval[BLACK][1].s = MAXCOMBO;
|
||||
sp->s_fval[WHITE][0].s = MAXCOMBO;
|
||||
sp->s_fval[WHITE][1].s = MAXCOMBO;
|
||||
} else if (i == (BSZ - 4)) {
|
||||
sp->s_fval[BLACK][0].s = 0x500;
|
||||
sp->s_fval[WHITE][0].s = 0x500;
|
||||
/* if direction 1 is not blocked */
|
||||
if (!(sp->s_flg & (BFLAG << 1))) {
|
||||
sp->s_fval[BLACK][1].s = 0x500;
|
||||
sp->s_fval[WHITE][1].s = 0x500;
|
||||
}
|
||||
} else {
|
||||
sp->s_fval[BLACK][0].s = 0x401;
|
||||
sp->s_fval[WHITE][0].s = 0x401;
|
||||
if (i < 5) {
|
||||
/* direction 3 is blocked */
|
||||
sp->s_flg |= (BFLAG << 3);
|
||||
sp->s_fval[BLACK][3].s = MAXCOMBO;
|
||||
sp->s_fval[WHITE][3].s = MAXCOMBO;
|
||||
} else if (i == 5 &&
|
||||
!(sp->s_flg & (BFLAG << 3))) {
|
||||
sp->s_fval[BLACK][3].s = 0x500;
|
||||
sp->s_fval[WHITE][3].s = 0x500;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Allocate a frame structure for non blocked frames.
|
||||
*/
|
||||
for (r = 4; --r >= 0; ) {
|
||||
if (sp->s_flg & (BFLAG << r))
|
||||
continue;
|
||||
cbp->c_combo.s = sp->s_fval[BLACK][r].s;
|
||||
cbp->c_vertex = sp - board;
|
||||
cbp->c_nframes = 1;
|
||||
cbp->c_dir = r;
|
||||
sp->s_frame[r] = cbp;
|
||||
cbp++;
|
||||
}
|
||||
}
|
||||
sp->s_occ = BORDER; /* left & right border */
|
||||
sp->s_flg = BFLAGALL;
|
||||
}
|
||||
|
||||
/* mark the borders as such */
|
||||
for (i = BSZ1; --i >= 0; sp++) {
|
||||
sp->s_occ = BORDER; /* bottom border */
|
||||
sp->s_flg = BFLAGALL;
|
||||
}
|
||||
|
||||
sortframes[BLACK] = (struct combostr *)0;
|
||||
sortframes[WHITE] = (struct combostr *)0;
|
||||
init_overlap();
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the overlap array.
|
||||
* Each entry in the array is a bit mask with eight bits corresponding
|
||||
* to whether frame B overlaps frame A (as indexed by overlap[A * FAREA + B]).
|
||||
* The eight bits coorespond to whether A and B are open ended (length 6) or
|
||||
* closed (length 5).
|
||||
* 0 A closed and B closed
|
||||
* 1 A closed and B open
|
||||
* 2 A open and B closed
|
||||
* 3 A open and B open
|
||||
* 4 A closed and B closed and overlaps in more than one spot
|
||||
* 5 A closed and B open and overlaps in more than one spot
|
||||
* 6 A open and B closed and overlaps in more than one spot
|
||||
* 7 A open and B open and overlaps in more than one spot
|
||||
* As pieces are played, it can make frames not overlap if there are no
|
||||
* common open spaces shared between the two frames.
|
||||
*/
|
||||
init_overlap()
|
||||
{
|
||||
register struct spotstr *sp1, *sp2;
|
||||
register struct combostr *cbp;
|
||||
register int i, f, r, n, d1, d2;
|
||||
int mask, bmask, vertex, s;
|
||||
u_char *str;
|
||||
short *ip;
|
||||
|
||||
memset(overlap, 0, sizeof(overlap));
|
||||
memset(intersect, 0, sizeof(intersect));
|
||||
str = &overlap[FAREA * FAREA];
|
||||
ip = &intersect[FAREA * FAREA];
|
||||
for (cbp = frames + FAREA; --cbp >= frames; ) { /* each frame */
|
||||
str -= FAREA;
|
||||
ip -= FAREA;
|
||||
sp1 = &board[vertex = cbp->c_vertex];
|
||||
d1 = dd[r = cbp->c_dir];
|
||||
/*
|
||||
* s = 5 if closed, 6 if open.
|
||||
* At this point black & white are the same.
|
||||
*/
|
||||
s = 5 + sp1->s_fval[BLACK][r].c.b;
|
||||
/* for each spot in frame A */
|
||||
for (i = 0; i < s; i++, sp1 += d1, vertex += d1) {
|
||||
/* the sixth spot in frame A only overlaps if it is open */
|
||||
mask = (i == 5) ? 0xC : 0xF;
|
||||
/* for each direction */
|
||||
for (r = 4; --r >= 0; ) {
|
||||
bmask = BFLAG << r;
|
||||
sp2 = sp1;
|
||||
d2 = dd[r];
|
||||
/* for each frame that intersects at spot sp1 */
|
||||
for (f = 0; f < 6; f++, sp2 -= d2) {
|
||||
if (sp2->s_occ == BORDER)
|
||||
break;
|
||||
if (sp2->s_flg & bmask)
|
||||
continue;
|
||||
n = sp2->s_frame[r] - frames;
|
||||
ip[n] = vertex;
|
||||
str[n] |= (f == 5) ? mask & 0xA : mask;
|
||||
if (r == cbp->c_dir) {
|
||||
/* compute the multiple spot overlap values */
|
||||
switch (i) {
|
||||
case 0: /* sp1 is the first spot in A */
|
||||
if (f == 4)
|
||||
str[n] |= 0xA0;
|
||||
else if (f != 5)
|
||||
str[n] |= 0xF0;
|
||||
break;
|
||||
case 1: /* sp1 is the second spot in A */
|
||||
if (f == 5)
|
||||
str[n] |= 0xA0;
|
||||
else
|
||||
str[n] |= 0xF0;
|
||||
break;
|
||||
case 4: /* sp1 is the penultimate spot in A */
|
||||
if (f == 0)
|
||||
str[n] |= 0xC0;
|
||||
else
|
||||
str[n] |= 0xF0;
|
||||
break;
|
||||
case 5: /* sp1 is the last spot in A */
|
||||
if (f == 1)
|
||||
str[n] |= 0xC0;
|
||||
else if (f != 0)
|
||||
str[n] |= 0xF0;
|
||||
break;
|
||||
default:
|
||||
str[n] |= 0xF0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
275
games/gomoku/bdisp.c
Normal file
275
games/gomoku/bdisp.c
Normal file
@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ralph Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)bdisp.c 8.2 (Berkeley) 5/3/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "gomoku.h"
|
||||
#include <stdio.h>
|
||||
#include <curses.h>
|
||||
|
||||
#define SCRNH 24 /* assume 24 lines for the moment */
|
||||
#define SCRNW 80 /* assume 80 chars for the moment */
|
||||
|
||||
static int lastline;
|
||||
static char pcolor[] = "*O.?";
|
||||
|
||||
/*
|
||||
* Initialize screen display.
|
||||
*/
|
||||
cursinit()
|
||||
{
|
||||
|
||||
initscr();
|
||||
noecho();
|
||||
cbreak();
|
||||
leaveok(stdscr, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore screen display.
|
||||
*/
|
||||
cursfini()
|
||||
{
|
||||
|
||||
leaveok(stdscr, FALSE);
|
||||
move(23, 0);
|
||||
clrtoeol();
|
||||
refresh();
|
||||
endwin();
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize board display.
|
||||
*/
|
||||
bdisp_init()
|
||||
{
|
||||
register int i, j;
|
||||
|
||||
/* top border */
|
||||
for (i = 1; i < BSZ1; i++) {
|
||||
move(0, 2 * i + 1);
|
||||
addch(letters[i]);
|
||||
}
|
||||
/* left and right edges */
|
||||
for (j = BSZ1; --j > 0; ) {
|
||||
move(20 - j, 0);
|
||||
printw("%2d ", j);
|
||||
move(20 - j, 2 * BSZ1 + 1);
|
||||
printw("%d ", j);
|
||||
}
|
||||
/* bottom border */
|
||||
for (i = 1; i < BSZ1; i++) {
|
||||
move(20, 2 * i + 1);
|
||||
addch(letters[i]);
|
||||
}
|
||||
bdwho(0);
|
||||
move(0, 47);
|
||||
addstr("# black white");
|
||||
lastline = 0;
|
||||
bdisp();
|
||||
}
|
||||
|
||||
/*
|
||||
* Update who is playing whom.
|
||||
*/
|
||||
bdwho(update)
|
||||
int update;
|
||||
{
|
||||
int i;
|
||||
extern char *plyr[];
|
||||
|
||||
move(21, 0);
|
||||
clrtoeol();
|
||||
i = 6 - strlen(plyr[BLACK]) / 2;
|
||||
move(21, i > 0 ? i : 0);
|
||||
printw("BLACK/%s", plyr[BLACK]);
|
||||
i = 30 - strlen(plyr[WHITE]) / 2;
|
||||
move(21, i);
|
||||
printw("WHITE/%s", plyr[WHITE]);
|
||||
move(21, 19);
|
||||
addstr(" vs. ");
|
||||
if (update)
|
||||
refresh();
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the board display after a move.
|
||||
*/
|
||||
bdisp()
|
||||
{
|
||||
register int i, j, c;
|
||||
register struct spotstr *sp;
|
||||
|
||||
for (j = BSZ1; --j > 0; ) {
|
||||
for (i = 1; i < BSZ1; i++) {
|
||||
move(BSZ1 - j, 2 * i + 1);
|
||||
sp = &board[i + j * BSZ1];
|
||||
if (debug > 1 && sp->s_occ == EMPTY) {
|
||||
if (sp->s_flg & IFLAGALL)
|
||||
c = '+';
|
||||
else if (sp->s_flg & CFLAGALL)
|
||||
c = '-';
|
||||
else
|
||||
c = '.';
|
||||
} else
|
||||
c = pcolor[sp->s_occ];
|
||||
addch(c);
|
||||
}
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Dump board display to a file.
|
||||
*/
|
||||
bdump(fp)
|
||||
FILE *fp;
|
||||
{
|
||||
register int i, j, c;
|
||||
register struct spotstr *sp;
|
||||
|
||||
/* top border */
|
||||
fprintf(fp, " A B C D E F G H J K L M N O P Q R S T\n");
|
||||
|
||||
for (j = BSZ1; --j > 0; ) {
|
||||
/* left edge */
|
||||
fprintf(fp, "%2d ", j);
|
||||
for (i = 1; i < BSZ1; i++) {
|
||||
sp = &board[i + j * BSZ1];
|
||||
if (debug > 1 && sp->s_occ == EMPTY) {
|
||||
if (sp->s_flg & IFLAGALL)
|
||||
c = '+';
|
||||
else if (sp->s_flg & CFLAGALL)
|
||||
c = '-';
|
||||
else
|
||||
c = '.';
|
||||
} else
|
||||
c = pcolor[sp->s_occ];
|
||||
putc(c, fp);
|
||||
putc(' ', fp);
|
||||
}
|
||||
/* right edge */
|
||||
fprintf(fp, "%d\n", j);
|
||||
}
|
||||
|
||||
/* bottom border */
|
||||
fprintf(fp, " A B C D E F G H J K L M N O P Q R S T\n");
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* Display a transcript entry
|
||||
*/
|
||||
dislog(str)
|
||||
char *str;
|
||||
{
|
||||
|
||||
if (++lastline >= SCRNH - 1) {
|
||||
/* move 'em up */
|
||||
lastline = 1;
|
||||
}
|
||||
if (strlen(str) >= SCRNW - 46)
|
||||
str[SCRNW - 46 - 1] = '\0';
|
||||
move(lastline, 46);
|
||||
addstr(str);
|
||||
clrtoeol();
|
||||
move(lastline + 1, 46);
|
||||
clrtoeol();
|
||||
}
|
||||
|
||||
/*
|
||||
* Display a question.
|
||||
*/
|
||||
ask(str)
|
||||
char *str;
|
||||
{
|
||||
int len = strlen(str);
|
||||
|
||||
move(23, 0);
|
||||
addstr(str);
|
||||
clrtoeol();
|
||||
move(23, len);
|
||||
refresh();
|
||||
}
|
||||
|
||||
getline(buf, size)
|
||||
char *buf;
|
||||
int size;
|
||||
{
|
||||
register char *cp, *end;
|
||||
register int c;
|
||||
extern int interactive;
|
||||
|
||||
cp = buf;
|
||||
end = buf + size - 1; /* save room for the '\0' */
|
||||
while (cp < end && (c = getchar()) != EOF && c != '\n' && c != '\r') {
|
||||
*cp++ = c;
|
||||
if (interactive) {
|
||||
switch (c) {
|
||||
case 0x0c: /* ^L */
|
||||
wrefresh(curscr);
|
||||
cp--;
|
||||
continue;
|
||||
case 0x15: /* ^U */
|
||||
case 0x18: /* ^X */
|
||||
while (cp > buf) {
|
||||
cp--;
|
||||
addch('\b');
|
||||
}
|
||||
clrtoeol();
|
||||
break;
|
||||
case '\b':
|
||||
case 0x7f: /* DEL */
|
||||
if (cp == buf + 1) {
|
||||
cp--;
|
||||
continue;
|
||||
}
|
||||
cp -= 2;
|
||||
addch('\b');
|
||||
c = ' ';
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
addch(c);
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
*cp = '\0';
|
||||
return(c != EOF);
|
||||
}
|
92
games/gomoku/gomoku.6
Normal file
92
games/gomoku/gomoku.6
Normal file
@ -0,0 +1,92 @@
|
||||
.\" Copyright (c) 1994
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to Berkeley by
|
||||
.\" Ralph Campbell.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)gomoku.6 8.2 (Berkeley) 8/4/94
|
||||
.\"
|
||||
.Dd August 4, 1994
|
||||
.Dt GOMOKU 6
|
||||
.Os BSD 4.4
|
||||
.Sh NAME
|
||||
.Nm gomoku
|
||||
.Nd game of 5 in a row
|
||||
.Sh SYNOPSIS
|
||||
.Nm gomoku
|
||||
.Op Fl bcdu
|
||||
.Op Fl D Ar debugfile
|
||||
.Op Ar inputfile
|
||||
.Sh DESCRIPTION
|
||||
.Nm Gomoku
|
||||
is a two player game were the object is to get 5 in a row horizontally,
|
||||
vertically or diagonally on a 19 by 19 grid. By convention, black always
|
||||
moves first.
|
||||
With no arguments,
|
||||
.Nm gomoku
|
||||
will display a playing board and prompt for moves from the user.
|
||||
Valid moves are a letter for the column and a number for the row of an empty
|
||||
board location. Entering ``quit" or ``resign" will end the game.
|
||||
You can save the current state of the game by entering ``save" and
|
||||
supplying a file name when prompted.
|
||||
The optional file
|
||||
.Ar inputfile
|
||||
can be used to restore a saved game.
|
||||
.Pp
|
||||
The options are:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl b
|
||||
This option sets background mode. Input moves are read from standard input,
|
||||
the computer picks a move, and prints it to standard output. The first
|
||||
input line should be either ``black" or ``white" to specify whether
|
||||
.Nm gomoku
|
||||
has the first move or not respectively. This
|
||||
option was intended for game tournaments where a referee program handles
|
||||
the board display and pits one program against another.
|
||||
.It Fl c
|
||||
Computer verses computer.
|
||||
.Nm Gomoku
|
||||
will play a game against itself. This is mostly used for testing.
|
||||
.It Fl d
|
||||
Print debugging information. Repeating this option more than
|
||||
once yields more detailed information.
|
||||
.It Fl D Ar debugfile
|
||||
Print the debug information to
|
||||
.Ar debugfile
|
||||
instead of to the standard output.
|
||||
.It Fl u
|
||||
User verses user. This is mostly used for testing.
|
||||
.Sh AUTHOR
|
||||
Ralph Campbell
|
||||
.Sh ACKNOWLEDGEMENTS
|
||||
The board display routines were based on the
|
||||
.Nm goref
|
||||
program written by Peter Langston.
|
266
games/gomoku/gomoku.h
Normal file
266
games/gomoku/gomoku.h
Normal file
@ -0,0 +1,266 @@
|
||||
/*
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ralph Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)gomoku.h 8.2 (Berkeley) 5/3/95
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/* board dimensions */
|
||||
#define BSZ 19
|
||||
#define BSZ1 (BSZ+1)
|
||||
#define BSZ2 (BSZ+2)
|
||||
#define BAREA (BSZ2*BSZ1+1)
|
||||
|
||||
/* frame dimentions (based on 5 in a row) */
|
||||
#define FSZ1 BSZ
|
||||
#define FSZ2 (BSZ-4)
|
||||
#define FAREA (FSZ1*FSZ2 + FSZ2*FSZ2 + FSZ1*FSZ2 + FSZ2*FSZ2)
|
||||
|
||||
#define MUP (BSZ1)
|
||||
#define MDOWN (-BSZ1)
|
||||
#define MLEFT (-1)
|
||||
#define MRIGHT (1)
|
||||
|
||||
/* values for s_occ */
|
||||
#define BLACK 0
|
||||
#define WHITE 1
|
||||
#define EMPTY 2
|
||||
#define BORDER 3
|
||||
|
||||
/* return values for makemove() */
|
||||
#define MOVEOK 0
|
||||
#define RESIGN 1
|
||||
#define ILLEGAL 2
|
||||
#define WIN 3
|
||||
#define TIE 4
|
||||
#define SAVE 5
|
||||
|
||||
#define A 1
|
||||
#define B 2
|
||||
#define C 3
|
||||
#define D 4
|
||||
#define E 5
|
||||
#define F 6
|
||||
#define G 7
|
||||
#define H 8
|
||||
#define J 9
|
||||
#define K 10
|
||||
#define L 11
|
||||
#define M 12
|
||||
#define N 13
|
||||
#define O 14
|
||||
#define P 15
|
||||
#define Q 16
|
||||
#define R 17
|
||||
#define S 18
|
||||
#define T 19
|
||||
|
||||
#define PT(x,y) ((x) + BSZ1 * (y))
|
||||
|
||||
/*
|
||||
* A 'frame' is a group of five or six contiguous board locations.
|
||||
* An open ended frame is one with spaces on both ends; otherwise, its closed.
|
||||
* A 'combo' is a group of intersecting frames and consists of two numbers:
|
||||
* 'A' is the number of moves to make the combo non-blockable.
|
||||
* 'B' is the minimum number of moves needed to win once it can't be blocked.
|
||||
* A 'force' is a combo that is one move away from being non-blockable
|
||||
*
|
||||
* Single frame combo values:
|
||||
* <A,B> board values
|
||||
* 5,0 . . . . . O
|
||||
* 4,1 . . . . . .
|
||||
* 4,0 . . . . X O
|
||||
* 3,1 . . . . X .
|
||||
* 3,0 . . . X X O
|
||||
* 2,1 . . . X X .
|
||||
* 2,0 . . X X X O
|
||||
* 1,1 . . X X X .
|
||||
* 1,0 . X X X X O
|
||||
* 0,1 . X X X X .
|
||||
* 0,0 X X X X X O
|
||||
*
|
||||
* The rule for combining two combos (<A1,B1> <A2,B2>)
|
||||
* with V valid intersection points, is:
|
||||
* A' = A1 + A2 - 2 - V
|
||||
* B' = MIN(A1 + B1 - 1, A2 + B2 - 1)
|
||||
* Each time a frame is added to the combo, the number of moves to complete
|
||||
* the force is the number of moves needed to 'fill' the frame plus one at
|
||||
* the intersection point. The number of moves to win is the number of moves
|
||||
* to complete the best frame minus the last move to complete the force.
|
||||
* Note that it doesn't make sense to combine a <1,x> with anything since
|
||||
* it is already a force. Also, the frames have to be independent so a
|
||||
* single move doesn't affect more than one frame making up the combo.
|
||||
*
|
||||
* Rules for comparing which of two combos (<A1,B1> <A2,B2>) is better:
|
||||
* Both the same color:
|
||||
* <A',B'> = (A1 < A2 || A1 == A2 && B1 <= B2) ? <A1,B1> : <A2,B2>
|
||||
* We want to complete the force first, then the combo with the
|
||||
* fewest moves to win.
|
||||
* Different colors, <A1,B1> is the combo for the player with the next move:
|
||||
* <A',B'> = A2 <= 1 && (A1 > 1 || A2 + B2 < A1 + B1) ? <A2,B2> : <A1,B1>
|
||||
* We want to block only if we have to (i.e., if they are one move away
|
||||
* from completing a force and we don't have a force that we can
|
||||
* complete which takes fewer or the same number of moves to win).
|
||||
*/
|
||||
|
||||
#define MAXA 6
|
||||
#define MAXB 2
|
||||
#define MAXCOMBO 0x600
|
||||
|
||||
union comboval {
|
||||
struct {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
u_char a; /* # moves to complete force */
|
||||
u_char b; /* # moves to win */
|
||||
#endif
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
u_char b; /* # moves to win */
|
||||
u_char a; /* # moves to complete force */
|
||||
#endif
|
||||
} c;
|
||||
u_short s;
|
||||
};
|
||||
|
||||
/*
|
||||
* This structure is used to record information about single frames (F) and
|
||||
* combinations of two more frames (C).
|
||||
* For combinations of two or more frames, there is an additional
|
||||
* array of pointers to the frames of the combination which is sorted
|
||||
* by the index into the frames[] array. This is used to prevent duplication
|
||||
* since frame A combined with B is the same as B with A.
|
||||
* struct combostr *c_sort[size c_nframes];
|
||||
* The leaves of the tree (frames) are numbered 0 (bottom, leftmost)
|
||||
* to c_nframes - 1 (top, right). This is stored in c_frameindex and
|
||||
* c_dir if C_LOOP is set.
|
||||
*/
|
||||
struct combostr {
|
||||
struct combostr *c_next; /* list of combos at the same level */
|
||||
struct combostr *c_prev; /* list of combos at the same level */
|
||||
struct combostr *c_link[2]; /* C:previous level or F:NULL */
|
||||
union comboval c_linkv[2]; /* C:combo value for link[0,1] */
|
||||
union comboval c_combo; /* C:combo value for this level */
|
||||
u_short c_vertex; /* C:intersection or F:frame head */
|
||||
u_char c_nframes; /* number of frames in the combo */
|
||||
u_char c_dir; /* C:loop frame or F:frame direction */
|
||||
u_char c_flg; /* C:combo flags */
|
||||
u_char c_frameindex; /* C:intersection frame index */
|
||||
u_char c_framecnt[2]; /* number of frames left to attach */
|
||||
u_char c_emask[2]; /* C:bit mask of completion spots for
|
||||
* link[0] and link[1] */
|
||||
u_char c_voff[2]; /* C:vertex offset within frame */
|
||||
};
|
||||
|
||||
/* flag values for c_flg */
|
||||
#define C_OPEN_0 0x01 /* link[0] is an open ended frame */
|
||||
#define C_OPEN_1 0x02 /* link[1] is an open ended frame */
|
||||
#define C_LOOP 0x04 /* link[1] intersects previous frame */
|
||||
#define C_MARK 0x08 /* indicates combo processed */
|
||||
|
||||
/*
|
||||
* This structure is used for recording the completion points of
|
||||
* multi frame combos.
|
||||
*/
|
||||
struct elist {
|
||||
struct elist *e_next; /* list of completion points */
|
||||
struct combostr *e_combo; /* the whole combo */
|
||||
u_char e_off; /* offset in frame of this empty spot */
|
||||
u_char e_frameindex; /* intersection frame index */
|
||||
u_char e_framecnt; /* number of frames left to attach */
|
||||
u_char e_emask; /* real value of the frame's emask */
|
||||
union comboval e_fval; /* frame combo value */
|
||||
};
|
||||
|
||||
/*
|
||||
* One spot structure for each location on the board.
|
||||
* A frame consists of the combination for the current spot plus the five spots
|
||||
* 0: right, 1: right & down, 2: down, 3: down & left.
|
||||
*/
|
||||
struct spotstr {
|
||||
short s_occ; /* color of occupant */
|
||||
short s_wval; /* weighted value */
|
||||
int s_flg; /* flags for graph walks */
|
||||
struct combostr *s_frame[4]; /* level 1 combo for frame[dir] */
|
||||
union comboval s_fval[2][4]; /* combo value for [color][frame] */
|
||||
union comboval s_combo[2]; /* minimum combo value for BLK & WHT */
|
||||
u_char s_level[2]; /* number of frames in the min combo */
|
||||
u_char s_nforce[2]; /* number of <1,x> combos */
|
||||
struct elist *s_empty; /* level n combo completion spots */
|
||||
struct elist *s_nempty; /* level n+1 combo completion spots */
|
||||
int dummy[2]; /* XXX */
|
||||
};
|
||||
|
||||
/* flag values for s_flg */
|
||||
#define CFLAG 0x000001 /* frame is part of a combo */
|
||||
#define CFLAGALL 0x00000F /* all frame directions marked */
|
||||
#define IFLAG 0x000010 /* legal intersection point */
|
||||
#define IFLAGALL 0x0000F0 /* any intersection points? */
|
||||
#define FFLAG 0x000100 /* frame is part of a <1,x> combo */
|
||||
#define FFLAGALL 0x000F00 /* all force frames */
|
||||
#define MFLAG 0x001000 /* frame has already been seen */
|
||||
#define MFLAGALL 0x00F000 /* all frames seen */
|
||||
#define BFLAG 0x010000 /* frame intersects border or dead */
|
||||
#define BFLAGALL 0x0F0000 /* all frames dead */
|
||||
|
||||
/*
|
||||
* This structure is used to store overlap information between frames.
|
||||
*/
|
||||
struct ovlp_info {
|
||||
int o_intersect; /* intersection spot */
|
||||
struct combostr *o_fcombo; /* the connecting combo */
|
||||
u_char o_link; /* which link to update (0 or 1) */
|
||||
u_char o_off; /* offset in frame of intersection */
|
||||
u_char o_frameindex; /* intersection frame index */
|
||||
};
|
||||
|
||||
extern char *letters;
|
||||
extern char fmtbuf[];
|
||||
extern char pdir[];
|
||||
|
||||
extern int dd[4];
|
||||
extern struct spotstr board[BAREA]; /* info for board */
|
||||
extern struct combostr frames[FAREA]; /* storage for single frames */
|
||||
extern struct combostr *sortframes[2]; /* sorted, non-empty frames */
|
||||
extern u_char overlap[FAREA * FAREA]; /* frame [a][b] overlap */
|
||||
extern short intersect[FAREA * FAREA]; /* frame [a][b] intersection */
|
||||
extern int movelog[BSZ * BSZ]; /* history of moves */
|
||||
extern int movenum;
|
||||
extern int debug;
|
||||
|
||||
extern char *copy();
|
||||
extern char *stoc();
|
||||
extern char *tail();
|
||||
|
||||
#define ASSERT(x)
|
532
games/gomoku/main.c
Normal file
532
games/gomoku/main.c
Normal file
@ -0,0 +1,532 @@
|
||||
/*
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ralph Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1994\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 5/4/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <curses.h>
|
||||
#include <err.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "gomoku.h"
|
||||
|
||||
#define USER 0 /* get input from standard input */
|
||||
#define PROGRAM 1 /* get input from program */
|
||||
#define INPUTF 2 /* get input from a file */
|
||||
|
||||
int interactive = 1; /* true if interactive */
|
||||
int debug; /* true if debugging */
|
||||
int test; /* both moves come from 1: input, 2: computer */
|
||||
char *prog; /* name of program */
|
||||
FILE *debugfp; /* file for debug output */
|
||||
FILE *inputfp; /* file for debug input */
|
||||
|
||||
char pdir[4] = "-\\|/";
|
||||
char fmtbuf[128];
|
||||
|
||||
struct spotstr board[BAREA]; /* info for board */
|
||||
struct combostr frames[FAREA]; /* storage for all frames */
|
||||
struct combostr *sortframes[2]; /* sorted list of non-empty frames */
|
||||
u_char overlap[FAREA * FAREA]; /* true if frame [a][b] overlap */
|
||||
short intersect[FAREA * FAREA]; /* frame [a][b] intersection */
|
||||
int movelog[BSZ * BSZ]; /* log of all the moves */
|
||||
int movenum; /* current move number */
|
||||
char *plyr[2]; /* who's who */
|
||||
|
||||
extern void quit();
|
||||
#ifdef DEBUG
|
||||
extern void whatsup();
|
||||
#endif
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char buf[128];
|
||||
int color, curmove, i, ch;
|
||||
int input[2];
|
||||
static char *fmt[2] = {
|
||||
"%3d %-6s",
|
||||
"%3d %-6s"
|
||||
};
|
||||
|
||||
prog = strrchr(argv[0], '/');
|
||||
if (prog)
|
||||
prog++;
|
||||
else
|
||||
prog = argv[0];
|
||||
|
||||
while ((ch = getopt(argc, argv, "bcdD:u")) != EOF) {
|
||||
switch (ch) {
|
||||
case 'b': /* background */
|
||||
interactive = 0;
|
||||
break;
|
||||
case 'd': /* debugging */
|
||||
debug++;
|
||||
break;
|
||||
case 'D': /* log debug output to file */
|
||||
if ((debugfp = fopen(optarg, "w")) == NULL)
|
||||
err(1, "%s", optarg);
|
||||
break;
|
||||
case 'u': /* testing: user verses user */
|
||||
test = 1;
|
||||
break;
|
||||
case 'c': /* testing: computer verses computer */
|
||||
test = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
if (argc) {
|
||||
if ((inputfp = fopen(*argv, "r")) == NULL)
|
||||
err(1, "%s", *argv);
|
||||
}
|
||||
|
||||
if (!debug)
|
||||
#ifdef SVR4
|
||||
srand(time(0));
|
||||
#else
|
||||
srandom(time(0));
|
||||
#endif
|
||||
if (interactive)
|
||||
cursinit(); /* initialize curses */
|
||||
again:
|
||||
bdinit(board); /* initialize board contents */
|
||||
|
||||
if (interactive) {
|
||||
plyr[BLACK] = plyr[WHITE] = "???";
|
||||
bdisp_init(); /* initialize display of board */
|
||||
#ifdef DEBUG
|
||||
signal(SIGINT, whatsup);
|
||||
#else
|
||||
signal(SIGINT, quit);
|
||||
#endif
|
||||
|
||||
if (inputfp == NULL && test == 0) {
|
||||
for (;;) {
|
||||
ask("black or white? ");
|
||||
getline(buf, sizeof(buf));
|
||||
if (buf[0] == 'b' || buf[0] == 'B') {
|
||||
color = BLACK;
|
||||
break;
|
||||
}
|
||||
if (buf[0] == 'w' || buf[0] == 'W') {
|
||||
color = WHITE;
|
||||
break;
|
||||
}
|
||||
move(22, 0);
|
||||
printw("Black moves first. Please enter `black' or `white'\n");
|
||||
}
|
||||
move(22, 0);
|
||||
clrtoeol();
|
||||
}
|
||||
} else {
|
||||
setbuf(stdout, 0);
|
||||
getline(buf, sizeof(buf));
|
||||
if (strcmp(buf, "black") == 0)
|
||||
color = BLACK;
|
||||
else if (strcmp(buf, "white") == 0)
|
||||
color = WHITE;
|
||||
else {
|
||||
sprintf(fmtbuf,
|
||||
"Huh? Expected `black' or `white', got `%s'\n",
|
||||
buf);
|
||||
panic(fmtbuf);
|
||||
}
|
||||
}
|
||||
|
||||
if (inputfp) {
|
||||
input[BLACK] = INPUTF;
|
||||
input[WHITE] = INPUTF;
|
||||
} else {
|
||||
switch (test) {
|
||||
case 0: /* user verses program */
|
||||
input[color] = USER;
|
||||
input[!color] = PROGRAM;
|
||||
break;
|
||||
|
||||
case 1: /* user verses user */
|
||||
input[BLACK] = USER;
|
||||
input[WHITE] = USER;
|
||||
break;
|
||||
|
||||
case 2: /* program verses program */
|
||||
input[BLACK] = PROGRAM;
|
||||
input[WHITE] = PROGRAM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (interactive) {
|
||||
plyr[BLACK] = input[BLACK] == USER ? "you" : prog;
|
||||
plyr[WHITE] = input[WHITE] == USER ? "you" : prog;
|
||||
bdwho(1);
|
||||
}
|
||||
|
||||
for (color = BLACK; ; color = !color) {
|
||||
top:
|
||||
switch (input[color]) {
|
||||
case INPUTF: /* input comes from a file */
|
||||
curmove = readinput(inputfp);
|
||||
if (curmove != ILLEGAL)
|
||||
break;
|
||||
switch (test) {
|
||||
case 0: /* user verses program */
|
||||
input[color] = USER;
|
||||
input[!color] = PROGRAM;
|
||||
break;
|
||||
|
||||
case 1: /* user verses user */
|
||||
input[BLACK] = USER;
|
||||
input[WHITE] = USER;
|
||||
break;
|
||||
|
||||
case 2: /* program verses program */
|
||||
input[BLACK] = PROGRAM;
|
||||
input[WHITE] = PROGRAM;
|
||||
break;
|
||||
}
|
||||
plyr[BLACK] = input[BLACK] == USER ? "you" : prog;
|
||||
plyr[WHITE] = input[WHITE] == USER ? "you" : prog;
|
||||
bdwho(1);
|
||||
goto top;
|
||||
|
||||
case USER: /* input comes from standard input */
|
||||
getinput:
|
||||
if (interactive)
|
||||
ask("move? ");
|
||||
if (!getline(buf, sizeof(buf))) {
|
||||
curmove = RESIGN;
|
||||
break;
|
||||
}
|
||||
if (buf[0] == '\0')
|
||||
goto getinput;
|
||||
curmove = ctos(buf);
|
||||
if (interactive) {
|
||||
if (curmove == SAVE) {
|
||||
FILE *fp;
|
||||
|
||||
ask("save file name? ");
|
||||
(void)getline(buf, sizeof(buf));
|
||||
if ((fp = fopen(buf, "w")) == NULL) {
|
||||
log("cannot create save file");
|
||||
goto getinput;
|
||||
}
|
||||
for (i = 0; i < movenum - 1; i++)
|
||||
fprintf(fp, "%s\n",
|
||||
stoc(movelog[i]));
|
||||
fclose(fp);
|
||||
goto getinput;
|
||||
}
|
||||
if (curmove != RESIGN &&
|
||||
board[curmove].s_occ != EMPTY) {
|
||||
log("Illegal move");
|
||||
goto getinput;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PROGRAM: /* input comes from the program */
|
||||
curmove = pickmove(color);
|
||||
break;
|
||||
}
|
||||
if (interactive) {
|
||||
sprintf(fmtbuf, fmt[color], movenum, stoc(curmove));
|
||||
log(fmtbuf);
|
||||
}
|
||||
if ((i = makemove(color, curmove)) != MOVEOK)
|
||||
break;
|
||||
if (interactive)
|
||||
bdisp();
|
||||
}
|
||||
if (interactive) {
|
||||
move(22, 0);
|
||||
switch (i) {
|
||||
case WIN:
|
||||
if (input[color] == PROGRAM)
|
||||
addstr("Ha ha, I won");
|
||||
else
|
||||
addstr("Rats! you won");
|
||||
break;
|
||||
case TIE:
|
||||
addstr("Wow! its a tie");
|
||||
break;
|
||||
case ILLEGAL:
|
||||
addstr("Illegal move");
|
||||
break;
|
||||
}
|
||||
clrtoeol();
|
||||
bdisp();
|
||||
if (i != RESIGN) {
|
||||
replay:
|
||||
ask("replay? ");
|
||||
if (getline(buf, sizeof(buf)) &&
|
||||
buf[0] == 'y' || buf[0] == 'Y')
|
||||
goto again;
|
||||
if (strcmp(buf, "save") == 0) {
|
||||
FILE *fp;
|
||||
|
||||
ask("save file name? ");
|
||||
(void)getline(buf, sizeof(buf));
|
||||
if ((fp = fopen(buf, "w")) == NULL) {
|
||||
log("cannot create save file");
|
||||
goto replay;
|
||||
}
|
||||
for (i = 0; i < movenum - 1; i++)
|
||||
fprintf(fp, "%s\n",
|
||||
stoc(movelog[i]));
|
||||
fclose(fp);
|
||||
goto replay;
|
||||
}
|
||||
}
|
||||
}
|
||||
quit();
|
||||
}
|
||||
|
||||
readinput(fp)
|
||||
FILE *fp;
|
||||
{
|
||||
char *cp;
|
||||
int c;
|
||||
|
||||
cp = fmtbuf;
|
||||
while ((c = getc(fp)) != EOF && c != '\n')
|
||||
*cp++ = c;
|
||||
*cp = '\0';
|
||||
return (ctos(fmtbuf));
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Handle strange situations.
|
||||
*/
|
||||
void
|
||||
whatsup(signum)
|
||||
int signum;
|
||||
{
|
||||
int i, pnum, n, s1, s2, d1, d2;
|
||||
struct spotstr *sp;
|
||||
FILE *fp;
|
||||
char *str;
|
||||
struct elist *ep;
|
||||
struct combostr *cbp;
|
||||
|
||||
if (!interactive)
|
||||
quit();
|
||||
top:
|
||||
ask("cmd? ");
|
||||
if (!getline(fmtbuf, sizeof(fmtbuf)))
|
||||
quit();
|
||||
switch (*fmtbuf) {
|
||||
case '\0':
|
||||
goto top;
|
||||
case 'q': /* conservative quit */
|
||||
quit();
|
||||
case 'd': /* set debug level */
|
||||
debug = fmtbuf[1] - '0';
|
||||
sprintf(fmtbuf, "Debug set to %d", debug);
|
||||
dlog(fmtbuf);
|
||||
sleep(1);
|
||||
case 'c':
|
||||
break;
|
||||
case 'b': /* back up a move */
|
||||
if (movenum > 1) {
|
||||
movenum--;
|
||||
board[movelog[movenum - 1]].s_occ = EMPTY;
|
||||
bdisp();
|
||||
}
|
||||
goto top;
|
||||
case 's': /* suggest a move */
|
||||
i = fmtbuf[1] == 'b' ? BLACK : WHITE;
|
||||
sprintf(fmtbuf, "suggest %c %s", i == BLACK ? 'B' : 'W',
|
||||
stoc(pickmove(i)));
|
||||
dlog(fmtbuf);
|
||||
goto top;
|
||||
case 'f': /* go forward a move */
|
||||
board[movelog[movenum - 1]].s_occ = movenum & 1 ? BLACK : WHITE;
|
||||
movenum++;
|
||||
bdisp();
|
||||
goto top;
|
||||
case 'l': /* print move history */
|
||||
if (fmtbuf[1] == '\0') {
|
||||
for (i = 0; i < movenum - 1; i++)
|
||||
dlog(stoc(movelog[i]));
|
||||
goto top;
|
||||
}
|
||||
if ((fp = fopen(fmtbuf + 1, "w")) == NULL)
|
||||
goto top;
|
||||
for (i = 0; i < movenum - 1; i++) {
|
||||
fprintf(fp, "%s", stoc(movelog[i]));
|
||||
if (++i < movenum - 1)
|
||||
fprintf(fp, " %s\n", stoc(movelog[i]));
|
||||
else
|
||||
fputc('\n', fp);
|
||||
}
|
||||
bdump(fp);
|
||||
fclose(fp);
|
||||
goto top;
|
||||
case 'o':
|
||||
n = 0;
|
||||
for (str = fmtbuf + 1; *str; str++)
|
||||
if (*str == ',') {
|
||||
for (d1 = 0; d1 < 4; d1++)
|
||||
if (str[-1] == pdir[d1])
|
||||
break;
|
||||
str[-1] = '\0';
|
||||
sp = &board[s1 = ctos(fmtbuf + 1)];
|
||||
n = (sp->s_frame[d1] - frames) * FAREA;
|
||||
*str++ = '\0';
|
||||
break;
|
||||
}
|
||||
sp = &board[s2 = ctos(str)];
|
||||
while (*str)
|
||||
str++;
|
||||
for (d2 = 0; d2 < 4; d2++)
|
||||
if (str[-1] == pdir[d2])
|
||||
break;
|
||||
n += sp->s_frame[d2] - frames;
|
||||
str = fmtbuf;
|
||||
sprintf(str, "overlap %s%c,", stoc(s1), pdir[d1]);
|
||||
str += strlen(str);
|
||||
sprintf(str, "%s%c = %x", stoc(s2), pdir[d2], overlap[n]);
|
||||
dlog(fmtbuf);
|
||||
goto top;
|
||||
case 'p':
|
||||
sp = &board[i = ctos(fmtbuf + 1)];
|
||||
sprintf(fmtbuf, "V %s %x/%d %d %x/%d %d %d %x", stoc(i),
|
||||
sp->s_combo[BLACK].s, sp->s_level[BLACK],
|
||||
sp->s_nforce[BLACK],
|
||||
sp->s_combo[WHITE].s, sp->s_level[WHITE],
|
||||
sp->s_nforce[WHITE], sp->s_wval, sp->s_flg);
|
||||
dlog(fmtbuf);
|
||||
sprintf(fmtbuf, "FB %s %x %x %x %x", stoc(i),
|
||||
sp->s_fval[BLACK][0].s, sp->s_fval[BLACK][1].s,
|
||||
sp->s_fval[BLACK][2].s, sp->s_fval[BLACK][3].s);
|
||||
dlog(fmtbuf);
|
||||
sprintf(fmtbuf, "FW %s %x %x %x %x", stoc(i),
|
||||
sp->s_fval[WHITE][0].s, sp->s_fval[WHITE][1].s,
|
||||
sp->s_fval[WHITE][2].s, sp->s_fval[WHITE][3].s);
|
||||
dlog(fmtbuf);
|
||||
goto top;
|
||||
case 'e': /* e {b|w} [0-9] spot */
|
||||
str = fmtbuf + 1;
|
||||
if (*str >= '0' && *str <= '9')
|
||||
n = *str++ - '0';
|
||||
else
|
||||
n = 0;
|
||||
sp = &board[i = ctos(str)];
|
||||
for (ep = sp->s_empty; ep; ep = ep->e_next) {
|
||||
cbp = ep->e_combo;
|
||||
if (n) {
|
||||
if (cbp->c_nframes > n)
|
||||
continue;
|
||||
if (cbp->c_nframes != n)
|
||||
break;
|
||||
}
|
||||
printcombo(cbp, fmtbuf);
|
||||
dlog(fmtbuf);
|
||||
}
|
||||
goto top;
|
||||
default:
|
||||
syntax:
|
||||
dlog("Options are:");
|
||||
dlog("q - quit");
|
||||
dlog("c - continue");
|
||||
dlog("d# - set debug level to #");
|
||||
dlog("p# - print values at #");
|
||||
goto top;
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* Display debug info.
|
||||
*/
|
||||
dlog(str)
|
||||
char *str;
|
||||
{
|
||||
|
||||
if (debugfp)
|
||||
fprintf(debugfp, "%s\n", str);
|
||||
if (interactive)
|
||||
dislog(str);
|
||||
else
|
||||
fprintf(stderr, "%s\n", str);
|
||||
}
|
||||
|
||||
log(str)
|
||||
char *str;
|
||||
{
|
||||
|
||||
if (debugfp)
|
||||
fprintf(debugfp, "%s\n", str);
|
||||
if (interactive)
|
||||
dislog(str);
|
||||
else
|
||||
printf("%s\n", str);
|
||||
}
|
||||
|
||||
void
|
||||
quit()
|
||||
{
|
||||
if (interactive) {
|
||||
bdisp(); /* show final board */
|
||||
cursfini();
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Die gracefully.
|
||||
*/
|
||||
panic(str)
|
||||
char *str;
|
||||
{
|
||||
fprintf(stderr, "%s: %s\n", prog, str);
|
||||
fputs("resign\n", stdout);
|
||||
quit();
|
||||
}
|
301
games/gomoku/makemove.c
Normal file
301
games/gomoku/makemove.c
Normal file
@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ralph Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)makemove.c 8.2 (Berkeley) 5/3/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "gomoku.h"
|
||||
|
||||
/* direction deltas */
|
||||
int dd[4] = {
|
||||
MRIGHT, MRIGHT+MDOWN, MDOWN, MDOWN+MLEFT
|
||||
};
|
||||
|
||||
int weight[5] = { 0, 1, 7, 22, 100 };
|
||||
|
||||
/*
|
||||
* Return values:
|
||||
* MOVEOK everything is OK.
|
||||
* RESIGN Player resigned.
|
||||
* ILLEGAL Illegal move.
|
||||
* WIN The the winning move was just played.
|
||||
* TIE The game is a tie.
|
||||
*/
|
||||
makemove(us, mv)
|
||||
int us, mv;
|
||||
{
|
||||
register struct spotstr *sp, *fsp;
|
||||
register union comboval *cp;
|
||||
struct spotstr *osp;
|
||||
struct combostr *cbp, *cbp1;
|
||||
union comboval *cp1;
|
||||
register int i, f, r, d, n;
|
||||
int space, val, bmask;
|
||||
|
||||
/* check for end of game */
|
||||
if (mv == RESIGN)
|
||||
return(RESIGN);
|
||||
|
||||
/* check for illegal move */
|
||||
sp = &board[mv];
|
||||
if (sp->s_occ != EMPTY)
|
||||
return(ILLEGAL);
|
||||
|
||||
/* make move */
|
||||
sp->s_occ = us;
|
||||
movelog[movenum - 1] = mv;
|
||||
if (++movenum == BSZ * BSZ)
|
||||
return(TIE);
|
||||
|
||||
/* compute new frame values */
|
||||
sp->s_wval = 0;
|
||||
osp = sp;
|
||||
for (r = 4; --r >= 0; ) { /* for each direction */
|
||||
d = dd[r];
|
||||
fsp = osp;
|
||||
bmask = BFLAG << r;
|
||||
for (f = 5; --f >= 0; fsp -= d) { /* for each frame */
|
||||
if (fsp->s_occ == BORDER)
|
||||
goto nextr;
|
||||
if (fsp->s_flg & bmask)
|
||||
continue;
|
||||
|
||||
/* remove this frame from the sorted list of frames */
|
||||
cbp = fsp->s_frame[r];
|
||||
if (cbp->c_next) {
|
||||
if (sortframes[BLACK] == cbp)
|
||||
sortframes[BLACK] = cbp->c_next;
|
||||
if (sortframes[WHITE] == cbp)
|
||||
sortframes[WHITE] = cbp->c_next;
|
||||
cbp->c_next->c_prev = cbp->c_prev;
|
||||
cbp->c_prev->c_next = cbp->c_next;
|
||||
}
|
||||
|
||||
/* compute old weight value for this frame */
|
||||
cp = &fsp->s_fval[BLACK][r];
|
||||
if (cp->s <= 0x500)
|
||||
val = weight[5 - cp->c.a - cp->c.b];
|
||||
else
|
||||
val = 0;
|
||||
cp = &fsp->s_fval[WHITE][r];
|
||||
if (cp->s <= 0x500)
|
||||
val += weight[5 - cp->c.a - cp->c.b];
|
||||
|
||||
/* compute new combo value for this frame */
|
||||
sp = fsp;
|
||||
space = sp->s_occ == EMPTY;
|
||||
n = 0;
|
||||
for (i = 5; --i >= 0; sp += d) { /* for each spot */
|
||||
if (sp->s_occ == us)
|
||||
n++;
|
||||
else if (sp->s_occ == EMPTY)
|
||||
sp->s_wval -= val;
|
||||
else {
|
||||
/* this frame is now blocked, adjust values */
|
||||
fsp->s_flg |= bmask;
|
||||
fsp->s_fval[BLACK][r].s = MAXCOMBO;
|
||||
fsp->s_fval[WHITE][r].s = MAXCOMBO;
|
||||
while (--i >= 0) {
|
||||
sp += d;
|
||||
if (sp->s_occ == EMPTY)
|
||||
sp->s_wval -= val;
|
||||
}
|
||||
goto nextf;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for game over */
|
||||
if (n == 5)
|
||||
return(WIN);
|
||||
|
||||
/* compute new value & combo number for this frame & color */
|
||||
fsp->s_fval[!us][r].s = MAXCOMBO;
|
||||
cp = &fsp->s_fval[us][r];
|
||||
/* both ends open? */
|
||||
if (space && sp->s_occ == EMPTY) {
|
||||
cp->c.a = 4 - n;
|
||||
cp->c.b = 1;
|
||||
} else {
|
||||
cp->c.a = 5 - n;
|
||||
cp->c.b = 0;
|
||||
}
|
||||
val = weight[n];
|
||||
sp = fsp;
|
||||
for (i = 5; --i >= 0; sp += d) /* for each spot */
|
||||
if (sp->s_occ == EMPTY)
|
||||
sp->s_wval += val;
|
||||
|
||||
/* add this frame to the sorted list of frames by combo value */
|
||||
cbp1 = sortframes[us];
|
||||
if (!cbp1)
|
||||
sortframes[us] = cbp->c_next = cbp->c_prev = cbp;
|
||||
else {
|
||||
cp1 = &board[cbp1->c_vertex].s_fval[us][cbp1->c_dir];
|
||||
if (cp->s <= cp1->s) {
|
||||
/* insert at the head of the list */
|
||||
sortframes[us] = cbp;
|
||||
} else {
|
||||
do {
|
||||
cbp1 = cbp1->c_next;
|
||||
cp1 = &board[cbp1->c_vertex].s_fval[us][cbp1->c_dir];
|
||||
if (cp->s <= cp1->s)
|
||||
break;
|
||||
} while (cbp1 != sortframes[us]);
|
||||
}
|
||||
cbp->c_next = cbp1;
|
||||
cbp->c_prev = cbp1->c_prev;
|
||||
cbp1->c_prev->c_next = cbp;
|
||||
cbp1->c_prev = cbp;
|
||||
}
|
||||
|
||||
nextf:
|
||||
;
|
||||
}
|
||||
|
||||
/* both ends open? */
|
||||
if (fsp->s_occ == EMPTY) {
|
||||
cp = &fsp->s_fval[BLACK][r];
|
||||
if (cp->c.b) {
|
||||
cp->c.a += 1;
|
||||
cp->c.b = 0;
|
||||
}
|
||||
cp = &fsp->s_fval[WHITE][r];
|
||||
if (cp->c.b) {
|
||||
cp->c.a += 1;
|
||||
cp->c.b = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nextr:
|
||||
;
|
||||
}
|
||||
|
||||
update_overlap(osp);
|
||||
|
||||
return(MOVEOK);
|
||||
}
|
||||
|
||||
/*
|
||||
* fix up the overlap array due to updating spot osp.
|
||||
*/
|
||||
update_overlap(osp)
|
||||
struct spotstr *osp;
|
||||
{
|
||||
register struct spotstr *sp, *sp1, *sp2;
|
||||
register int i, f, r, r1, d, d1, n;
|
||||
int a, b, bmask, bmask1;
|
||||
struct spotstr *esp;
|
||||
char *str;
|
||||
|
||||
for (r = 4; --r >= 0; ) { /* for each direction */
|
||||
d = dd[r];
|
||||
sp1 = osp;
|
||||
bmask = BFLAG << r;
|
||||
for (f = 0; f < 6; f++, sp1 -= d) { /* for each frame */
|
||||
if (sp1->s_occ == BORDER)
|
||||
break;
|
||||
if (sp1->s_flg & bmask)
|
||||
continue;
|
||||
/*
|
||||
* Update all other frames that intersect the current one
|
||||
* to indicate whether they still overlap or not.
|
||||
* Since F1 overlap F2 == F2 overlap F1, we only need to
|
||||
* do the rows 0 <= r1 <= r. The r1 == r case is special
|
||||
* since the two frames can overlap at more than one point.
|
||||
*/
|
||||
str = &overlap[(a = sp1->s_frame[r] - frames) * FAREA];
|
||||
sp2 = sp1 - d;
|
||||
for (i = f + 1; i < 6; i++, sp2 -= d) {
|
||||
if (sp2->s_occ == BORDER)
|
||||
break;
|
||||
if (sp2->s_flg & bmask)
|
||||
continue;
|
||||
/*
|
||||
* count the number of empty spots to see if there is
|
||||
* still an overlap.
|
||||
*/
|
||||
n = 0;
|
||||
sp = sp1;
|
||||
for (b = i - f; b < 5; b++, sp += d) {
|
||||
if (sp->s_occ == EMPTY) {
|
||||
esp = sp; /* save the intersection point */
|
||||
n++;
|
||||
}
|
||||
}
|
||||
b = sp2->s_frame[r] - frames;
|
||||
if (n == 0) {
|
||||
if (sp->s_occ == EMPTY) {
|
||||
str[b] &= 0xA;
|
||||
overlap[b * FAREA + a] &= 0xC;
|
||||
intersect[a * FAREA + b] = n = sp - board;
|
||||
intersect[b * FAREA + a] = n;
|
||||
} else {
|
||||
str[b] = 0;
|
||||
overlap[b * FAREA + a] = 0;
|
||||
}
|
||||
} else if (n == 1) {
|
||||
if (sp->s_occ == EMPTY) {
|
||||
str[b] &= 0xAF;
|
||||
overlap[b * FAREA + a] &= 0xCF;
|
||||
} else {
|
||||
str[b] &= 0xF;
|
||||
overlap[b * FAREA + a] &= 0xF;
|
||||
}
|
||||
intersect[a * FAREA + b] = n = esp - board;
|
||||
intersect[b * FAREA + a] = n;
|
||||
}
|
||||
/* else no change, still multiple overlap */
|
||||
}
|
||||
|
||||
/* the other directions can only intersect at spot osp */
|
||||
for (r1 = r; --r1 >= 0; ) {
|
||||
d1 = dd[r1];
|
||||
bmask1 = BFLAG << r1;
|
||||
sp = osp;
|
||||
for (i = 6; --i >= 0; sp -= d1) { /* for each spot */
|
||||
if (sp->s_occ == BORDER)
|
||||
break;
|
||||
if (sp->s_flg & bmask1)
|
||||
continue;
|
||||
b = sp->s_frame[r1] - frames;
|
||||
str[b] = 0;
|
||||
overlap[b * FAREA + a] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1479
games/gomoku/pickmove.c
Normal file
1479
games/gomoku/pickmove.c
Normal file
File diff suppressed because it is too large
Load Diff
106
games/gomoku/stoc.c
Normal file
106
games/gomoku/stoc.c
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ralph Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)stoc.c 8.1 (Berkeley) 7/24/94";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "gomoku.h"
|
||||
#include <ctype.h>
|
||||
|
||||
char *letters = "<ABCDEFGHJKLMNOPQRST>";
|
||||
|
||||
struct mvstr {
|
||||
int m_code;
|
||||
char *m_text;
|
||||
};
|
||||
static struct mvstr mv[] = {
|
||||
RESIGN, "resign",
|
||||
RESIGN, "quit",
|
||||
SAVE, "save",
|
||||
-1, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Turn the spot number form of a move into the character form.
|
||||
*/
|
||||
char *
|
||||
stoc(s)
|
||||
int s;
|
||||
{
|
||||
static char buf[32];
|
||||
register int i;
|
||||
|
||||
for (i = 0; mv[i].m_code >= 0; i++)
|
||||
if (s == mv[i].m_code)
|
||||
return(mv[i].m_text);
|
||||
sprintf(buf, "%c%d", letters[s % BSZ1], s / BSZ1);
|
||||
return(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn the character form of a move into the spot number form.
|
||||
*/
|
||||
ctos(mp)
|
||||
char *mp;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; mv[i].m_code >= 0; i++)
|
||||
if (strcmp(mp, mv[i].m_text) == 0)
|
||||
return(mv[i].m_code);
|
||||
if (!isalpha(mp[0]))
|
||||
return(ILLEGAL);
|
||||
i = atoi(&mp[1]);
|
||||
if (i < 1 || i > 19)
|
||||
return(ILLEGAL);
|
||||
return(PT(lton(mp[0]), i));
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn a letter into a number.
|
||||
*/
|
||||
lton(c)
|
||||
int c;
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (islower(c))
|
||||
c = toupper(c);
|
||||
for (i = 1; i <= BSZ && letters[i] != c; i++)
|
||||
;
|
||||
return(i);
|
||||
}
|
Loading…
Reference in New Issue
Block a user