src/game.c

changeset 26
e0a76ee1bb2b
parent 25
3ab0c2e1a4e2
child 27
efeb98bc69c9
equal deleted inserted replaced
25:3ab0c2e1a4e2 26:e0a76ee1bb2b
110 logelem = logelem->next; 110 logelem = logelem->next;
111 } 111 }
112 } 112 }
113 } 113 }
114 114
115 static void eval_move_failed_msg(int code) {
116 switch (code) {
117 case AMBIGUOUS_MOVE:
118 printw("Ambiguous move - please specify the piece to move.");
119 break;
120 case INVALID_POSITION:
121 printw("Cannot find the piece that shall be moved.");
122 break;
123 case NEED_PROMOTION:
124 printw("You need to promote the pawn (append \"=Q\" e.g.)!");
125 break;
126 default:
127 printw("Can't interpret move - please use algebraic notation.");
128 }
129 }
130
131 static int domove_singlemachine(GameState *gamestate) {
132
133 const size_t buflen = 8;
134 char movestr[buflen];
135
136 int inputy = getmaxy(stdscr) - 6;
137 while (1) {
138 move(inputy, 0);
139 printw(
140 "Use chess notation to enter your move.\n"
141 "Or type 'surr' to surrender or 'remis' to end with remis.\n\n"
142 "Type your move: ");
143 clrtoeol();
144 refresh();
145 getnstr(movestr, buflen);
146
147 if (strncmp(movestr, "surr", buflen) == 0) {
148 printw("%s surrendered!",
149 gamestate->mycolor==WHITE?"White":"Black");
150 clrtoeol();
151 refresh();
152 return 1;
153 } else if (strncmp(movestr, "remis", buflen) == 0) {
154 printw("Game ends remis.");
155 clrtoeol();
156 refresh();
157 return 1;
158 } else {
159 Move move;
160 int eval_result = eval_move(gamestate, movestr, &move);
161 switch (eval_result) {
162 case VALID_MOVE_SYNTAX:
163 if (validate_move(gamestate, &move)) {
164 apply_move(gamestate, &move);
165 if (move.checkmate) {
166 printw("Checkmate!");
167 clrtoeol();
168 return 1;
169 } else if (move.stalemate) {
170 printw("Stalemate!");
171 clrtoeol();
172 return 1;
173 } else {
174 return 0;
175 }
176 } else {
177 printw("Invalid move.");
178 }
179 break;
180 default:
181 eval_move_failed_msg(eval_result);
182 }
183 clrtoeol();
184 }
185 }
186 }
115 187
116 static int sendmove(GameState *gamestate, int opponent) { 188 static int sendmove(GameState *gamestate, int opponent) {
117 189
118 const size_t buflen = 8; 190 const size_t buflen = 8;
119 char movestr[buflen]; 191 char movestr[buflen];
165 case VALID_MOVE_SYNTAX: 237 case VALID_MOVE_SYNTAX:
166 net_send_data(opponent, NETCODE_MOVE, &move, sizeof(Move)); 238 net_send_data(opponent, NETCODE_MOVE, &move, sizeof(Move));
167 code = net_recieve_code(opponent); 239 code = net_recieve_code(opponent);
168 move.check = code == NETCODE_CHECK; 240 move.check = code == NETCODE_CHECK;
169 move.checkmate = code == NETCODE_CHECKMATE; 241 move.checkmate = code == NETCODE_CHECKMATE;
242 move.stalemate = code == NETCODE_STALEMATE;
170 if (code == NETCODE_DECLINE) { 243 if (code == NETCODE_DECLINE) {
171 printw("Invalid move."); 244 printw("Invalid move.");
172 } else { 245 } else {
173 apply_move(gamestate, &move); 246 apply_move(gamestate, &move);
174 if (move.checkmate) { 247 if (move.checkmate) {
175 printw("Checkmate!"); 248 printw("Checkmate!");
176 clrtoeol(); 249 clrtoeol();
177 return 1; 250 return 1;
251 } else if (move.stalemate) {
252 printw("Stalemate!");
253 clrtoeol();
254 return 1;
178 } else { 255 } else {
179 return 0; 256 return 0;
180 } 257 }
181 } 258 }
182 break; 259 break;
183 case AMBIGUOUS_MOVE:
184 printw("Ambiguous move - please specify the piece to move.");
185 break;
186 case INVALID_POSITION:
187 printw("Cannot find the piece that shall be moved.");
188 break;
189 case NEED_PROMOTION:
190 printw("You need to promote the pawn (append \"=Q\" e.g.)!");
191 break;
192 default: 260 default:
193 printw("Can't interpret move - please use algebraic notation."); 261 eval_move_failed_msg(eval_result);
194 } 262 }
195 clrtoeol(); 263 clrtoeol();
196 } 264 }
197 } 265 }
198 } 266 }
232 apply_move(gamestate, &move); 300 apply_move(gamestate, &move);
233 if (move.check) { 301 if (move.check) {
234 net_send_code(opponent, NETCODE_CHECK); 302 net_send_code(opponent, NETCODE_CHECK);
235 } else if (move.checkmate) { 303 } else if (move.checkmate) {
236 net_send_code(opponent, NETCODE_CHECKMATE); 304 net_send_code(opponent, NETCODE_CHECKMATE);
305 printw("\rCheckmate!");
306 clrtoeol();
307 return 1;
308 } else if (move.stalemate) {
309 net_send_code(opponent, NETCODE_STALEMATE);
310 printw("\rStalemate!");
311 clrtoeol();
312 return 1;
237 } else { 313 } else {
238 net_send_code(opponent, NETCODE_ACCEPT); 314 net_send_code(opponent, NETCODE_ACCEPT);
239 } 315 }
240 return 0; 316 return 0;
241 } else { 317 } else {
243 } 319 }
244 } 320 }
245 } 321 }
246 } 322 }
247 323
248 void game_start(Settings *settings, int opponent) { 324 static void init_board(GameState *gamestate) {
249 _Bool myturn = is_server(settings) ==
250 (settings->gameinfo.servercolor == WHITE);
251
252 GameState gamestate;
253 Board initboard = { 325 Board initboard = {
254 {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK}, 326 {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK},
255 {WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN}, 327 {WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN},
256 {0, 0, 0, 0, 0, 0, 0, 0}, 328 {0, 0, 0, 0, 0, 0, 0, 0},
257 {0, 0, 0, 0, 0, 0, 0, 0}, 329 {0, 0, 0, 0, 0, 0, 0, 0},
258 {0, 0, 0, 0, 0, 0, 0, 0}, 330 {0, 0, 0, 0, 0, 0, 0, 0},
259 {0, 0, 0, 0, 0, 0, 0, 0}, 331 {0, 0, 0, 0, 0, 0, 0, 0},
260 {BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN}, 332 {BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN},
261 {BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK} 333 {BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK}
262 }; 334 };
263 memcpy(gamestate.board, initboard, sizeof(Board)); 335 memcpy(gamestate->board, initboard, sizeof(Board));
336 }
337
338 void game_start_singlemachine(Settings *settings) {
339 GameState gamestate;
340 init_board(&gamestate);
341 gamestate.mycolor = WHITE;
342 gamestate.movelist = gamestate.lastmove = NULL;
343 // TODO: time limit
344 _Bool running;
345 do {
346 clear();
347 draw_board(&gamestate);
348 running = !domove_singlemachine(&gamestate);
349 gamestate.mycolor = opponent_color(gamestate.mycolor);
350 } while (running);
351
352 gamestate_cleanup(&gamestate);
353
354 mvaddstr(getmaxy(stdscr)-1, 0,
355 "Game has ended. Press any key to leave...");
356 refresh();
357 getch();
358 }
359
360 void game_start(Settings *settings, int opponent) {
361 _Bool myturn = is_server(settings) ==
362 (settings->gameinfo.servercolor == WHITE);
363
364 // TODO: time limit
365 GameState gamestate;
366 init_board(&gamestate);
264 gamestate.mycolor = myturn ? WHITE:BLACK; 367 gamestate.mycolor = myturn ? WHITE:BLACK;
265 gamestate.movelist = gamestate.lastmove = NULL; 368 gamestate.movelist = gamestate.lastmove = NULL;
266 369
267 _Bool running; 370 _Bool running;
268 do { 371 do {
279 382
280 gamestate_cleanup(&gamestate); 383 gamestate_cleanup(&gamestate);
281 384
282 mvaddstr(getmaxy(stdscr)-1, 0, 385 mvaddstr(getmaxy(stdscr)-1, 0,
283 "Game has ended. Press any key to leave..."); 386 "Game has ended. Press any key to leave...");
387 refresh();
284 getch(); 388 getch();
285 } 389 }

mercurial