]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - gomoku/bdisp.c
games: remove trailing whitespace in *.c and *.h
[bsdgames-darwin.git] / gomoku / bdisp.c
1 /* $NetBSD: bdisp.c,v 1.18 2021/05/02 12:50:44 rillig Exp $ */
2
3 /*
4 * Copyright (c) 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Ralph Campbell.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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.
21 *
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
32 * SUCH DAMAGE.
33 */
34
35 #include <sys/cdefs.h>
36 #ifndef lint
37 #if 0
38 static char sccsid[] = "@(#)bdisp.c 8.2 (Berkeley) 5/3/95";
39 #else
40 __RCSID("$NetBSD: bdisp.c,v 1.18 2021/05/02 12:50:44 rillig Exp $");
41 #endif
42 #endif /* not lint */
43
44 #include <curses.h>
45 #include <string.h>
46 #include <stdlib.h>
47 #include <err.h>
48 #include "gomoku.h"
49
50 #define SCRNH 24 /* assume 24 lines for the moment */
51 #define SCRNW 80 /* assume 80 chars for the moment */
52
53 static int lastline;
54 static char pcolor[] = "*O.?";
55
56 /*
57 * Initialize screen display.
58 */
59 void
60 cursinit(void)
61 {
62
63 if (!initscr()) {
64 errx(EXIT_FAILURE, "Couldn't initialize screen");
65 }
66 if ((LINES < SCRNH) || (COLS < SCRNW)) {
67 errx(EXIT_FAILURE, "Screen too small (need %d%xd)",
68 SCRNW, SCRNH);
69 }
70 keypad(stdscr, TRUE);
71 nonl();
72 noecho();
73 cbreak();
74 leaveok(stdscr, FALSE);
75
76 #if 0 /* no mouse support in netbsd curses yet */
77 mousemask(BUTTON1_CLICKED, NULL);
78 #endif
79 }
80
81 /*
82 * Restore screen display.
83 */
84 void
85 cursfini(void)
86 {
87
88 move(BSZ4, 0);
89 clrtoeol();
90 refresh();
91 echo();
92 endwin();
93 }
94
95 /*
96 * Initialize board display.
97 */
98 void
99 bdisp_init(void)
100 {
101 int i, j;
102
103 /* top border */
104 for (i = 1; i < BSZ1; i++) {
105 move(0, 2 * i + 1);
106 addch(letters[i]);
107 }
108 /* left and right edges */
109 for (j = BSZ1; --j > 0; ) {
110 move(20 - j, 0);
111 printw("%2d ", j);
112 move(20 - j, 2 * BSZ1 + 1);
113 printw("%d ", j);
114 }
115 /* bottom border */
116 for (i = 1; i < BSZ1; i++) {
117 move(20, 2 * i + 1);
118 addch(letters[i]);
119 }
120 bdwho(0);
121 move(0, 47);
122 addstr("# black white");
123 lastline = 0;
124 bdisp();
125 }
126
127 /*
128 * Update who is playing whom.
129 */
130 void
131 bdwho(int update)
132 {
133 int i, j;
134
135 move(21, 0);
136 printw(" ");
137 i = strlen(plyr[BLACK]);
138 j = strlen(plyr[WHITE]);
139 if (i + j <= 20) {
140 move(21, 10 - (i+j)/2);
141 printw("BLACK/%s (*) vs. WHITE/%s (O)",
142 plyr[BLACK], plyr[WHITE]);
143 } else {
144 move(21, 0);
145 if (i <= 10) {
146 j = 20 - i;
147 } else if (j <= 10) {
148 i = 20 - j;
149 } else {
150 i = j = 10;
151 }
152 printw("BLACK/%.*s (*) vs. WHITE/%.*s (O)",
153 i, plyr[BLACK], j, plyr[WHITE]);
154 }
155 if (update)
156 refresh();
157 }
158
159 /*
160 * Update the board display after a move.
161 */
162 void
163 bdisp(void)
164 {
165 int i, j, c;
166 struct spotstr *sp;
167
168 for (j = BSZ1; --j > 0; ) {
169 for (i = 1; i < BSZ1; i++) {
170 move(BSZ1 - j, 2 * i + 1);
171 sp = &board[i + j * BSZ1];
172 if (debug > 1 && sp->s_occ == EMPTY) {
173 if (sp->s_flags & IFLAGALL)
174 c = '+';
175 else if (sp->s_flags & CFLAGALL)
176 c = '-';
177 else
178 c = '.';
179 } else
180 c = pcolor[sp->s_occ];
181 addch(c);
182 }
183 }
184 refresh();
185 }
186
187 #ifdef DEBUG
188 /*
189 * Dump board display to a file.
190 */
191 void
192 bdump(FILE *fp)
193 {
194 int i, j, c;
195 struct spotstr *sp;
196
197 /* top border */
198 fprintf(fp, " A B C D E F G H J K L M N O P Q R S T\n");
199
200 for (j = BSZ1; --j > 0; ) {
201 /* left edge */
202 fprintf(fp, "%2d ", j);
203 for (i = 1; i < BSZ1; i++) {
204 sp = &board[i + j * BSZ1];
205 if (debug > 1 && sp->s_occ == EMPTY) {
206 if (sp->s_flags & IFLAGALL)
207 c = '+';
208 else if (sp->s_flags & CFLAGALL)
209 c = '-';
210 else
211 c = '.';
212 } else
213 c = pcolor[sp->s_occ];
214 putc(c, fp);
215 putc(' ', fp);
216 }
217 /* right edge */
218 fprintf(fp, "%d\n", j);
219 }
220
221 /* bottom border */
222 fprintf(fp, " A B C D E F G H J K L M N O P Q R S T\n");
223 }
224 #endif /* DEBUG */
225
226 /*
227 * Display a transcript entry
228 */
229 void
230 dislog(const char *str)
231 {
232
233 if (++lastline >= SCRNH - 1) {
234 /* move 'em up */
235 lastline = 1;
236 }
237 move(lastline, TRANSCRIPT_COL);
238 addnstr(str, SCRNW - TRANSCRIPT_COL - 1);
239 clrtoeol();
240 move(lastline + 1, TRANSCRIPT_COL);
241 clrtoeol();
242 }
243
244 /*
245 * Display a question.
246 */
247
248 void
249 ask(const char *str)
250 {
251 int len = strlen(str);
252
253 move(BSZ4, 0);
254 addstr(str);
255 clrtoeol();
256 move(BSZ4, len);
257 refresh();
258 }
259
260 int
261 get_key(const char *allowed)
262 {
263 int ch;
264
265 while (1) {
266 ch = getch();
267 if (allowed != NULL &&
268 ch != '\0' && strchr(allowed, ch) == NULL) {
269 beep();
270 refresh();
271 continue;
272 }
273 break;
274 }
275 return ch;
276 }
277
278 int
279 get_line(char *buf, int size)
280 {
281 char *cp, *end;
282 int c;
283
284 c = 0;
285 cp = buf;
286 end = buf + size - 1; /* save room for the '\0' */
287 while (cp < end && (c = getchar()) != EOF && c != '\n' && c != '\r') {
288 *cp++ = c;
289 if (interactive) {
290 switch (c) {
291 case 0x0c: /* ^L */
292 wrefresh(curscr);
293 cp--;
294 continue;
295 case 0x15: /* ^U */
296 case 0x18: /* ^X */
297 while (cp > buf) {
298 cp--;
299 addch('\b');
300 }
301 clrtoeol();
302 break;
303 case '\b':
304 case 0x7f: /* DEL */
305 if (cp == buf + 1) {
306 cp--;
307 continue;
308 }
309 cp -= 2;
310 addch('\b');
311 c = ' ';
312 /* FALLTHROUGH */
313 default:
314 addch(c);
315 }
316 refresh();
317 }
318 }
319 *cp = '\0';
320 return(c != EOF);
321 }
322
323 /*
324 * Decent (n)curses interface for the game, based on Eric S. Raymond's
325 * modifications to the battleship (bs) user interface.
326 */
327 int
328 get_coord(void)
329 {
330 static int curx = BSZ / 2;
331 static int cury = BSZ / 2;
332 int ny, nx, ch;
333
334 BGOTO(cury, curx);
335 refresh();
336 nx = curx;
337 ny = cury;
338 for (;;) {
339 mvprintw(BSZ3, (BSZ -6)/2, "(%c %d) ",
340 'A'+ ((curx > 7) ? (curx+1) : curx), cury + 1);
341 BGOTO(cury, curx);
342
343 ch = getch();
344 switch (ch) {
345 case 'k':
346 case '8':
347 case KEY_UP:
348 nx = curx;
349 ny = cury + 1;
350 break;
351 case 'j':
352 case '2':
353 case KEY_DOWN:
354 nx = curx;
355 ny = BSZ + cury - 1;
356 break;
357 case 'h':
358 case '4':
359 case KEY_LEFT:
360 nx = BSZ + curx - 1;
361 ny = cury;
362 break;
363 case 'l':
364 case '6':
365 case KEY_RIGHT:
366 nx = curx + 1;
367 ny = cury;
368 break;
369 case 'y':
370 case '7':
371 case KEY_A1:
372 nx = BSZ + curx - 1;
373 ny = cury + 1;
374 break;
375 case 'b':
376 case '1':
377 case KEY_C1:
378 nx = BSZ + curx - 1;
379 ny = BSZ + cury - 1;
380 break;
381 case 'u':
382 case '9':
383 case KEY_A3:
384 nx = curx + 1;
385 ny = cury + 1;
386 break;
387 case 'n':
388 case '3':
389 case KEY_C3:
390 nx = curx + 1;
391 ny = BSZ + cury - 1;
392 break;
393 case 'K':
394 nx = curx;
395 ny = cury + 5;
396 break;
397 case 'J':
398 nx = curx;
399 ny = BSZ + cury - 5;
400 break;
401 case 'H':
402 nx = BSZ + curx - 5;
403 ny = cury;
404 break;
405 case 'L':
406 nx = curx + 5;
407 ny = cury;
408 break;
409 case 'Y':
410 nx = BSZ + curx - 5;
411 ny = cury + 5;
412 break;
413 case 'B':
414 nx = BSZ + curx - 5;
415 ny = BSZ + cury - 5;
416 break;
417 case 'U':
418 nx = curx + 5;
419 ny = cury + 5;
420 break;
421 case 'N':
422 nx = curx + 5;
423 ny = BSZ + cury - 5;
424 break;
425 case '\f':
426 nx = curx;
427 ny = cury;
428 (void)clearok(stdscr, TRUE);
429 (void)refresh();
430 break;
431 #if 0 /* notyet */
432 case KEY_MOUSE:
433 {
434 MEVENT myevent;
435
436 getmouse(&myevent);
437 if (myevent.y >= 1 && myevent.y <= BSZ1 &&
438 myevent.x >= 3 && myevent.x <= (2 * BSZ + 1)) {
439 curx = (myevent.x - 3) / 2;
440 cury = BSZ - myevent.y;
441 return PT(curx,cury);
442 } else {
443 beep();
444 }
445 }
446 break;
447 #endif /* 0 */
448 case 'Q':
449 case 'q':
450 return RESIGN;
451 break;
452 case 'S':
453 case 's':
454 return SAVE;
455 break;
456 case ' ':
457 case '\r':
458 (void) mvaddstr(BSZ3, (BSZ -6)/2, " ");
459 return PT(curx+1,cury+1);
460 break;
461 }
462
463 curx = nx % BSZ;
464 cury = ny % BSZ;
465 }
466 }