1.1 --- a/src/game.c Tue Apr 01 12:30:25 2014 +0200 1.2 +++ b/src/game.c Tue Apr 01 14:04:00 2014 +0200 1.3 @@ -112,6 +112,78 @@ 1.4 } 1.5 } 1.6 1.7 +static void eval_move_failed_msg(int code) { 1.8 + switch (code) { 1.9 + case AMBIGUOUS_MOVE: 1.10 + printw("Ambiguous move - please specify the piece to move."); 1.11 + break; 1.12 + case INVALID_POSITION: 1.13 + printw("Cannot find the piece that shall be moved."); 1.14 + break; 1.15 + case NEED_PROMOTION: 1.16 + printw("You need to promote the pawn (append \"=Q\" e.g.)!"); 1.17 + break; 1.18 + default: 1.19 + printw("Can't interpret move - please use algebraic notation."); 1.20 + } 1.21 +} 1.22 + 1.23 +static int domove_singlemachine(GameState *gamestate) { 1.24 + 1.25 + const size_t buflen = 8; 1.26 + char movestr[buflen]; 1.27 + 1.28 + int inputy = getmaxy(stdscr) - 6; 1.29 + while (1) { 1.30 + move(inputy, 0); 1.31 + printw( 1.32 + "Use chess notation to enter your move.\n" 1.33 + "Or type 'surr' to surrender or 'remis' to end with remis.\n\n" 1.34 + "Type your move: "); 1.35 + clrtoeol(); 1.36 + refresh(); 1.37 + getnstr(movestr, buflen); 1.38 + 1.39 + if (strncmp(movestr, "surr", buflen) == 0) { 1.40 + printw("%s surrendered!", 1.41 + gamestate->mycolor==WHITE?"White":"Black"); 1.42 + clrtoeol(); 1.43 + refresh(); 1.44 + return 1; 1.45 + } else if (strncmp(movestr, "remis", buflen) == 0) { 1.46 + printw("Game ends remis."); 1.47 + clrtoeol(); 1.48 + refresh(); 1.49 + return 1; 1.50 + } else { 1.51 + Move move; 1.52 + int eval_result = eval_move(gamestate, movestr, &move); 1.53 + switch (eval_result) { 1.54 + case VALID_MOVE_SYNTAX: 1.55 + if (validate_move(gamestate, &move)) { 1.56 + apply_move(gamestate, &move); 1.57 + if (move.checkmate) { 1.58 + printw("Checkmate!"); 1.59 + clrtoeol(); 1.60 + return 1; 1.61 + } else if (move.stalemate) { 1.62 + printw("Stalemate!"); 1.63 + clrtoeol(); 1.64 + return 1; 1.65 + } else { 1.66 + return 0; 1.67 + } 1.68 + } else { 1.69 + printw("Invalid move."); 1.70 + } 1.71 + break; 1.72 + default: 1.73 + eval_move_failed_msg(eval_result); 1.74 + } 1.75 + clrtoeol(); 1.76 + } 1.77 + } 1.78 +} 1.79 1.80 static int sendmove(GameState *gamestate, int opponent) { 1.81 1.82 @@ -167,6 +239,7 @@ 1.83 code = net_recieve_code(opponent); 1.84 move.check = code == NETCODE_CHECK; 1.85 move.checkmate = code == NETCODE_CHECKMATE; 1.86 + move.stalemate = code == NETCODE_STALEMATE; 1.87 if (code == NETCODE_DECLINE) { 1.88 printw("Invalid move."); 1.89 } else { 1.90 @@ -175,22 +248,17 @@ 1.91 printw("Checkmate!"); 1.92 clrtoeol(); 1.93 return 1; 1.94 + } else if (move.stalemate) { 1.95 + printw("Stalemate!"); 1.96 + clrtoeol(); 1.97 + return 1; 1.98 } else { 1.99 return 0; 1.100 } 1.101 } 1.102 break; 1.103 - case AMBIGUOUS_MOVE: 1.104 - printw("Ambiguous move - please specify the piece to move."); 1.105 - break; 1.106 - case INVALID_POSITION: 1.107 - printw("Cannot find the piece that shall be moved."); 1.108 - break; 1.109 - case NEED_PROMOTION: 1.110 - printw("You need to promote the pawn (append \"=Q\" e.g.)!"); 1.111 - break; 1.112 default: 1.113 - printw("Can't interpret move - please use algebraic notation."); 1.114 + eval_move_failed_msg(eval_result); 1.115 } 1.116 clrtoeol(); 1.117 } 1.118 @@ -234,6 +302,14 @@ 1.119 net_send_code(opponent, NETCODE_CHECK); 1.120 } else if (move.checkmate) { 1.121 net_send_code(opponent, NETCODE_CHECKMATE); 1.122 + printw("\rCheckmate!"); 1.123 + clrtoeol(); 1.124 + return 1; 1.125 + } else if (move.stalemate) { 1.126 + net_send_code(opponent, NETCODE_STALEMATE); 1.127 + printw("\rStalemate!"); 1.128 + clrtoeol(); 1.129 + return 1; 1.130 } else { 1.131 net_send_code(opponent, NETCODE_ACCEPT); 1.132 } 1.133 @@ -245,22 +321,49 @@ 1.134 } 1.135 } 1.136 1.137 +static void init_board(GameState *gamestate) { 1.138 + Board initboard = { 1.139 + {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK}, 1.140 + {WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN}, 1.141 + {0, 0, 0, 0, 0, 0, 0, 0}, 1.142 + {0, 0, 0, 0, 0, 0, 0, 0}, 1.143 + {0, 0, 0, 0, 0, 0, 0, 0}, 1.144 + {0, 0, 0, 0, 0, 0, 0, 0}, 1.145 + {BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN}, 1.146 + {BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK} 1.147 + }; 1.148 + memcpy(gamestate->board, initboard, sizeof(Board)); 1.149 +} 1.150 + 1.151 +void game_start_singlemachine(Settings *settings) { 1.152 + GameState gamestate; 1.153 + init_board(&gamestate); 1.154 + gamestate.mycolor = WHITE; 1.155 + gamestate.movelist = gamestate.lastmove = NULL; 1.156 + // TODO: time limit 1.157 + _Bool running; 1.158 + do { 1.159 + clear(); 1.160 + draw_board(&gamestate); 1.161 + running = !domove_singlemachine(&gamestate); 1.162 + gamestate.mycolor = opponent_color(gamestate.mycolor); 1.163 + } while (running); 1.164 + 1.165 + gamestate_cleanup(&gamestate); 1.166 + 1.167 + mvaddstr(getmaxy(stdscr)-1, 0, 1.168 + "Game has ended. Press any key to leave..."); 1.169 + refresh(); 1.170 + getch(); 1.171 +} 1.172 + 1.173 void game_start(Settings *settings, int opponent) { 1.174 _Bool myturn = is_server(settings) == 1.175 (settings->gameinfo.servercolor == WHITE); 1.176 1.177 + // TODO: time limit 1.178 GameState gamestate; 1.179 - Board initboard = { 1.180 - {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK}, 1.181 - {WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN}, 1.182 - {0, 0, 0, 0, 0, 0, 0, 0}, 1.183 - {0, 0, 0, 0, 0, 0, 0, 0}, 1.184 - {0, 0, 0, 0, 0, 0, 0, 0}, 1.185 - {0, 0, 0, 0, 0, 0, 0, 0}, 1.186 - {BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN}, 1.187 - {BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK} 1.188 - }; 1.189 - memcpy(gamestate.board, initboard, sizeof(Board)); 1.190 + init_board(&gamestate); 1.191 gamestate.mycolor = myturn ? WHITE:BLACK; 1.192 gamestate.movelist = gamestate.lastmove = NULL; 1.193 1.194 @@ -281,5 +384,6 @@ 1.195 1.196 mvaddstr(getmaxy(stdscr)-1, 0, 1.197 "Game has ended. Press any key to leave..."); 1.198 + refresh(); 1.199 getch(); 1.200 }