xref: /dragonfly/games/gomoku/bdisp.c (revision 00b5bfed606f09b3980f2138f99c802b608cb5a5)
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