static int getcoord(int atcpu) { int ny, nx, c; if (atcpu) cgoto(cury, curx); else pgoto(cury, curx); (void) refresh(); for (;;) { if (atcpu) { (void) mvprintw(CYBASE + BDEPTH + 1, CXBASE + 11, "(%d, %c)", curx, 'A' + cury); cgoto(cury, curx); } else { (void) mvprintw(PYBASE + BDEPTH + 1, PXBASE + 11, "(%d, %c)", curx, 'A' + cury); pgoto(cury, curx); } switch (c = getch()) { case 'k': case '8': case KEY_UP: ny = cury + BDEPTH - 1; nx = curx; break; case 'j': case '2': case KEY_DOWN: ny = cury + 1; nx = curx; break; case 'h': case '4': case KEY_LEFT: ny = cury; nx = curx + BWIDTH - 1; break; case 'l': case '6': case KEY_RIGHT: ny = cury; nx = curx + 1; break; case 'y': case '7': case KEY_A1: ny = cury + BDEPTH - 1; nx = curx + BWIDTH - 1; break; case 'b': case '1': case KEY_C1: ny = cury + 1; nx = curx + BWIDTH - 1; break; case 'u': case '9': case KEY_A3: ny = cury + BDEPTH - 1; nx = curx + 1; break; case 'n': case '3': case KEY_C3: ny = cury + 1; nx = curx + 1; break; case FF: nx = curx; ny = cury; (void) clearok(stdscr, TRUE); (void) refresh(); break; #ifdef NCURSES_MOUSE_VERSION case KEY_MOUSE: { MEVENT myevent; getmouse(&myevent); if (atcpu && myevent.y >= CY(0) && myevent.y <= CY(BDEPTH) && myevent.x >= CX(0) && myevent.x <= CX(BDEPTH)) { curx = CXINV(myevent.x); cury = CYINV(myevent.y); return (' '); } else { beep(); continue; } } /* no fall through */ #endif /* NCURSES_MOUSE_VERSION */ default: if (atcpu) (void) mvaddstr(CYBASE + BDEPTH + 1, CXBASE + 11, " "); else (void) mvaddstr(PYBASE + BDEPTH + 1, PXBASE + 11, " "); return (c); } curx = nx % BWIDTH; cury = ny % BDEPTH; } }
static void play(void) /* play the game */ { bool keyhelp; /* TRUE if keystroke help is up */ int i, j, count; int lastcol = 0; /* last location visited */ int lastrow = 0; int ny = 0, nx = 0; int review = 0; /* review history */ int rw = 0, col = 0; /* current row and column */ do { /* clear screen and draw board */ werase(boardwin); werase(helpwin); werase(msgwin); dosquares(); help1(); wnoutrefresh(stdscr); wnoutrefresh(helpwin); wnoutrefresh(msgwin); wnoutrefresh(boardwin); doupdate(); movecount = 0; for (i = 0; i < BDEPTH; i++) { for (j = 0; j < BWIDTH; j++) { board[i][j] = FALSE; unmarkcell(i, j); } } memset(history, 0, sizeof(history)); history[0].y = history[0].x = -1; history[1].y = history[1].x = -1; lastrow = lastcol = -2; movecount = 1; trialcount = 1; keyhelp = FALSE; show_help(&keyhelp); for (;;) { if (rw != lastrow || col != lastcol) { if (lastrow >= 0 && lastcol >= 0) { cellmove(lastrow, lastcol); if (board[lastrow][lastcol]) waddch(boardwin, trail); else waddch(boardwin, oldch); } cellmove(rw, col); oldch = winch(boardwin); lastrow = rw; lastcol = col; } cellmove(rw, col); waddch(boardwin, plus); cellmove(rw, col); wrefresh(msgwin); switch (wgetch(boardwin)) { case 'k': case '8': case KEY_UP: ny = rw + BDEPTH - 1; nx = col; break; case 'j': case '2': case KEY_DOWN: ny = rw + 1; nx = col; break; case 'h': case '4': case KEY_LEFT: ny = rw; nx = col + BWIDTH - 1; break; case 'l': case '6': case KEY_RIGHT: ny = rw; nx = col + 1; break; case 'y': case '7': case KEY_A1: ny = rw + BDEPTH - 1; nx = col + BWIDTH - 1; break; case 'b': case '1': case KEY_C1: ny = rw + 1; nx = col + BWIDTH - 1; break; case 'u': case '9': case KEY_A3: ny = rw + BDEPTH - 1; nx = col + 1; break; case 'n': case '3': case KEY_C3: ny = rw + 1; nx = col + 1; break; #ifdef NCURSES_MOUSE_VERSION case KEY_MOUSE: { MEVENT myevent; getmouse(&myevent); if (myevent.y >= CY(0) && myevent.y <= CY(BDEPTH) && myevent.x >= CX(0) && myevent.x <= CX(BWIDTH)) { nx = CXINV(myevent.x); ny = CYINV(myevent.y); ungetch('\n'); break; } else { beep(); continue; } } #endif /* NCURSES_MOUSE_VERSION */ case KEY_B2: case '\n': case ' ': review = 0; if (evalmove(rw, col)) { drawmove(trail, history[movecount - 1].y, history[movecount - 1].x, rw, col); history[movecount].y = (short) rw; history[movecount].x = (short) col; movecount++; trialcount++; if (!chkmoves(rw, col)) { if (completed() < 0) { waddstr(msgwin, "\nYou won."); } else { waddstr(msgwin, "\nNo further moves are possible."); } } } else { beep(); } break; case KEY_UNDO: case KEY_BACKSPACE: case '\b': review = 0; if (movecount <= 0) { no_previous_move(); } else if (movecount <= 1) { ny = history[movecount].y; nx = history[movecount].x; if (nx < 0 || ny < 0) { ny = lastrow; nx = lastcol; } movecount = 0; board[ny][nx] = FALSE; oldch = minus; drawmove(' ', ny, nx, -1, -1); movecount = 1; trialcount = 1; no_previous_move(); } else { int oldy = history[movecount - 1].y; int oldx = history[movecount - 1].x; if (!board[rw][col]) { cellmove(rw, col); waddch(boardwin, ' '); } board[oldy][oldx] = FALSE; --movecount; ny = history[movecount - 1].y; nx = history[movecount - 1].x; if (nx < 0 || ny < 0) { ny = oldy; nx = oldx; } drawmove(' ', oldy, oldx, ny, nx); /* avoid problems if we just changed the current cell */ cellmove(lastrow, lastcol); oldch = winch(boardwin); } break; case 'a': nx = col; ny = rw; find_next_move(&ny, &nx); break; case 'F': if (review > 0) { review--; ny = history[movecount - review - 1].y; nx = history[movecount - review - 1].x; } else { beep(); } break; case 'B': if (review < movecount - 2) { review++; ny = history[movecount - review - 1].y; nx = history[movecount - review - 1].x; } else { beep(); } break; case KEY_REDO: case '\f': case 'r': clearok(curscr, TRUE); wnoutrefresh(stdscr); wnoutrefresh(boardwin); wnoutrefresh(msgwin); wnoutrefresh(helpwin); doupdate(); break; case 'q': case 'x': goto dropout; case '?': show_help(&keyhelp); break; default: beep(); break; } col = nx % BWIDTH; rw = ny % BDEPTH; } dropout: if ((count = completed()) < 0) wprintw(msgwin, "\nYou won. Care to try again? "); else wprintw(msgwin, "\n%d squares filled. Try again? ", count); wclrtoeol(msgwin); } while (tolower(wgetch(msgwin)) == 'y'); }