]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - gomoku/main.c
1 /* $NetBSD: main.c,v 1.27 2016/06/12 02:15:26 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>
37 __COPYRIGHT("@(#) Copyright (c) 1994\
38 The Regents of the University of California. All rights reserved.");
43 static char sccsid
[] = "@(#)main.c 8.4 (Berkeley) 5/4/95";
45 __RCSID("$NetBSD: main.c,v 1.27 2016/06/12 02:15:26 dholland Exp $");
61 #define USER 0 /* get input from standard input */
62 #define PROGRAM 1 /* get input from program */
63 #define INPUTF 2 /* get input from a file */
65 #define LOGIN_NAME_MAX 73
67 int interactive
= 1; /* true if interactive */
68 int debug
; /* true if debugging */
69 static int test
; /* both moves come from 1: input, 2: computer */
70 static char *prog
; /* name of program */
71 static char user
[LOGIN_NAME_MAX
]; /* name of player */
72 static FILE *debugfp
; /* file for debug output */
73 static FILE *inputfp
; /* file for debug input */
75 const char pdir
[4] = "-\\|/";
77 struct spotstr board
[BAREA
]; /* info for board */
78 struct combostr frames
[FAREA
]; /* storage for all frames */
79 struct combostr
*sortframes
[2]; /* sorted list of non-empty frames */
80 u_char overlap
[FAREA
* FAREA
]; /* true if frame [a][b] overlap */
81 short intersect
[FAREA
* FAREA
]; /* frame [a][b] intersection */
82 int movelog
[BSZ
* BSZ
]; /* log of all the moves */
83 int movenum
; /* current move number */
84 const char *plyr
[2]; /* who's who */
86 static int readinput(FILE *);
87 static void misclog(const char *, ...) __printflike(1, 2);
88 static void quit(void) __dead
;
89 static void quitsig(int) __dead
;
92 main(int argc
, char **argv
)
97 int color
, curmove
, i
, ch
;
100 /* Revoke setgid privileges */
105 strlcpy(user
, tmp
, sizeof(user
));
112 prog
= strrchr(argv
[0], '/');
118 while ((ch
= getopt(argc
, argv
, "bcdD:u")) != -1) {
120 case 'b': /* background */
123 case 'd': /* debugging */
126 case 'D': /* log debug output to file */
127 if ((debugfp
= fopen(optarg
, "w")) == NULL
)
128 err(1, "%s", optarg
);
130 case 'u': /* testing: user versus user */
133 case 'c': /* testing: computer versus computer */
141 if ((inputfp
= fopen(*argv
, "r")) == NULL
)
148 cursinit(); /* initialize curses */
150 bdinit(board
); /* initialize board contents */
153 plyr
[BLACK
] = plyr
[WHITE
] = "???";
154 bdisp_init(); /* initialize display of board */
156 signal(SIGINT
, whatsup
);
158 signal(SIGINT
, quitsig
);
161 if (inputfp
== NULL
&& test
== 0) {
163 printw("Black moves first. ");
164 ask("(B)lack or (W)hite? ");
167 if (ch
== 'b' || ch
== 'B') {
171 if (ch
== 'w' || ch
== 'W') {
175 if (ch
== 'q' || ch
== 'Q') {
179 ask("Please choose (B)lack or (W)hite: ");
186 get_line(buf
, sizeof(buf
));
187 if (strcmp(buf
, "black") == 0)
189 else if (strcmp(buf
, "white") == 0)
192 panic("Huh? Expected `black' or `white', got `%s'\n",
198 input
[BLACK
] = INPUTF
;
199 input
[WHITE
] = INPUTF
;
202 case 0: /* user versus program */
204 input
[!color
] = PROGRAM
;
207 case 1: /* user versus user */
212 case 2: /* program versus program */
213 input
[BLACK
] = PROGRAM
;
214 input
[WHITE
] = PROGRAM
;
219 plyr
[BLACK
] = input
[BLACK
] == USER
? user
: prog
;
220 plyr
[WHITE
] = input
[WHITE
] == USER
? user
: prog
;
224 for (color
= BLACK
; ; color
= !color
) {
226 switch (input
[color
]) {
227 case INPUTF
: /* input comes from a file */
228 curmove
= readinput(inputfp
);
229 if (curmove
!= ILLEGAL
)
232 case 0: /* user versus program */
234 input
[!color
] = PROGRAM
;
237 case 1: /* user versus user */
242 case 2: /* program versus program */
243 input
[BLACK
] = PROGRAM
;
244 input
[WHITE
] = PROGRAM
;
247 plyr
[BLACK
] = input
[BLACK
] == USER
? user
: prog
;
248 plyr
[WHITE
] = input
[WHITE
] == USER
? user
: prog
;
252 case USER
: /* input comes from standard input */
255 ask("Select move, (S)ave or (Q)uit.");
256 curmove
= get_coord();
257 if (curmove
== SAVE
) {
260 ask("Save file name? ");
261 (void)get_line(fname
, sizeof(fname
));
262 if ((fp
= fopen(fname
, "w")) == NULL
) {
263 misclog("cannot create save file");
266 for (i
= 0; i
< movenum
- 1; i
++)
272 if (curmove
!= RESIGN
&&
273 board
[curmove
].s_occ
!= EMPTY
) {
274 /*misclog("Illegal move");*/
279 if (!get_line(buf
, sizeof(buf
))) {
289 case PROGRAM
: /* input comes from the program */
292 curmove
= pickmove(color
);
296 misclog("%3d%s%-6s", movenum
, color
? " " : " ",
299 if ((i
= makemove(color
, curmove
)) != MOVEOK
)
308 if (input
[color
] == PROGRAM
)
309 addstr("Ha ha, I won");
310 else if (input
[0] == USER
&& input
[1] == USER
)
311 addstr("Well, you won (and lost)");
313 addstr("Rats! you won");
316 addstr("Wow! It's a tie");
319 addstr("Illegal move");
327 ch
= get_key("YyNnQqSs");
328 if (ch
== 'Y' || ch
== 'y')
333 ask("Save file name? ");
334 (void)get_line(fname
, sizeof(fname
));
335 if ((fp
= fopen(fname
, "w")) == NULL
) {
336 misclog("cannot create save file");
339 for (i
= 0; i
< movenum
- 1; i
++)
360 while ((c
= getc(fp
)) != EOF
&& c
!= '\n' && pos
< sizeof(buf
) - 1)
368 * Handle strange situations.
373 int i
, n
, s1
, s2
, d1
, d2
;
378 struct combostr
*cbp
;
385 ask("debug command: ");
386 if (!get_line(input
, sizeof(input
)))
391 case 'q': /* conservative quit */
393 case 'd': /* set debug level */
394 debug
= input
[1] - '0';
395 debuglog("Debug set to %d", debug
);
399 case 'b': /* back up a move */
402 board
[movelog
[movenum
- 1]].s_occ
= EMPTY
;
406 case 's': /* suggest a move */
407 i
= input
[1] == 'b' ? BLACK
: WHITE
;
408 debuglog("suggest %c %s", i
== BLACK
? 'B' : 'W',
411 case 'f': /* go forward a move */
412 board
[movelog
[movenum
- 1]].s_occ
= movenum
& 1 ? BLACK
: WHITE
;
416 case 'l': /* print move history */
417 if (input
[1] == '\0') {
418 for (i
= 0; i
< movenum
- 1; i
++)
419 debuglog("%s", stoc(movelog
[i
]));
422 if ((fp
= fopen(input
+ 1, "w")) == NULL
)
424 for (i
= 0; i
< movenum
- 1; i
++) {
425 fprintf(fp
, "%s", stoc(movelog
[i
]));
426 if (++i
< movenum
- 1)
427 fprintf(fp
, " %s\n", stoc(movelog
[i
]));
435 /* avoid use w/o initialization on invalid input */
439 for (str
= input
+ 1; *str
; str
++)
441 for (d1
= 0; d1
< 4; d1
++)
442 if (str
[-1] == pdir
[d1
])
445 sp
= &board
[s1
= ctos(input
+ 1)];
446 n
= (sp
->s_frame
[d1
] - frames
) * FAREA
;
450 sp
= &board
[s2
= ctos(str
)];
453 for (d2
= 0; d2
< 4; d2
++)
454 if (str
[-1] == pdir
[d2
])
456 n
+= sp
->s_frame
[d2
] - frames
;
457 debuglog("overlap %s%c,%s%c = %x", stoc(s1
), pdir
[d1
],
458 stoc(s2
), pdir
[d2
], overlap
[n
]);
461 sp
= &board
[i
= ctos(input
+ 1)];
462 debuglog("V %s %x/%d %d %x/%d %d %d %x", stoc(i
),
463 sp
->s_combo
[BLACK
].s
, sp
->s_level
[BLACK
],
465 sp
->s_combo
[WHITE
].s
, sp
->s_level
[WHITE
],
466 sp
->s_nforce
[WHITE
], sp
->s_wval
, sp
->s_flags
);
467 debuglog("FB %s %x %x %x %x", stoc(i
),
468 sp
->s_fval
[BLACK
][0].s
, sp
->s_fval
[BLACK
][1].s
,
469 sp
->s_fval
[BLACK
][2].s
, sp
->s_fval
[BLACK
][3].s
);
470 debuglog("FW %s %x %x %x %x", stoc(i
),
471 sp
->s_fval
[WHITE
][0].s
, sp
->s_fval
[WHITE
][1].s
,
472 sp
->s_fval
[WHITE
][2].s
, sp
->s_fval
[WHITE
][3].s
);
474 case 'e': /* e {b|w} [0-9] spot */
476 if (*str
>= '0' && *str
<= '9')
480 sp
= &board
[i
= ctos(str
)];
481 for (ep
= sp
->s_empty
; ep
; ep
= ep
->e_next
) {
484 if (cbp
->c_nframes
> n
)
486 if (cbp
->c_nframes
!= n
)
489 printcombo(cbp
, tmp
, sizeof(tmp
));
494 debuglog("Options are:");
495 debuglog("q - quit");
496 debuglog("c - continue");
497 debuglog("d# - set debug level to #");
498 debuglog("p# - print values at #");
505 * Display debug info.
508 debuglog(const char *fmt
, ...)
514 vsnprintf(buf
, sizeof(buf
), fmt
, ap
);
518 fprintf(debugfp
, "%s\n", buf
);
522 fprintf(stderr
, "%s\n", buf
);
526 misclog(const char *fmt
, ...)
532 vsnprintf(buf
, sizeof(buf
), fmt
, ap
);
536 fprintf(debugfp
, "%s\n", buf
);
547 bdisp(); /* show final board */
554 quitsig(int dummy __unused
)
563 panic(const char *fmt
, ...)
572 fprintf(stderr
, "%s: ", prog
);
574 vfprintf(stderr
, fmt
, ap
);
576 fprintf(stderr
, "\n");
578 fputs("I resign\n", stdout
);