src/chess/rules.c

changeset 122
e65d9b5e9324
parent 115
206201d544be
equal deleted inserted replaced
121:53f714ac783d 122:e65d9b5e9324
142 if (move->check) { 142 if (move->check) {
143 string[idx++] = gamestate->checkmate?'#':'+'; 143 string[idx++] = gamestate->checkmate?'#':'+';
144 } 144 }
145 } 145 }
146 146
147 static void addmove(GameState* gamestate, Move *data) { 147 static void calc_movetime(GameState *gamestate, Move *move) {
148 if (gamestate->movecount == gamestate->movecapacity) {
149 gamestate->movecapacity += 64; /* 32 more full moves */
150 gamestate->moves = realloc(gamestate->moves,
151 gamestate->movecapacity * sizeof(Move));
152 }
153
154 Move *move = &gamestate->moves[gamestate->movecount];
155 *move = *data;
156
157 struct timeval curtimestamp; 148 struct timeval curtimestamp;
158 gettimeofday(&curtimestamp, NULL); 149 gettimeofday(&curtimestamp, NULL);
159 move->timestamp.tv_sec = curtimestamp.tv_sec; 150 move->timestamp.tv_sec = curtimestamp.tv_sec;
160 move->timestamp.tv_usec = (int32_t) curtimestamp.tv_usec; 151 move->timestamp.tv_usec = (int32_t) curtimestamp.tv_usec;
161 152
162 if (gamestate->movecount > 1) { 153 if (gamestate->movecount > 1) {
163 struct movetimeval lasttstamp = last_move(gamestate).timestamp; 154 struct movetimeval lasttstamp = last_move(gamestate).timestamp;
164 uint64_t sec = curtimestamp.tv_sec - lasttstamp.tv_sec; 155 uint64_t sec = curtimestamp.tv_sec - lasttstamp.tv_sec;
165 suseconds_t micros; 156 suseconds_t micros;
166 if (curtimestamp.tv_usec < lasttstamp.tv_usec) { 157 if (curtimestamp.tv_usec < lasttstamp.tv_usec) {
167 micros = 1000000-(lasttstamp.tv_usec - curtimestamp.tv_usec); 158 micros = 1000000-(lasttstamp.tv_usec - curtimestamp.tv_usec);
168 sec--; 159 sec--;
169 } else { 160 } else {
170 micros = curtimestamp.tv_usec - lasttstamp.tv_usec; 161 micros = curtimestamp.tv_usec - lasttstamp.tv_usec;
171 } 162 }
172 163
173 move->movetime.tv_sec = sec; 164 move->movetime.tv_sec = sec;
174 move->movetime.tv_usec = (int32_t) micros; 165 move->movetime.tv_usec = (int32_t) micros;
175 } else { 166 } else {
176 /* no move time for the first move of both white and black */ 167 /* no move time for the first move of both white and black */
177 move->movetime.tv_usec = 0; 168 move->movetime.tv_usec = 0;
178 move->movetime.tv_sec = 0; 169 move->movetime.tv_sec = 0;
179 } 170 }
171 }
172
173 static void addmove(GameState* gamestate, Move *data) {
174 if (gamestate->movecount == gamestate->movecapacity) {
175 gamestate->movecapacity += 64; /* 32 more full moves */
176 gamestate->moves = realloc(gamestate->moves,
177 gamestate->movecapacity * sizeof(Move));
178 }
179
180 Move *move = &gamestate->moves[gamestate->movecount];
181 *move = *data;
182
183 /* only if move has no time info, compute it */
184 if (move->movetime.tv_sec == 0 && move->movetime.tv_usec == 0) {
185 calc_movetime(gamestate, move);
186 }
187
188 /* important: only "add" the move after calculating the time! */
180 gamestate->movecount++; 189 gamestate->movecount++;
181 } 190 }
182 191
183 char getpiecechr(uint8_t piece) { 192 char getpiecechr(uint8_t piece) {
184 switch (piece & PIECE_MASK) { 193 switch (piece & PIECE_MASK) {
278 /* add move, even in simulation (checkmate test needs it) */ 287 /* add move, even in simulation (checkmate test needs it) */
279 addmove(gamestate, move); 288 addmove(gamestate, move);
280 } 289 }
281 290
282 void apply_move(GameState *gamestate, Move *move) { 291 void apply_move(GameState *gamestate, Move *move) {
283 apply_move_impl(gamestate, move, 0); 292 apply_move_impl(gamestate, move, false);
293 }
294
295 void gamestate_at_move(GameState *gamestate,
296 unsigned move_number, GameState *replay) {
297 gamestate_init(replay);
298 replay->review = true;
299 if (move_number > gamestate->movecount) {
300 move_number = gamestate->movecount;
301 }
302 for (unsigned i = 0 ; i < move_number ; i++) {
303 apply_move_impl(replay, &(gamestate->moves[i]), true);
304 }
284 } 305 }
285 306
286 static int validate_move_rules(GameState *gamestate, Move *move) { 307 static int validate_move_rules(GameState *gamestate, Move *move) {
287 /* validate indices (don't trust opponent) */ 308 /* validate indices (don't trust opponent) */
288 if (!chkidx(move)) { 309 if (!chkidx(move)) {
355 } 376 }
356 377
357 /* simulate move for check validation */ 378 /* simulate move for check validation */
358 GameState simulation = gamestate_copy_sim(gamestate); 379 GameState simulation = gamestate_copy_sim(gamestate);
359 Move simmove = *move; 380 Move simmove = *move;
360 apply_move_impl(&simulation, &simmove, 1); 381 apply_move_impl(&simulation, &simmove, true);
361 382
362 /* find kings for check validation */ 383 /* find kings for check validation */
363 uint8_t piececolor = (move->piece & COLOR_MASK); 384 uint8_t piececolor = (move->piece & COLOR_MASK);
364 385
365 uint8_t mykingfile = 0, mykingrow = 0, opkingfile = 0, opkingrow = 0; 386 uint8_t mykingfile = 0, mykingrow = 0, opkingfile = 0, opkingrow = 0;

mercurial