/* Get a keystroke from the user (or from a macro) and perform the * indicated command. A non-zero return value indicates a request to * change the current puzzle, the actual value being a delta. */ static int doturn(void) { switch (input()) { case ARROW_N: if (!movecursor(NORTH)) ding(); break; case ARROW_E: if (!movecursor(EAST)) ding(); break; case ARROW_S: if (!movecursor(SOUTH)) ding(); break; case ARROW_W: if (!movecursor(WEST)) ding(); break; case 'k': if (!shiftfromcurrblock(NORTH)) ding(); break; case 'l': if (!shiftfromcurrblock(EAST)) ding(); break; case 'j': if (!shiftfromcurrblock(SOUTH)) ding(); break; case 'h': if (!shiftfromcurrblock(WEST)) ding(); break; case 'K': if (!newmove(NORTH)) ding(); break; case 'L': if (!newmove(EAST)) ding(); break; case 'J': if (!newmove(SOUTH)) ding(); break; case 'H': if (!newmove(WEST)) ding(); break; case 'x': if (!undomove()) ding(); break; case 'z': if (!redomove()) ding(); break; case 'X': if (!undostep()) ding(); break; case 'Z': if (!redostep()) ding(); break; case 'R': initgamestate(); break; case 's': savestate(); break; case 'r': if (!restorestate()) ding(); break; case 'S': if (!partialsave()) ding(); break; case 'g': drawgoalscreen(); break; case '?': drawhelpscreen(); break; case '\f': break; case 'P': return -1; case 'N': return +1; case 'q': exit(0); case 'Q': exit(0); } return 0; }
int main(void) { int gameboard[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* Start empty */ char charboard[CHAR_BOARD_LENGTH]; int *gameboard_ptr = gameboard; char *charboard_ptr = charboard; strcpy(charboard, blankboard); newmove(XPLAYER, A1, gameboard_ptr, charboard_ptr); newmove(OPLAYER, B3, gameboard_ptr, charboard_ptr); newmove(XPLAYER, C1, gameboard_ptr, charboard_ptr); return(0); }
/* Apply one move from the current macro. */ int macromove(void) { if (macroplay >= 0) if (!newmove(macro->list[macroplay].yx) || ++macroplay >= macro->count) macroplay = -1; return macroplay >= 0; }
/* Handle commands from the mouse. While the mouse is being dragged, * the function attempts to move the current block towards the cursor. */ int mousecallback(int y, int x, int mstate) { static int startpos, lastpos; static int startmovecount = -1; int pos, dir, altdir; int retval, n; if (mstate == -2) return startmovecount < 0 ? 'X' : 0; else if (mstate == +2) return 0; pos = y * XSIZE + x; if (mstate == -1) { if (y < 1 || x < 1 || y >= state.game->ysize - 1 || x >= state.game->xsize - 1) return 0; n = blockid(state.map[pos]); if (!n || n == WALLID) return 0; state.currblock = n; state.ycurrpos = state.xcurrpos = 0; startpos = lastpos = pos; startmovecount = state.undo.count; return '\f'; } if (startmovecount < 0) return 0; if (y < 0 || x < 0 || y >= state.game->ysize || x >= state.game->xsize) { if (startmovecount < state.undo.count) { undomoves(state.undo.count - startmovecount); lastpos = startpos; } if (mstate == +1) startmovecount = -1; return '\f'; } retval = 0; while (pos != lastpos) { raydirections(lastpos / XSIZE, lastpos % XSIZE, y, x, &dir, &altdir); if (dir < 0 || !canmove(state.currblock, dir)) { if (altdir < 0 || !canmove(state.currblock, altdir)) dir = -1; else dir = altdir; } if (dir < 0 || !newmove(dir)) break; lastpos += dirdelta[dir]; retval = '\f'; } if (mstate == +1) startmovecount = -1; return retval; }