src/chess/rules.c

changeset 219
24b866230dd4
parent 218
1e9751f8eb0d
child 220
04da225a5677
equal deleted inserted replaced
218:1e9751f8eb0d 219:24b866230dd4
43 #include <assert.h> 43 #include <assert.h>
44 44
45 void gamestate_init(GameState *gamestate) { 45 void gamestate_init(GameState *gamestate) {
46 memset(gamestate, 0, sizeof(GameState)); 46 memset(gamestate, 0, sizeof(GameState));
47 47
48 // TODO: implement feature - game can be started from arbitrary position
49 Board initboard = { 48 Board initboard = {
50 {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK}, 49 {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK},
51 {WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN}, 50 {WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN},
52 {0, 0, 0, 0, 0, 0, 0, 0}, 51 {0, 0, 0, 0, 0, 0, 0, 0},
53 {0, 0, 0, 0, 0, 0, 0, 0}, 52 {0, 0, 0, 0, 0, 0, 0, 0},
97 simulation.movecount++; 96 simulation.movecount++;
98 } else { 97 } else {
99 simulation.fen_start = strdup(gamestate->fen_start); 98 simulation.fen_start = strdup(gamestate->fen_start);
100 } 99 }
101 100
101 // TODO: think about setting move_start to a reasonable value
102
102 return simulation; 103 return simulation;
103 }
104
105 Color current_color(const GameState *gamestate) {
106 // TODO: better would be an API that returns the correct number
107 unsigned mc = gamestate->movecount + gamestate->move_start;
108 return (mc % 2 == 0) ? WHITE : BLACK;
109 } 104 }
110 105
111 static void calc_movetime(GameState *gamestate, Move *move) { 106 static void calc_movetime(GameState *gamestate, Move *move) {
112 /* only if move has no time info, compute it */ 107 /* only if move has no time info, compute it */
113 if (move->movetime > 0) return; 108 if (move->movetime > 0) return;
148 return 0; 143 return 0;
149 } 144 }
150 } 145 }
151 146
152 static bool check_stalemate(const GameState *gamestate) { 147 static bool check_stalemate(const GameState *gamestate) {
153 Color next_player = gamestate->movecount % 2 == 0 ? WHITE : BLACK; 148 Color next_player = current_color(gamestate);
154 149
155 /* scan the board for pieces of the next player's color */ 150 /* scan the board for pieces of the next player's color */
156 Move moves[QUEEN_MOVES_MAX]; 151 Move moves[QUEEN_MOVES_MAX];
157 for (Rank r = 0; r < 8; r++) { 152 for (Rank r = 0; r < 8; r++) {
158 for (File f = 0; f < 8; f++) { 153 for (File f = 0; f < 8; f++) {
434 void gamestate_at_move(const GameState *gamestate, 429 void gamestate_at_move(const GameState *gamestate,
435 unsigned move_number, GameState *replay) { 430 unsigned move_number, GameState *replay) {
436 gamestate_init(replay); 431 gamestate_init(replay);
437 memcpy(&replay->info, &gamestate->info, sizeof(GameInfo)); 432 memcpy(&replay->info, &gamestate->info, sizeof(GameInfo));
438 replay->review = true; 433 replay->review = true;
434 // TODO: respect move_start offset
439 if (move_number > gamestate->movecount) { 435 if (move_number > gamestate->movecount) {
440 move_number = gamestate->movecount; 436 move_number = gamestate->movecount;
441 } 437 }
442 for (unsigned i = 0 ; i < move_number ; i++) { 438 for (unsigned i = 0 ; i < move_number ; i++) {
443 apply_move(replay, &(gamestate->moves[i])); 439 apply_move(replay, &(gamestate->moves[i]));
1260 } 1256 }
1261 return false; 1257 return false;
1262 } 1258 }
1263 1259
1264 uint16_t remaining_movetime(const GameState *gamestate, Color color) { 1260 uint16_t remaining_movetime(const GameState *gamestate, Color color) {
1261 // TODO: we probably need to add the move_start offset here...
1265 unsigned move_number = gamestate->movecount; 1262 unsigned move_number = gamestate->movecount;
1266 if (color == BLACK) { 1263 if (color == BLACK) {
1267 move_number |= 1; 1264 move_number |= 1;
1268 } else { 1265 } else {
1269 move_number = (move_number + 1) & ~1; 1266 move_number = (move_number + 1) & ~1;
1270 } 1267 }
1271 return remaining_movetime2(gamestate, move_number); 1268 return remaining_movetime2(gamestate, move_number);
1272 } 1269 }
1273 1270
1274 uint16_t remaining_movetime2(const GameState *gamestate, unsigned move_number) { 1271 uint16_t remaining_movetime2(const GameState *gamestate, unsigned move_number) {
1272 // TODO: ... and remove / consider the move_start offset here
1275 if (!gamestate->info.timecontrol) { 1273 if (!gamestate->info.timecontrol) {
1276 return 0; 1274 return 0;
1277 } 1275 }
1278 1276
1279 unsigned total_time = gamestate->info.time; 1277 unsigned total_time = gamestate->info.time;

mercurial