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