1 /* $OpenBSD: bdisp.c,v 1.13 2016/01/08 21:38:33 mestre Exp $ */
2 /*
3 * Copyright (c) 1994
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Ralph Campbell.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include <curses.h>
35 #include <err.h>
36 #include <string.h>
37
38 #include "gomoku.h"
39
40 #define SCRNH 24 /* assume 24 lines for the moment */
41 #define SCRNW 80 /* assume 80 chars for the moment */
42
43 static int lastline;
44 static char pcolor[] = "*O.?";
45
46 /*
47 * Initialize screen display.
48 */
49 void
cursinit(void)50 cursinit(void)
51 {
52 initscr();
53 if ((LINES < SCRNH) || (COLS < SCRNW)) {
54 endwin();
55 errx(1,"Screen too small (need %dx%d)",SCRNW,SCRNH);
56 }
57 #ifdef KEY_MIN
58 keypad(stdscr, TRUE);
59 #endif /* KEY_MIN */
60 nonl();
61 noecho();
62 cbreak();
63
64 #ifdef NCURSES_MOUSE_VERSION
65 mousemask(BUTTON1_CLICKED, (mmask_t *)NULL);
66 #endif /* NCURSES_MOUSE_VERSION*/
67 }
68
69 /*
70 * Restore screen display.
71 */
72 void
cursfini(void)73 cursfini(void)
74 {
75 move(BSZ4, 0);
76 clrtoeol();
77 refresh();
78 echo();
79 endwin();
80 }
81
82 /*
83 * Initialize board display.
84 */
85 void
bdisp_init(void)86 bdisp_init(void)
87 {
88 int i, j;
89
90 /* top border */
91 for (i = 1; i < BSZ1; i++) {
92 move(0, 2 * i + 1);
93 addch(letters[i]);
94 }
95 /* left and right edges */
96 for (j = BSZ1; --j > 0; ) {
97 move(20 - j, 0);
98 printw("%2d ", j);
99 move(20 - j, 2 * BSZ1 + 1);
100 printw("%d ", j);
101 }
102 /* bottom border */
103 for (i = 1; i < BSZ1; i++) {
104 move(20, 2 * i + 1);
105 addch(letters[i]);
106 }
107 bdwho(0);
108 move(0, 47);
109 addstr("# black white");
110 lastline = 0;
111 bdisp();
112 }
113
114 /*
115 * Update who is playing whom.
116 */
117 void
bdwho(int update)118 bdwho(int update)
119 {
120 int i, j;
121 extern char *plyr[];
122
123 move(21, 0);
124 printw(" ");
125 i = strlen(plyr[BLACK]);
126 j = strlen(plyr[WHITE]);
127 if (i + j <= 20) {
128 move(21, 10 - (i + j)/2);
129 printw("BLACK/%s (*) vs. WHITE/%s (O)",
130 plyr[BLACK], plyr[WHITE]);
131 } else {
132 move(21, 0);
133 if (i <= 10)
134 j = 20 - i;
135 else if (j <= 10)
136 i = 20 - j;
137 else
138 i = j = 10;
139 printw("BLACK/%.*s (*) vs. WHITE/%.*s (O)",
140 i, plyr[BLACK], j, plyr[WHITE]);
141 }
142 if (update)
143 refresh();
144 }
145
146 /*
147 * Update the board display after a move.
148 */
149 void
bdisp(void)150 bdisp(void)
151 {
152 int i, j, c;
153 struct spotstr *sp;
154
155 for (j = BSZ1; --j > 0; ) {
156 for (i = 1; i < BSZ1; i++) {
157 move(BSZ1 - j, 2 * i + 1);
158 sp = &board[i + j * BSZ1];
159 if (debug > 1 && sp->s_occ == EMPTY) {
160 if (sp->s_flg & IFLAGALL)
161 c = '+';
162 else if (sp->s_flg & CFLAGALL)
163 c = '-';
164 else
165 c = '.';
166 } else
167 c = pcolor[sp->s_occ];
168 addch(c);
169 }
170 }
171 refresh();
172 }
173
174 #ifdef DEBUG
175 /*
176 * Dump board display to a file.
177 */
bdump(FILE * fp)178 void bdump(FILE *fp)
179 {
180 int i, j, c;
181 struct spotstr *sp;
182
183 /* top border */
184 fprintf(fp, " A B C D E F G H J K L M N O P Q R S T\n");
185
186 for (j = BSZ1; --j > 0; ) {
187 /* left edge */
188 fprintf(fp, "%2d ", j);
189 for (i = 1; i < BSZ1; i++) {
190 sp = &board[i + j * BSZ1];
191 if (debug > 1 && sp->s_occ == EMPTY) {
192 if (sp->s_flg & IFLAGALL)
193 c = '+';
194 else if (sp->s_flg & CFLAGALL)
195 c = '-';
196 else
197 c = '.';
198 } else
199 c = pcolor[sp->s_occ];
200 putc(c, fp);
201 putc(' ', fp);
202 }
203 /* right edge */
204 fprintf(fp, "%d\n", j);
205 }
206
207 /* bottom border */
208 fprintf(fp, " A B C D E F G H J K L M N O P Q R S T\n");
209 }
210 #endif /* DEBUG */
211
212 /*
213 * Display a transcript entry
214 */
215 void
dislog(char * str)216 dislog(char *str)
217 {
218
219 if (++lastline >= SCRNH - 1) {
220 /* move 'em up */
221 lastline = 1;
222 }
223 if (strlen(str) >= SCRNW - (2 * BSZ4))
224 str[SCRNW - (2 * BSZ4) - 1] = '\0';
225 move(lastline, (2 * BSZ4));
226 addstr(str);
227 clrtoeol();
228 move(lastline + 1, (2 * BSZ4));
229 clrtoeol();
230 }
231
232 /*
233 * Display a question.
234 */
235 void
ask(char * str)236 ask(char *str)
237 {
238 int len = strlen(str);
239
240 move(BSZ4, 0);
241 addstr(str);
242 clrtoeol();
243 move(BSZ4, len);
244 refresh();
245 }
246
247 int
get_line(char * buf,int size)248 get_line(char *buf, int size)
249 {
250 char *cp, *end;
251 int c = EOF;
252 extern int interactive;
253
254 cp = buf;
255 end = buf + size - 1; /* save room for the '\0' */
256 while (cp < end && (c = getchar()) != EOF && c != '\n' && c != '\r') {
257 *cp++ = c;
258 if (interactive) {
259 switch (c) {
260 case 0x0c: /* ^L */
261 wrefresh(curscr);
262 cp--;
263 continue;
264 case 0x15: /* ^U */
265 case 0x18: /* ^X */
266 while (cp > buf) {
267 cp--;
268 addch('\b');
269 }
270 clrtoeol();
271 break;
272 case '\b':
273 case 0x7f: /* DEL */
274 if (cp == buf + 1) {
275 cp--;
276 continue;
277 }
278 cp -= 2;
279 addch('\b');
280 c = ' ';
281 /* FALLTHROUGH */
282 default:
283 addch(c);
284 }
285 refresh();
286 }
287 }
288 *cp = '\0';
289 return(c != EOF);
290 }
291
292
293 /* Decent (n)curses interface for the game, based on Eric S. Raymond's
294 * modifications to the battleship (bs) user interface.
295 */
getcoord(void)296 int getcoord(void)
297 {
298 static int curx = BSZ / 2;
299 static int cury = BSZ / 2;
300 int ny, nx, c;
301
302 BGOTO(cury,curx);
303 refresh();
304 nx = curx; ny = cury;
305 for (;;) {
306 mvprintw(BSZ3, (BSZ -6)/2, "(%c %d)",
307 'A'+ ((curx > 7) ? (curx+1) : curx), cury + 1);
308 BGOTO(cury, curx);
309
310 switch(c = getch()) {
311 case 'k': case '8':
312 #ifdef KEY_MIN
313 case KEY_UP:
314 #endif /* KEY_MIN */
315 ny = cury + 1; nx = curx;
316 break;
317 case 'j': case '2':
318 #ifdef KEY_MIN
319 case KEY_DOWN:
320 #endif /* KEY_MIN */
321 ny = BSZ + cury - 1; nx = curx;
322 break;
323 case 'h': case '4':
324 #ifdef KEY_MIN
325 case KEY_LEFT:
326 #endif /* KEY_MIN */
327 ny = cury; nx = BSZ + curx - 1;
328 break;
329 case 'l': case '6':
330 #ifdef KEY_MIN
331 case KEY_RIGHT:
332 #endif /* KEY_MIN */
333 ny = cury; nx = curx + 1;
334 break;
335 case 'y': case '7':
336 #ifdef KEY_MIN
337 case KEY_A1:
338 #endif /* KEY_MIN */
339 ny = cury + 1; nx = BSZ + curx - 1;
340 break;
341 case 'b': case '1':
342 #ifdef KEY_MIN
343 case KEY_C1:
344 #endif /* KEY_MIN */
345 ny = BSZ + cury - 1; nx = BSZ + curx - 1;
346 break;
347 case 'u': case '9':
348 #ifdef KEY_MIN
349 case KEY_A3:
350 #endif /* KEY_MIN */
351 ny = cury + 1; nx = curx + 1;
352 break;
353 case 'n': case '3':
354 #ifdef KEY_MIN
355 case KEY_C3:
356 #endif /* KEY_MIN */
357 ny = BSZ + cury - 1; nx = curx + 1;
358 break;
359 case 'K':
360 ny = cury + 5; nx = curx;
361 break;
362 case 'J':
363 ny = BSZ + cury - 5; nx = curx;
364 break;
365 case 'H':
366 ny = cury; nx = BSZ + curx - 5;
367 break;
368 case 'L':
369 ny = cury; nx = curx + 5;
370 break;
371 case 'Y':
372 ny = cury + 5; nx = BSZ + curx - 5;
373 break;
374 case 'B':
375 ny = BSZ + cury - 5; nx = BSZ + curx - 5;
376 break;
377 case 'U':
378 ny = cury + 5; nx = curx + 5;
379 break;
380 case 'N':
381 ny = BSZ + cury - 5; nx = curx + 5;
382 break;
383 case FF:
384 nx = curx; ny = cury;
385 (void)clearok(stdscr, TRUE);
386 (void)refresh();
387 break;
388 #ifdef NCURSES_MOUSE_VERSION
389 case KEY_MOUSE:
390 {
391 MEVENT myevent;
392
393 getmouse(&myevent);
394 if (myevent.y >= 1 && myevent.y <= BSZ1
395 && myevent.x >= 3 && myevent.x <= (2 * BSZ + 1))
396 {
397 curx = (myevent.x - 3) / 2;
398 cury = BSZ - myevent.y;
399 return(PT(curx,cury));
400 }
401 else
402 beep();
403 }
404 break;
405 #endif /* NCURSES_MOUSE_VERSION */
406 case 'Q':
407 return(RESIGN);
408 break;
409 case 'S':
410 return(SAVE);
411 break;
412 case ' ':
413 case '\015': /* return */
414 (void) mvaddstr(BSZ3, (BSZ -6)/2, " ");
415 return(PT(curx+1,cury+1));
416 break;
417 }
418
419 curx = nx % BSZ;
420 cury = ny % BSZ;
421 }
422 }
423