| 275 } |
275 } |
| 276 |
276 |
| 277 return 0; |
277 return 0; |
| 278 } |
278 } |
| 279 |
279 |
| 280 static void draw_board(GameState *gamestate, uint8_t perspective) { |
280 static void draw_board(GameState *gamestate, Color perspective) { |
| 281 if (gamestate->movecount == 0) { |
281 if (gamestate->movecount == 0) { |
| 282 mvaddstr(0, 0, gamestate->fen_start); |
282 mvaddstr(0, 0, gamestate->fen_start); |
| 283 } else { |
283 } else { |
| 284 mvaddstr(0, 0, gamestate->fen[gamestate->movecount - 1]); |
284 mvaddstr(0, 0, gamestate->fen[gamestate->movecount - 1]); |
| 285 } |
285 } |
| 286 |
286 |
| 287 for (uint8_t y = 0 ; y < 8 ; y++) { |
287 for (Rank y = 0 ; y < 8 ; y++) { |
| 288 for (uint8_t x = 0 ; x < 8 ; x++) { |
288 for (File x = 0 ; x < 8 ; x++) { |
| 289 uint8_t col = gamestate->board[y][x] & COLOR_MASK; |
289 Piece piece = piece_at(gamestate, y, x); |
| 290 uint8_t piece = gamestate->board[y][x]; |
290 Color col = piece_color(piece); |
| |
291 |
| 291 char piecestr[5]; |
292 char piecestr[5]; |
| 292 if (piece) { |
293 if (piece) { |
| 293 if (settings.unicode) { |
294 if (settings.unicode) { |
| 294 char* uc = getpieceunicode(piece); |
295 char* uc = getpieceunicode(piece); |
| 295 strncpy(piecestr, uc, 5); |
296 strncpy(piecestr, uc, 5); |
| 522 static NetMove hton_move(Move move) { |
523 static NetMove hton_move(Move move) { |
| 523 return (NetMove) { |
524 return (NetMove) { |
| 524 .mtime_sec = net_htonl(move.movetime / 1000000ull), |
525 .mtime_sec = net_htonl(move.movetime / 1000000ull), |
| 525 .mtime_usec = net_htonl(move.movetime % 1000000ull), |
526 .mtime_usec = net_htonl(move.movetime % 1000000ull), |
| 526 .piece = move.piece, |
527 .piece = move.piece, |
| 527 .fromfile = move.fromfile, .fromrow = move.fromrow, |
528 .fromfile = move.fromfile, .fromrank = move.fromrank, |
| 528 .tofile = move.tofile, .torow = move.torow, |
529 .tofile = move.tofile, .torank = move.torank, |
| 529 .capture = move.capture, |
530 .capture = move.capture, |
| 530 .check_or_mate = move.checkmate + move.check, |
531 .check_or_mate = move.checkmate + move.check, |
| 531 .promotion = move.promotion, |
532 .promotion = move.promotion, |
| 532 }; |
533 }; |
| 533 } |
534 } |
| 537 .string = {0}, /* calculated before applying the move */ |
538 .string = {0}, /* calculated before applying the move */ |
| 538 .timestamp = {0}, /* planned to be removed */ |
539 .timestamp = {0}, /* planned to be removed */ |
| 539 .movetime = (uint64_t)net_ntohl(move.mtime_sec) |
540 .movetime = (uint64_t)net_ntohl(move.mtime_sec) |
| 540 * 1000000ull + net_ntohl(move.mtime_usec), |
541 * 1000000ull + net_ntohl(move.mtime_usec), |
| 541 .piece = move.piece, |
542 .piece = move.piece, |
| 542 .fromfile = move.fromfile, .fromrow = move.fromrow, |
543 .fromfile = move.fromfile, .fromrank = move.fromrank, |
| 543 .tofile = move.tofile, .torow = move.torow, |
544 .tofile = move.tofile, .torank = move.torank, |
| 544 .promotion = move.promotion, |
545 .promotion = move.promotion, |
| 545 .check = move.check_or_mate, |
546 .check = move.check_or_mate, |
| 546 .checkmate = move.check_or_mate >> 1, |
547 .checkmate = move.check_or_mate >> 1, |
| 547 .capture = move.capture |
548 .capture = move.capture |
| 548 }; |
549 }; |
| 549 } |
550 } |
| 550 |
551 |
| 551 static int sendmove(GameState *gamestate, int opponent, uint8_t mycolor) { |
552 static int sendmove(GameState *gamestate, int opponent, Color mycolor) { |
| 552 |
553 |
| 553 size_t bufpos = 0; |
554 size_t bufpos = 0; |
| 554 char movestr[MOVESTR_BUFLEN]; |
555 char movestr[MOVESTR_BUFLEN]; |
| 555 bool remis_offered = false; |
556 bool remis_offered = false; |
| 556 bool remis_rejected = false; |
557 bool remis_rejected = false; |
| 693 } |
694 } |
| 694 } |
695 } |
| 695 } |
696 } |
| 696 } |
697 } |
| 697 |
698 |
| 698 static int recvmove(GameState *gamestate, int opponent, uint8_t mycolor) { |
699 static int recvmove(GameState *gamestate, int opponent, Color mycolor) { |
| 699 memset(gamestate->premove, 0, sizeof(gamestate->premove)); |
700 memset(gamestate->premove, 0, sizeof(gamestate->premove)); |
| 700 |
701 |
| 701 size_t bufpos = 0; |
702 size_t bufpos = 0; |
| 702 char movestr[MOVESTR_BUFLEN]; |
703 char movestr[MOVESTR_BUFLEN]; |
| 703 bool remis_suggested = false, remis_offered = false; |
704 bool remis_suggested = false, remis_offered = false; |
| 958 } |
959 } |
| 959 |
960 |
| 960 static void game_play_singlemachine(GameState *gamestate) { |
961 static void game_play_singlemachine(GameState *gamestate) { |
| 961 inputy = getmaxy(stdscr) - 6; |
962 inputy = getmaxy(stdscr) - 6; |
| 962 |
963 |
| 963 uint8_t curcol = current_color(gamestate); |
964 Color curcol = current_color(gamestate); |
| 964 bool running = is_game_running(gamestate); |
965 bool running = is_game_running(gamestate); |
| 965 while (running) { |
966 while (running) { |
| 966 clear(); |
967 clear(); |
| 967 uint8_t perspective = settings.disableflip ? WHITE : curcol; |
968 Color perspective = settings.disableflip ? WHITE : curcol; |
| 968 draw_board(gamestate, perspective); |
969 draw_board(gamestate, perspective); |
| 969 running = !domove_singlemachine(gamestate, curcol); |
970 running = !domove_singlemachine(gamestate, curcol); |
| 970 curcol = opponent_color(curcol); |
971 curcol = opponent_color(curcol); |
| 971 } |
972 } |
| 972 game_review(gamestate); |
973 game_review(gamestate); |
| 973 } |
974 } |
| 974 |
975 |
| 975 static void game_play(GameState *gamestate, int opponent, bool as_client) { |
976 static void game_play(GameState *gamestate, int opponent, bool as_client) { |
| 976 inputy = getmaxy(stdscr) - 6; |
977 inputy = getmaxy(stdscr) - 6; |
| 977 |
978 |
| 978 uint8_t mycolor = gamestate->info.servercolor; |
979 Color mycolor = gamestate->info.servercolor; |
| 979 if (as_client) { |
980 if (as_client) { |
| 980 mycolor = opponent_color(mycolor); |
981 mycolor = opponent_color(mycolor); |
| 981 } |
982 } |
| 982 |
983 |
| 983 bool myturn = current_color(gamestate) == mycolor; |
984 bool myturn = current_color(gamestate) == mycolor; |