src/chess/rules.c

changeset 181
8bda076d0a16
parent 179
5ef724e21702
child 182
04c65336777f
equal deleted inserted replaced
180:0fed680c487c 181:8bda076d0a16
193 string[idx++] = '+'; 193 string[idx++] = '+';
194 } 194 }
195 } 195 }
196 196
197 static void calc_movetime(GameState *gamestate, Move *move) { 197 static void calc_movetime(GameState *gamestate, Move *move) {
198 /* only if move has no time info, compute it */
199 if (move->movetime > 0) return;
200
198 struct timeval curtimestamp; 201 struct timeval curtimestamp;
199 gettimeofday(&curtimestamp, NULL); 202 gettimeofday(&curtimestamp, NULL);
200 move->timestamp.tv_sec = curtimestamp.tv_sec; 203 move->timestamp.sec = curtimestamp.tv_sec;
201 move->timestamp.tv_usec = (int32_t) curtimestamp.tv_usec; 204 move->timestamp.usec = (int32_t) curtimestamp.tv_usec;
202 move->movetime.tv_usec = 0;
203 move->movetime.tv_sec = 0;
204 if (gamestate->movecount > 1) { 205 if (gamestate->movecount > 1) {
205 struct movetimeval lasttstamp = 206 struct movetimeval lasttstamp =
206 gamestate->moves[gamestate->movecount - 1].timestamp; 207 gamestate->moves[gamestate->movecount - 1].timestamp;
207 uint64_t sec = curtimestamp.tv_sec - lasttstamp.tv_sec; 208
208 suseconds_t micros; 209 uint64_t cur = move->timestamp.sec * 1000000ull + move->timestamp.usec;
209 if (curtimestamp.tv_usec < lasttstamp.tv_usec) { 210 uint64_t last = lasttstamp.sec * 1000000ull + lasttstamp.usec;
210 micros = 1000000-(lasttstamp.tv_usec - curtimestamp.tv_usec); 211
211 sec--; 212 move->movetime = cur - last;
212 } else {
213 micros = curtimestamp.tv_usec - lasttstamp.tv_usec;
214 }
215
216 while (micros >= 1000000) {
217 micros -= 1000000;
218 sec++;
219 }
220
221 if (sec >= gamestate->info.delay) {
222 move->movetime.tv_sec = sec;
223 move->movetime.tv_usec = (int32_t) micros;
224 }
225 } 213 }
226 } 214 }
227 215
228 size_t piece_moves_allowed(const GameState *gamestate, 216 size_t piece_moves_allowed(const GameState *gamestate,
229 Row r, File f, Move *moves) { 217 Row r, File f, Move *moves) {
467 } 455 }
468 456
469 /* copy the move data into the game's move array */ 457 /* copy the move data into the game's move array */
470 Move *melem = &gamestate->moves[gamestate->movecount]; 458 Move *melem = &gamestate->moves[gamestate->movecount];
471 *melem = *move; 459 *melem = *move;
472 460 calc_movetime(gamestate, melem);
473 /* only if move has no time info, compute it */
474 if (melem->movetime.tv_sec == 0 && melem->movetime.tv_usec == 0) {
475 calc_movetime(gamestate, melem);
476 }
477 461
478 /* important: only "add" the move after calculating the time! */ 462 /* important: only "add" the move after calculating the time! */
479 gamestate->movecount++; 463 gamestate->movecount++;
480 464
481 /* calculate the FEN of the new position and store it in the FEN array */ 465 /* calculate the FEN of the new position and store it in the FEN array */
1230 if (!gamestate->info.timecontrol) { 1214 if (!gamestate->info.timecontrol) {
1231 return 0; 1215 return 0;
1232 } 1216 }
1233 1217
1234 unsigned total_time = gamestate->info.time; 1218 unsigned total_time = gamestate->info.time;
1235 unsigned used_time = 0; 1219 uint64_t used_time_usec = 0;
1236 suseconds_t micros = 0;
1237 1220
1238 /* when this is a 0+X game, the clock starts with the increment */ 1221 /* when this is a 0+X game, the clock starts with the increment */
1239 if (gamestate->info.time == 0) { 1222 if (gamestate->info.time == 0) {
1240 total_time += gamestate->info.addtime; 1223 total_time += gamestate->info.addtime;
1241 } 1224 }
1243 /* go through all already played moves */ 1226 /* go through all already played moves */
1244 unsigned first_move = move_number % 2; 1227 unsigned first_move = move_number % 2;
1245 unsigned next_move = move_number; 1228 unsigned next_move = move_number;
1246 if (next_move > gamestate->movecount) next_move = gamestate->movecount; 1229 if (next_move > gamestate->movecount) next_move = gamestate->movecount;
1247 for (unsigned i = first_move ; i < next_move ; i += 2) { 1230 for (unsigned i = first_move ; i < next_move ; i += 2) {
1248 used_time += gamestate->moves[i].movetime.tv_sec; 1231 used_time_usec += gamestate->moves[i].movetime;
1249 micros += gamestate->moves[i].movetime.tv_usec;
1250 /* add increments starting with move 2 */ 1232 /* add increments starting with move 2 */
1251 if (i > 1) total_time += gamestate->info.addtime; 1233 if (i > 1) total_time += gamestate->info.addtime;
1252 }
1253
1254 /* apply microseconds */
1255 while (micros >= 1000000) {
1256 micros -= 1000000;
1257 used_time++;
1258 } 1234 }
1259 1235
1260 /* when the player is currently playing, count down the clock */ 1236 /* when the player is currently playing, count down the clock */
1261 if (is_game_running(gamestate) && move_number > 1 && 1237 if (is_game_running(gamestate) && move_number > 1 &&
1262 move_number == gamestate->movecount) { 1238 move_number == gamestate->movecount) {
1264 gamestate->moves[move_number - 1].timestamp; 1240 gamestate->moves[move_number - 1].timestamp;
1265 struct timeval currenttstamp; 1241 struct timeval currenttstamp;
1266 gettimeofday(&currenttstamp, NULL); 1242 gettimeofday(&currenttstamp, NULL);
1267 1243
1268 /* calculate current move time */ 1244 /* calculate current move time */
1269 unsigned cmsec = currenttstamp.tv_sec - lastmovetstamp.tv_sec; 1245 uint64_t cusec = currenttstamp.tv_sec - lastmovetstamp.sec;
1270 suseconds_t cmusec = currenttstamp.tv_usec - lastmovetstamp.tv_usec; 1246 cusec *= 1000000ull;
1271 1247 cusec += currenttstamp.tv_usec - lastmovetstamp.usec;
1272 /* add microseconds carried over from last move and apply both */
1273 cmusec += micros;
1274 cmsec += cmusec / 1000000;
1275 1248
1276 /* add the time and respect a possible dealy */ 1249 /* add the time and respect a possible dealy */
1277 if (cmsec >= gamestate->info.delay) { 1250 uint64_t delay = gamestate->info.delay * 1000000ull;
1278 used_time += cmsec - gamestate->info.delay; 1251 if (cusec >= delay) {
1279 } 1252 used_time_usec += cusec - delay;
1280 } 1253 }
1254 }
1255
1256 unsigned used_time = used_time_usec / 1000000ull;
1281 1257
1282 return used_time >= total_time ? 0 : total_time - used_time; 1258 return used_time >= total_time ? 0 : total_time - used_time;
1283 } 1259 }
1284 1260
1285 int print_clk(uint16_t time, char *str, bool always_hours) { 1261 int print_clk(uint16_t time, char *str, bool always_hours) {

mercurial