src/chess/rules.c

changeset 157
07cbfc477b22
parent 156
05fc8a454700
child 158
52d452d0e7bf
equal deleted inserted replaced
156:05fc8a454700 157:07cbfc477b22
32 #include "rook.h" 32 #include "rook.h"
33 #include "knight.h" 33 #include "knight.h"
34 #include "bishop.h" 34 #include "bishop.h"
35 #include "queen.h" 35 #include "queen.h"
36 #include "king.h" 36 #include "king.h"
37 #include "fen.h"
37 38
38 #include <string.h> 39 #include <string.h>
39 #include <stdio.h> 40 #include <stdio.h>
40 #include <stdlib.h> 41 #include <stdlib.h>
41 #include <sys/time.h> 42 #include <sys/time.h>
42 43
43 void gamestate_init(GameState *gamestate) { 44 void gamestate_init(GameState *gamestate) {
44 memset(gamestate, 0, sizeof(GameState)); 45 memset(gamestate, 0, sizeof(GameState));
45 46
47 // TODO: implement feature - game can be started from arbitrary position
46 Board initboard = { 48 Board initboard = {
47 {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK}, 49 {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK},
48 {WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN}, 50 {WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN},
49 {0, 0, 0, 0, 0, 0, 0, 0}, 51 {0, 0, 0, 0, 0, 0, 0, 0},
50 {0, 0, 0, 0, 0, 0, 0, 0}, 52 {0, 0, 0, 0, 0, 0, 0, 0},
52 {0, 0, 0, 0, 0, 0, 0, 0}, 54 {0, 0, 0, 0, 0, 0, 0, 0},
53 {BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN}, 55 {BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN},
54 {BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK} 56 {BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK}
55 }; 57 };
56 memcpy(gamestate->board, initboard, sizeof(Board)); 58 memcpy(gamestate->board, initboard, sizeof(Board));
59 char fen[FEN_MAX_LENGTH];
60 fen_compute(fen, gamestate);
61 gamestate->fen_start = strdup(fen);
57 } 62 }
58 63
59 void gamestate_cleanup(GameState *gamestate) { 64 void gamestate_cleanup(GameState *gamestate) {
60 free(gamestate->moves); 65 free(gamestate->moves);
66 free(gamestate->fen_start);
67 for (unsigned i = 0 ; i < gamestate->movecount ; i++) {
68 free(gamestate->fen[i]);
69 }
70 free(gamestate->fen);
61 gamestate->movecount = gamestate->movecapacity = 0; 71 gamestate->movecount = gamestate->movecapacity = 0;
62 } 72 }
63 73
64 static GameState gamestate_copy_sim(GameState *gamestate) { 74 static GameState gamestate_copy_sim(GameState *gamestate) {
65 GameState simulation = *gamestate; 75 GameState simulation = *gamestate;
66 76
67 // create a new move list for the simulation 77 /* create new move and position lists for the simulation */
68 simulation.movecapacity = 4; 78 simulation.movecapacity = 4;
69 simulation.movecount = 0; 79 simulation.movecount = 0;
70 simulation.moves = malloc(4 * sizeof(Move)); 80 simulation.moves = malloc(4 * sizeof(Move));
71 81 simulation.fen = malloc(4 * sizeof(char*));
72 // copy the most recent move if a move was played 82
83 /* copy the most recent move and position if a move was played */
73 if (gamestate->movecount > 0) { 84 if (gamestate->movecount > 0) {
85 simulation.fen_start = strdup(gamestate->movecount == 1 ?
86 gamestate->fen_start : gamestate->fen[gamestate->movecount - 2]);
74 simulation.moves[0] = last_move(gamestate); 87 simulation.moves[0] = last_move(gamestate);
88 simulation.fen[0] = strdup(gamestate->fen[gamestate->movecount - 1]);
75 simulation.movecount++; 89 simulation.movecount++;
90 } else {
91 simulation.fen_start = strdup(gamestate->fen_start);
76 } 92 }
77 93
78 return simulation; 94 return simulation;
79 } 95 }
80 96
197 move->movetime.tv_usec = (int32_t) micros; 213 move->movetime.tv_usec = (int32_t) micros;
198 } 214 }
199 } 215 }
200 } 216 }
201 217
202 static void addmove(GameState* gamestate, Move *data) {
203 if (gamestate->movecount == gamestate->movecapacity) {
204 gamestate->movecapacity += 64; /* 32 more full moves */
205 gamestate->moves = realloc(gamestate->moves,
206 gamestate->movecapacity * sizeof(Move));
207 }
208
209 Move *move = &gamestate->moves[gamestate->movecount];
210 *move = *data;
211
212 /* only if move has no time info, compute it */
213 if (move->movetime.tv_sec == 0 && move->movetime.tv_usec == 0) {
214 calc_movetime(gamestate, move);
215 }
216
217 /* important: only "add" the move after calculating the time! */
218 gamestate->movecount++;
219 }
220
221 char getpiecechr(uint8_t piece) { 218 char getpiecechr(uint8_t piece) {
222 switch (piece & PIECE_MASK) { 219 switch (piece & PIECE_MASK) {
223 case ROOK: return 'R'; 220 case ROOK: return 'R';
224 case KNIGHT: return 'N'; 221 case KNIGHT: return 'N';
225 case BISHOP: return 'B'; 222 case BISHOP: return 'B';
312 gamestate->board[move->torow][fileidx('a')] = 0; 309 gamestate->board[move->torow][fileidx('a')] = 0;
313 gamestate->board[move->torow][fileidx('d')] = color|ROOK; 310 gamestate->board[move->torow][fileidx('d')] = color|ROOK;
314 } 311 }
315 } 312 }
316 313
317 /* add move, even in simulation (checkmate test needs it) */ 314 /* add move to the moves array and the new position to the FEN array */
318 addmove(gamestate, move); 315 if (gamestate->movecount == gamestate->movecapacity) {
316 gamestate->movecapacity += 64; /* 32 more full moves */
317 gamestate->moves = realloc(gamestate->moves,
318 gamestate->movecapacity * sizeof(Move));
319 gamestate->fen = realloc(gamestate->fen,
320 gamestate->movecapacity * sizeof(char*));
321 }
322
323 /* copy the move data into the game's move array */
324 Move *melem = &gamestate->moves[gamestate->movecount];
325 *melem = *move;
326
327 /* calculate the FEN and store it in the FEN array */
328 char fen[FEN_MAX_LENGTH];
329 fen_compute(fen, gamestate);
330 gamestate->fen[gamestate->movecount] = strdup(fen);
331
332 /* only if move has no time info, compute it */
333 if (melem->movetime.tv_sec == 0 && melem->movetime.tv_usec == 0) {
334 calc_movetime(gamestate, melem);
335 }
336
337 /* important: only "add" the move after calculating the time! */
338 gamestate->movecount++;
319 } 339 }
320 340
321 void apply_move(GameState *gamestate, Move *move) { 341 void apply_move(GameState *gamestate, Move *move) {
322 apply_move_impl(gamestate, move, false); 342 apply_move_impl(gamestate, move, false);
323 } 343 }

mercurial