src/chess/rules.c

Tue, 28 Jul 2026 12:58:49 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 28 Jul 2026 12:58:49 +0200
changeset 157
07cbfc477b22
parent 156
05fc8a454700
child 158
52d452d0e7bf
permissions
-rw-r--r--

add FEN history to the game state

relates to #872

19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
1 /*
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
3 *
55
54ea19938d57 updated copyright and version info
Mike Becker <universe@uap-core.de>
parents: 51
diff changeset
4 * Copyright 2016 Mike Becker. All rights reserved.
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
5 *
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
8 *
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
11 *
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
15 *
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
27 *
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
28 */
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
29
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
30 #include "rules.h"
78
ceb9197b3c6d improve code structure
Mike Becker <universe@uap-core.de>
parents: 69
diff changeset
31 #include "pawn.h"
ceb9197b3c6d improve code structure
Mike Becker <universe@uap-core.de>
parents: 69
diff changeset
32 #include "rook.h"
ceb9197b3c6d improve code structure
Mike Becker <universe@uap-core.de>
parents: 69
diff changeset
33 #include "knight.h"
ceb9197b3c6d improve code structure
Mike Becker <universe@uap-core.de>
parents: 69
diff changeset
34 #include "bishop.h"
ceb9197b3c6d improve code structure
Mike Becker <universe@uap-core.de>
parents: 69
diff changeset
35 #include "queen.h"
ceb9197b3c6d improve code structure
Mike Becker <universe@uap-core.de>
parents: 69
diff changeset
36 #include "king.h"
157
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
37 #include "fen.h"
78
ceb9197b3c6d improve code structure
Mike Becker <universe@uap-core.de>
parents: 69
diff changeset
38
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
39 #include <string.h>
100
685af47592b5 add API for formatting clocks
Mike Becker <universe@uap-core.de>
parents: 99
diff changeset
40 #include <stdio.h>
23
824c9522ce66 introduced game state structure
Mike Becker <universe@uap-core.de>
parents: 21
diff changeset
41 #include <stdlib.h>
36
ebe0c961e9a6 reduced awesome great nanosecond precision so we can compile on OS X
Mike Becker <universe@uap-core.de>
parents: 33
diff changeset
42 #include <sys/time.h>
23
824c9522ce66 introduced game state structure
Mike Becker <universe@uap-core.de>
parents: 21
diff changeset
43
129
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
44 void gamestate_init(GameState *gamestate) {
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
45 memset(gamestate, 0, sizeof(GameState));
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
46
157
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
47 // TODO: implement feature - game can be started from arbitrary position
129
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
48 Board initboard = {
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
49 {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK},
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
50 {WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN},
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
51 {0, 0, 0, 0, 0, 0, 0, 0},
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
52 {0, 0, 0, 0, 0, 0, 0, 0},
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
53 {0, 0, 0, 0, 0, 0, 0, 0},
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
54 {0, 0, 0, 0, 0, 0, 0, 0},
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
55 {BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN},
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
56 {BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK}
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
57 };
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
58 memcpy(gamestate->board, initboard, sizeof(Board));
157
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
59 char fen[FEN_MAX_LENGTH];
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
60 fen_compute(fen, gamestate);
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
61 gamestate->fen_start = strdup(fen);
129
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
62 }
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
63
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
64 void gamestate_cleanup(GameState *gamestate) {
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
65 free(gamestate->moves);
157
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
66 free(gamestate->fen_start);
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
67 for (unsigned i = 0 ; i < gamestate->movecount ; i++) {
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
68 free(gamestate->fen[i]);
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
69 }
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
70 free(gamestate->fen);
129
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
71 gamestate->movecount = gamestate->movecapacity = 0;
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
72 }
189c7c77aaab simplify code structure
Mike Becker <universe@uap-core.de>
parents: 122
diff changeset
73
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
74 static GameState gamestate_copy_sim(GameState *gamestate) {
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
75 GameState simulation = *gamestate;
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 87
diff changeset
76
157
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
77 /* create new move and position lists for the simulation */
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 87
diff changeset
78 simulation.movecapacity = 4;
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 87
diff changeset
79 simulation.movecount = 0;
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 87
diff changeset
80 simulation.moves = malloc(4 * sizeof(Move));
157
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
81 simulation.fen = malloc(4 * sizeof(char*));
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 87
diff changeset
82
157
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
83 /* copy the most recent move and position if a move was played */
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 87
diff changeset
84 if (gamestate->movecount > 0) {
157
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
85 simulation.fen_start = strdup(gamestate->movecount == 1 ?
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
86 gamestate->fen_start : gamestate->fen[gamestate->movecount - 2]);
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 87
diff changeset
87 simulation.moves[0] = last_move(gamestate);
157
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
88 simulation.fen[0] = strdup(gamestate->fen[gamestate->movecount - 1]);
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 87
diff changeset
89 simulation.movecount++;
157
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
90 } else {
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
91 simulation.fen_start = strdup(gamestate->fen_start);
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
92 }
51
84f2e380a434 added support for game continuation over network + fixed major bug in checkmate anticipation when the king is attacked diagonally
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
93
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
94 return simulation;
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
95 }
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
96
133
c58ae152733e simplify FEN generation and add current_color() function to rules
Mike Becker <universe@uap-core.de>
parents: 131
diff changeset
97 uint8_t current_color(GameState *gamestate) {
c58ae152733e simplify FEN generation and add current_color() function to rules
Mike Becker <universe@uap-core.de>
parents: 131
diff changeset
98 return (gamestate->movecount % 2 == 0) ? WHITE : BLACK;
c58ae152733e simplify FEN generation and add current_color() function to rules
Mike Becker <universe@uap-core.de>
parents: 131
diff changeset
99 }
c58ae152733e simplify FEN generation and add current_color() function to rules
Mike Becker <universe@uap-core.de>
parents: 131
diff changeset
100
67
c76e46970a59 verified that checkmate notation does work correctly
Mike Becker <universe@uap-core.de>
parents: 66
diff changeset
101 /* MUST be called BETWEEN validating AND applying a move to work correctly */
49
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
102 static void format_move(GameState *gamestate, Move *move) {
66
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
103 char *string = &(move->string[0]);
49
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
104
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
105 /* at least 8 characters should be available, wipe them out */
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
106 memset(string, 0, 8);
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
107
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
108 unsigned int idx;
49
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
109 if ((move->piece&PIECE_MASK) == KING &&
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
110 abs(move->tofile-move->fromfile) == 2) {
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
111 /* special formats for castling */
49
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
112 if (move->tofile==fileidx('c')) {
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
113 memcpy(string, "O-O-O", 5);
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
114 idx = 5;
49
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
115 } else {
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
116 memcpy(string, "O-O", 3);
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
117 idx = 3;
49
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
118 }
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
119 } else {
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
120 /* start by notating the piece character */
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
121 string[0] = getpiecechr(move->piece);
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
122 idx = string[0] ? 1 : 0;
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
123
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
124 /* find out how many source information we do need */
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
125 uint8_t piece = move->piece & PIECE_MASK;
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
126 if (piece == PAWN) {
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
127 if (move->capture) {
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
128 string[idx++] = filechr(move->fromfile);
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
129 }
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
130 } else if (piece != KING) {
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
131 /* resolve ambiguities, if any */
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
132 Move threats[16];
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
133 uint8_t threatcount;
66
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
134 if (get_threats(gamestate, move->torow, move->tofile,
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
135 move->piece&COLOR_MASK, threats, &threatcount)) {
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
136 unsigned int ambrows = 0, ambfiles = 0, ambpiece = 0;
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
137 for (uint8_t i = 0 ; i < threatcount ; i++) {
66
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
138 if (threats[i].piece == move->piece) {
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
139 ambpiece++;
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
140 if (threats[i].fromrow == move->fromrow) {
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
141 ambrows++;
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
142 }
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
143 if (threats[i].fromfile == move->fromfile) {
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
144 ambfiles++;
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
145 }
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
146 }
49
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
147 }
66
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
148 /* neither file, nor row are ambiguous, name file */
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
149 if (ambpiece > 1 && ambrows == 1 && ambfiles == 1) {
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
150 /* this is most likely the case with Knights
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
151 * in diagonal opposition */
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
152 string[idx++] = filechr(move->fromfile);
66
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
153 } else {
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
154 /* ambiguous row, name file */
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
155 if (ambrows > 1) {
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
156 string[idx++] = filechr(move->fromfile);
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
157 }
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
158 /* ambiguous file, name row */
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
159 if (ambfiles > 1) {
152
231e5f07a657 fix incorrect move notation when disambiguating moves
Mike Becker <universe@uap-core.de>
parents: 151
diff changeset
160 string[idx++] = rowchr(move->fromrow);
66
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
161 }
49
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
162 }
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
163 }
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
164 }
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
165
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
166 /* capturing? */
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
167 if (move->capture) {
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
168 string[idx++] = 'x';
49
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
169 }
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
170
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
171 /* destination */
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
172 string[idx++] = filechr(move->tofile);
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
173 string[idx++] = rowchr(move->torow);
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
174
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
175 /* promotion? */
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
176 if (move->promotion) {
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
177 string[idx++] = '=';
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
178 string[idx++] = getpiecechr(move->promotion);
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
179 }
49
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
180 }
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
181
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
182 /* check? */
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
183 if (move->check) {
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
184 string[idx++] = gamestate->checkmate?'#':'+';
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
185 }
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
186 }
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
187
122
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
188 static void calc_movetime(GameState *gamestate, Move *move) {
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
189 struct timeval curtimestamp;
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
190 gettimeofday(&curtimestamp, NULL);
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
191 move->timestamp.tv_sec = curtimestamp.tv_sec;
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
192 move->timestamp.tv_usec = (int32_t) curtimestamp.tv_usec;
130
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
193 move->movetime.tv_usec = 0;
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
194 move->movetime.tv_sec = 0;
122
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
195 if (gamestate->movecount > 1) {
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
196 struct movetimeval lasttstamp = last_move(gamestate).timestamp;
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
197 uint64_t sec = curtimestamp.tv_sec - lasttstamp.tv_sec;
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
198 suseconds_t micros;
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
199 if (curtimestamp.tv_usec < lasttstamp.tv_usec) {
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
200 micros = 1000000-(lasttstamp.tv_usec - curtimestamp.tv_usec);
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
201 sec--;
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
202 } else {
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
203 micros = curtimestamp.tv_usec - lasttstamp.tv_usec;
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
204 }
130
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
205
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
206 while (micros >= 1000000) {
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
207 micros -= 1000000;
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
208 sec++;
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
209 }
122
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
210
130
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
211 if (sec >= gamestate->info.delay) {
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
212 move->movetime.tv_sec = sec;
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
213 move->movetime.tv_usec = (int32_t) micros;
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
214 }
122
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
215 }
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
216 }
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
217
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
218 char getpiecechr(uint8_t piece) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
219 switch (piece & PIECE_MASK) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
220 case ROOK: return 'R';
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
221 case KNIGHT: return 'N';
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
222 case BISHOP: return 'B';
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
223 case QUEEN: return 'Q';
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
224 case KING: return 'K';
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
225 default: return '\0';
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
226 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
227 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
228
87
d4d67105d4e1 minor code improvements
Mike Becker <universe@uap-core.de>
parents: 80
diff changeset
229 char* getpieceunicode(uint8_t piece) {
110
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
230 if ((piece & COLOR_MASK) == WHITE) {
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
231 switch (piece & PIECE_MASK) {
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
232 case PAWN: return "\u2659";
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
233 case ROOK: return "\u2656";
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
234 case KNIGHT: return "\u2658";
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
235 case BISHOP: return "\u2657";
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
236 case QUEEN: return "\u2655";
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
237 case KING: return "\u2654";
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
238 default: return "";
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
239 }
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
240 } else {
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
241 switch (piece & PIECE_MASK) {
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
242 case PAWN: return "\u265f";
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
243 case ROOK: return "\u265c";
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
244 case KNIGHT: return "\u265e";
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
245 case BISHOP: return "\u265d";
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
246 case QUEEN: return "\u265b";
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
247 case KING: return "\u265a";
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
248 default: return "";
e2bb03494d46 correctly use unicode chars for white pieces
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
249 }
69
c8f2c280cff7 adds unicode support
Mike Becker <universe@uap-core.de>
parents: 68
diff changeset
250 }
c8f2c280cff7 adds unicode support
Mike Becker <universe@uap-core.de>
parents: 68
diff changeset
251 }
c8f2c280cff7 adds unicode support
Mike Becker <universe@uap-core.de>
parents: 68
diff changeset
252
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
253 uint8_t getpiece(char c) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
254 switch (c) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
255 case 'R': return ROOK;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
256 case 'N': return KNIGHT;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
257 case 'B': return BISHOP;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
258 case 'Q': return QUEEN;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
259 case 'K': return KING;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
260 default: return 0;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
261 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
262 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
263
139
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
264 // TODO: check if we really need this "simulate" flag for performance
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
265 static void apply_move_impl(GameState *gamestate, Move *move, bool simulate) {
66
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
266 /* format move before moving (s.t. ambiguities can be resolved) */
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
267 if (!simulate) {
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
268 if (!move->string[0]) {
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
269 format_move(gamestate, move);
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
270 }
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
271 }
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
272
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
273 uint8_t piece = move->piece & PIECE_MASK;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
274 uint8_t color = move->piece & COLOR_MASK;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
275
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
276 /* en passant capture */
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
277 if (move->capture && piece == PAWN &&
23
824c9522ce66 introduced game state structure
Mike Becker <universe@uap-core.de>
parents: 21
diff changeset
278 mdst(gamestate->board, move) == 0) {
824c9522ce66 introduced game state structure
Mike Becker <universe@uap-core.de>
parents: 21
diff changeset
279 gamestate->board[move->fromrow][move->tofile] = 0;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
280 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
281
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
282 /* remove old en passant threats */
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
283 for (uint8_t file = 0 ; file < 8 ; file++) {
23
824c9522ce66 introduced game state structure
Mike Becker <universe@uap-core.de>
parents: 21
diff changeset
284 gamestate->board[3][file] &= ~ENPASSANT_THREAT;
824c9522ce66 introduced game state structure
Mike Becker <universe@uap-core.de>
parents: 21
diff changeset
285 gamestate->board[4][file] &= ~ENPASSANT_THREAT;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
286 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
287
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
288 /* add new en passant threat */
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
289 if (piece == PAWN && (
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
290 (move->fromrow == 1 && move->torow == 3) ||
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
291 (move->fromrow == 6 && move->torow == 4))) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
292 move->piece |= ENPASSANT_THREAT;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
293 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
294
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
295 /* move (and maybe capture or promote) */
23
824c9522ce66 introduced game state structure
Mike Becker <universe@uap-core.de>
parents: 21
diff changeset
296 msrc(gamestate->board, move) = 0;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
297 if (move->promotion) {
23
824c9522ce66 introduced game state structure
Mike Becker <universe@uap-core.de>
parents: 21
diff changeset
298 mdst(gamestate->board, move) = move->promotion;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
299 } else {
23
824c9522ce66 introduced game state structure
Mike Becker <universe@uap-core.de>
parents: 21
diff changeset
300 mdst(gamestate->board, move) = move->piece;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
301 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
302
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
303 /* castling */
49
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
304 if (piece == KING && move->fromfile == fileidx('e')) {
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
305 if (move->tofile == fileidx('g')) {
23
824c9522ce66 introduced game state structure
Mike Becker <universe@uap-core.de>
parents: 21
diff changeset
306 gamestate->board[move->torow][fileidx('h')] = 0;
824c9522ce66 introduced game state structure
Mike Becker <universe@uap-core.de>
parents: 21
diff changeset
307 gamestate->board[move->torow][fileidx('f')] = color|ROOK;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
308 } else if (move->tofile == fileidx('c')) {
23
824c9522ce66 introduced game state structure
Mike Becker <universe@uap-core.de>
parents: 21
diff changeset
309 gamestate->board[move->torow][fileidx('a')] = 0;
824c9522ce66 introduced game state structure
Mike Becker <universe@uap-core.de>
parents: 21
diff changeset
310 gamestate->board[move->torow][fileidx('d')] = color|ROOK;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
311 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
312 }
66
f5cc75565f7c fixes ambiguity resolver in PGN output not resolving ambiguities for diagonally attacking Knights
Mike Becker <universe@uap-core.de>
parents: 64
diff changeset
313
157
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
314 /* add move to the moves array and the new position to the FEN array */
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
315 if (gamestate->movecount == gamestate->movecapacity) {
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
316 gamestate->movecapacity += 64; /* 32 more full moves */
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
317 gamestate->moves = realloc(gamestate->moves,
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
318 gamestate->movecapacity * sizeof(Move));
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
319 gamestate->fen = realloc(gamestate->fen,
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
320 gamestate->movecapacity * sizeof(char*));
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
321 }
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
322
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
323 /* copy the move data into the game's move array */
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
324 Move *melem = &gamestate->moves[gamestate->movecount];
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
325 *melem = *move;
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
326
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
327 /* calculate the FEN and store it in the FEN array */
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
328 char fen[FEN_MAX_LENGTH];
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
329 fen_compute(fen, gamestate);
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
330 gamestate->fen[gamestate->movecount] = strdup(fen);
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
331
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
332 /* only if move has no time info, compute it */
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
333 if (melem->movetime.tv_sec == 0 && melem->movetime.tv_usec == 0) {
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
334 calc_movetime(gamestate, melem);
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
335 }
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
336
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
337 /* important: only "add" the move after calculating the time! */
07cbfc477b22 add FEN history to the game state
Mike Becker <universe@uap-core.de>
parents: 156
diff changeset
338 gamestate->movecount++;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
339 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
340
49
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
341 void apply_move(GameState *gamestate, Move *move) {
122
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
342 apply_move_impl(gamestate, move, false);
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
343 }
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
344
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
345 void gamestate_at_move(GameState *gamestate,
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
346 unsigned move_number, GameState *replay) {
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
347 gamestate_init(replay);
130
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
348 memcpy(&replay->info, &gamestate->info, sizeof(GameInfo));
122
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
349 replay->review = true;
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
350 if (move_number > gamestate->movecount) {
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
351 move_number = gamestate->movecount;
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
352 }
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
353 for (unsigned i = 0 ; i < move_number ; i++) {
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
354 apply_move_impl(replay, &(gamestate->moves[i]), true);
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
355 }
49
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
356 }
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
357
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
358 static int validate_move_rules(GameState *gamestate, Move *move) {
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
359 /* validate indices (don't trust opponent) */
153
bad2d6d4b861 fix wrong error message when move indices are invalid
Mike Becker <universe@uap-core.de>
parents: 152
diff changeset
360 if (!isidx(move->fromrow) || !isidx(move->fromfile) ||
bad2d6d4b861 fix wrong error message when move indices are invalid
Mike Becker <universe@uap-core.de>
parents: 152
diff changeset
361 !isidx(move->torow) || !isidx(move->tofile)) {
bad2d6d4b861 fix wrong error message when move indices are invalid
Mike Becker <universe@uap-core.de>
parents: 152
diff changeset
362 return INVALID_MOVE_SYNTAX;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
363 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
364
21
2e5846019b4f implemented rook + some fixes
Mike Becker <universe@uap-core.de>
parents: 19
diff changeset
365 /* must move */
2e5846019b4f implemented rook + some fixes
Mike Becker <universe@uap-core.de>
parents: 19
diff changeset
366 if (move->fromfile == move->tofile && move->fromrow == move->torow) {
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
367 return INVALID_MOVE_SYNTAX;
21
2e5846019b4f implemented rook + some fixes
Mike Becker <universe@uap-core.de>
parents: 19
diff changeset
368 }
2e5846019b4f implemented rook + some fixes
Mike Becker <universe@uap-core.de>
parents: 19
diff changeset
369
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
370 /* does piece exist */
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
371 if ((msrc(gamestate->board, move)&(PIECE_MASK|COLOR_MASK))
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
372 != (move->piece&(PIECE_MASK|COLOR_MASK))) {
154
5336e985bd69 rename INVALID_POSITION to PIECE_NOT_FOUND
Mike Becker <universe@uap-core.de>
parents: 153
diff changeset
373 return PIECE_NOT_FOUND;
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
374 }
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
375
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
376 /* can't capture own pieces */
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
377 if ((mdst(gamestate->board, move) & COLOR_MASK)
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
378 == (move->piece & COLOR_MASK)) {
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
379 return RULES_VIOLATED;
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
380 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
381
151
f1b6a0388d85 fix that en passant captures do not work
Mike Becker <universe@uap-core.de>
parents: 147
diff changeset
382 /* must capture, if and only if destination is occupied... */
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
383 if ((mdst(gamestate->board, move) == 0 && move->capture) ||
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
384 (mdst(gamestate->board, move) != 0 && !move->capture)) {
151
f1b6a0388d85 fix that en passant captures do not work
Mike Becker <universe@uap-core.de>
parents: 147
diff changeset
385 /* ... or the capture happens en passant */
f1b6a0388d85 fix that en passant captures do not work
Mike Becker <universe@uap-core.de>
parents: 147
diff changeset
386 if (!move->capture || (move->piece & PIECE_MASK) != PAWN ||
f1b6a0388d85 fix that en passant captures do not work
Mike Becker <universe@uap-core.de>
parents: 147
diff changeset
387 !(gamestate->board[move->fromrow][move->tofile]
f1b6a0388d85 fix that en passant captures do not work
Mike Becker <universe@uap-core.de>
parents: 147
diff changeset
388 & ENPASSANT_THREAT)) {
f1b6a0388d85 fix that en passant captures do not work
Mike Becker <universe@uap-core.de>
parents: 147
diff changeset
389 return INVALID_MOVE_SYNTAX;
f1b6a0388d85 fix that en passant captures do not work
Mike Becker <universe@uap-core.de>
parents: 147
diff changeset
390 }
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
391 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
392
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
393 /* validate individual rules */
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
394 bool chkrules;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
395 switch (move->piece & PIECE_MASK) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
396 case PAWN:
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
397 chkrules = pawn_chkrules(gamestate, move) &&
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
398 !pawn_isblocked(gamestate, move);
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
399 break;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
400 case ROOK:
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
401 chkrules = rook_chkrules(move) &&
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
402 !rook_isblocked(gamestate, move);
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
403 break;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
404 case KNIGHT:
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
405 chkrules = knight_chkrules(move); /* knight is never blocked */
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
406 break;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
407 case BISHOP:
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
408 chkrules = bishop_chkrules(move) &&
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
409 !bishop_isblocked(gamestate, move);
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
410 break;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
411 case QUEEN:
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
412 chkrules = queen_chkrules(move) &&
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
413 !queen_isblocked(gamestate, move);
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
414 break;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
415 case KING:
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
416 chkrules = king_chkrules(gamestate, move) &&
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
417 !king_isblocked(gamestate, move);
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
418 break;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
419 default:
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
420 return INVALID_MOVE_SYNTAX;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
421 }
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
422
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
423 return chkrules ? VALID_MOVE_SEMANTICS : RULES_VIOLATED;
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
424 }
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
425
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
426 int validate_move(GameState *gamestate, Move *move) {
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
427
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
428 int result = validate_move_rules(gamestate, move);
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
429
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
430 /* cancel processing to save resources */
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
431 if (result != VALID_MOVE_SEMANTICS) {
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
432 return result;
25
3ab0c2e1a4e2 implemented king
Mike Becker <universe@uap-core.de>
parents: 23
diff changeset
433 }
3ab0c2e1a4e2 implemented king
Mike Becker <universe@uap-core.de>
parents: 23
diff changeset
434
62
564af8a16828 fixes move validation working on old king's position, when the king moves
Mike Becker <universe@uap-core.de>
parents: 55
diff changeset
435 /* simulate move for check validation */
564af8a16828 fixes move validation working on old king's position, when the king moves
Mike Becker <universe@uap-core.de>
parents: 55
diff changeset
436 GameState simulation = gamestate_copy_sim(gamestate);
564af8a16828 fixes move validation working on old king's position, when the king moves
Mike Becker <universe@uap-core.de>
parents: 55
diff changeset
437 Move simmove = *move;
122
e65d9b5e9324 implement interactive game review
Mike Becker <universe@uap-core.de>
parents: 115
diff changeset
438 apply_move_impl(&simulation, &simmove, true);
62
564af8a16828 fixes move validation working on old king's position, when the king moves
Mike Becker <universe@uap-core.de>
parents: 55
diff changeset
439
28
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
440 /* find kings for check validation */
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
441 uint8_t piececolor = (move->piece & COLOR_MASK);
136
1a84ee6b4bf0 start fixing issue #895
Mike Becker <universe@uap-core.de>
parents: 135
diff changeset
442 uint8_t oppcolor = opponent_color(piececolor);
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
443
28
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
444 uint8_t mykingfile = 0, mykingrow = 0, opkingfile = 0, opkingrow = 0;
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
445 for (uint8_t row = 0 ; row < 8 ; row++) {
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
446 for (uint8_t file = 0 ; file < 8 ; file++) {
62
564af8a16828 fixes move validation working on old king's position, when the king moves
Mike Becker <universe@uap-core.de>
parents: 55
diff changeset
447 if (simulation.board[row][file] ==
28
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
448 (piececolor == WHITE?WKING:BKING)) {
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
449 mykingfile = file;
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
450 mykingrow = row;
62
564af8a16828 fixes move validation working on old king's position, when the king moves
Mike Becker <universe@uap-core.de>
parents: 55
diff changeset
451 } else if (simulation.board[row][file] ==
28
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
452 (piececolor == WHITE?BKING:WKING)) {
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
453 opkingfile = file;
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
454 opkingrow = row;
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
455 }
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
456 }
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
457 }
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
458
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
459 /* don't move into or stay in check position */
136
1a84ee6b4bf0 start fixing issue #895
Mike Becker <universe@uap-core.de>
parents: 135
diff changeset
460 if (is_covered(&simulation, mykingrow, mykingfile, oppcolor)) {
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
461 gamestate_cleanup(&simulation);
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
462 if ((move->piece & PIECE_MASK) == KING) {
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
463 return KING_MOVES_INTO_CHECK;
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
464 } else {
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
465 /* last move is always not null in this case */
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 87
diff changeset
466 return last_move(gamestate).check ?
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
467 KING_IN_CHECK : PIECE_PINNED;
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
468 }
28
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
469 }
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
470
25
3ab0c2e1a4e2 implemented king
Mike Becker <universe@uap-core.de>
parents: 23
diff changeset
471 /* correct check and checkmate flags (move is still valid) */
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
472 Move threats[16];
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
473 uint8_t threatcount;
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
474 move->check = get_threats(&simulation, opkingrow, opkingfile,
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
475 piececolor, threats, &threatcount);
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
476
28
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
477 if (move->check) {
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
478 /* determine possible escape fields */
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
479 bool canescape = false;
28
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
480 for (int dr = -1 ; dr <= 1 && !canescape ; dr++) {
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
481 for (int df = -1 ; df <= 1 && !canescape ; df++) {
139
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
482 if (dr == 0 && df == 0) continue;
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
483 if (!isidx(opkingrow + dr)) continue;
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
484 if (!isidx(opkingfile + df)) continue;
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
485 uint8_t er = opkingrow + dr;
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
486 uint8_t ef = opkingfile + df;
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
487
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
488 /* check if escape field is already covered (threatened) */
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
489 if (is_covered(&simulation, er, ef, piececolor))
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
490 continue;
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
491
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
492 /* check if piece of the king's color blocks the field */
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
493 if ((simulation.board[er][ef] & COLOR_MASK) == oppcolor)
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
494 continue;
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
495
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
496 /* check if an attacking piece blocks the field */
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
497 if ((simulation.board[er][ef] & COLOR_MASK) == piececolor) {
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
498 /* test if the king can fight back */
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
499 GameState sim_retaliate = gamestate_copy_sim(&simulation);
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
500 Move move_retaliate = {0};
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
501 move_retaliate.piece = (oppcolor|KING);
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
502 move_retaliate.fromrow = opkingrow;
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
503 move_retaliate.fromfile = opkingfile;
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
504 move_retaliate.torow = er;
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
505 move_retaliate.tofile = ef;
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
506 move_retaliate.capture = 1;
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
507 apply_move_impl(&sim_retaliate, &move_retaliate, true);
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
508 canescape = !is_covered(&sim_retaliate, er, ef, piececolor);
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
509 gamestate_cleanup(&sim_retaliate);
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
510 } else {
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
511 /* the field is not covered and unoccupied */
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
512 canescape = true;
28
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
513 }
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
514 }
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
515 }
139
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
516
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
517 /* can't escape, can the king be rescued? */
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
518 if (!canescape && threatcount == 1) {
139
fa10bee331ac fix checkmate detection
Mike Becker <universe@uap-core.de>
parents: 137
diff changeset
519 canescape = is_protected(&simulation,
136
1a84ee6b4bf0 start fixing issue #895
Mike Becker <universe@uap-core.de>
parents: 135
diff changeset
520 threats[0].fromrow, threats[0].fromfile, oppcolor);
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
521 }
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
522
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
523 /* can't capture, can he block? */
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
524 if (!canescape && threatcount == 1) {
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
525 Move *threat = &(threats[0]);
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
526 uint8_t threatpiece = threat->piece & PIECE_MASK;
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
527
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
528 /* knight, pawns and the king cannot be blocked */
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
529 if (threatpiece == BISHOP || threatpiece == ROOK
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
530 || threatpiece == QUEEN) {
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
531 if (threat->fromrow == threat->torow) {
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
532 /* rook aspect (on row) */
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
533 int d = threat->tofile > threat->fromfile ? 1 : -1;
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
534 uint8_t file = threat->fromfile;
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
535 while (!canescape && file != threat->tofile - d) {
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
536 file += d;
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
537 canescape |= is_protected(&simulation,
136
1a84ee6b4bf0 start fixing issue #895
Mike Becker <universe@uap-core.de>
parents: 135
diff changeset
538 threat->torow, file, oppcolor);
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
539 }
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
540 } else if (threat->fromfile == threat->tofile) {
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
541 /* rook aspect (on file) */
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
542 int d = threat->torow > threat->fromrow ? 1 : -1;
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
543 uint8_t row = threat->fromrow;
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
544 while (!canescape && row != threat->torow - d) {
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
545 row += d;
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
546 canescape |= is_protected(&simulation,
136
1a84ee6b4bf0 start fixing issue #895
Mike Becker <universe@uap-core.de>
parents: 135
diff changeset
547 row, threat->tofile, oppcolor);
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
548 }
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
549 } else {
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
550 /* bishop aspect */
51
84f2e380a434 added support for game continuation over network + fixed major bug in checkmate anticipation when the king is attacked diagonally
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
551 int dr = threat->torow > threat->fromrow ? 1 : -1;
84f2e380a434 added support for game continuation over network + fixed major bug in checkmate anticipation when the king is attacked diagonally
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
552 int df = threat->tofile > threat->fromfile ? 1 : -1;
28
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
553
51
84f2e380a434 added support for game continuation over network + fixed major bug in checkmate anticipation when the king is attacked diagonally
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
554 uint8_t row = threat->fromrow;
84f2e380a434 added support for game continuation over network + fixed major bug in checkmate anticipation when the king is attacked diagonally
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
555 uint8_t file = threat->fromfile;
84f2e380a434 added support for game continuation over network + fixed major bug in checkmate anticipation when the king is attacked diagonally
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
556 while (!canescape && file != threat->tofile - df
84f2e380a434 added support for game continuation over network + fixed major bug in checkmate anticipation when the king is attacked diagonally
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
557 && row != threat->torow - dr) {
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
558 row += dr;
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
559 file += df;
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
560 canescape |= is_protected(&simulation, row, file,
136
1a84ee6b4bf0 start fixing issue #895
Mike Becker <universe@uap-core.de>
parents: 135
diff changeset
561 oppcolor);
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
562 }
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
563 }
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
564 }
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
565 }
28
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
566
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
567 if (!canescape) {
136
1a84ee6b4bf0 start fixing issue #895
Mike Becker <universe@uap-core.de>
parents: 135
diff changeset
568 gamestate->checkmate = true;
28
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
569 }
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
570 }
0c1371488d87 NEED TESTING: implemented check and checkmate - TODO: avoid checkmate by moving another piece in between
Mike Becker <universe@uap-core.de>
parents: 27
diff changeset
571
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
572 gamestate_cleanup(&simulation);
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
573
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
574 return VALID_MOVE_SEMANTICS;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
575 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
576
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
577 bool get_threats(GameState *gamestate, uint8_t row, uint8_t file,
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
578 uint8_t color, Move *threats, uint8_t *threatcount) {
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
579 Move candidates[32];
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
580 int candidatecount = 0;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
581 for (uint8_t r = 0 ; r < 8 ; r++) {
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
582 for (uint8_t f = 0 ; f < 8 ; f++) {
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
583 if ((gamestate->board[r][f] & COLOR_MASK) == color) {
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
584 /* non-capturing move */
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
585 memset(&(candidates[candidatecount]), 0, sizeof(Move));
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
586 candidates[candidatecount].piece = gamestate->board[r][f];
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
587 candidates[candidatecount].fromrow = r;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
588 candidates[candidatecount].fromfile = f;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
589 candidates[candidatecount].torow = row;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
590 candidates[candidatecount].tofile = file;
135
114e764fbae5 fixes #893 - pawn could not promote
Mike Becker <universe@uap-core.de>
parents: 133
diff changeset
591 if ((gamestate->board[r][f]&PIECE_MASK) == PAWN
114e764fbae5 fixes #893 - pawn could not promote
Mike Becker <universe@uap-core.de>
parents: 133
diff changeset
592 && (row == 0 || row == 7)) {
114e764fbae5 fixes #893 - pawn could not promote
Mike Becker <universe@uap-core.de>
parents: 133
diff changeset
593 /* the exact piece for promotion does not matter */
114e764fbae5 fixes #893 - pawn could not promote
Mike Becker <universe@uap-core.de>
parents: 133
diff changeset
594 candidates[candidatecount].promotion = color|QUEEN;
114e764fbae5 fixes #893 - pawn could not promote
Mike Becker <universe@uap-core.de>
parents: 133
diff changeset
595 }
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
596 candidatecount++;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
597
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
598 /* capturing move */
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
599 memcpy(&(candidates[candidatecount]),
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
600 &(candidates[candidatecount-1]), sizeof(Move));
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
601 candidates[candidatecount].capture = 1;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
602 candidatecount++;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
603 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
604 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
605 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
606
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
607 if (threatcount) {
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
608 *threatcount = 0;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
609 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
610
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
611
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
612 bool result = false;
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
613
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
614 for (int i = 0 ; i < candidatecount ; i++) {
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
615 if (validate_move_rules(gamestate, &(candidates[i]))
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
616 == VALID_MOVE_SEMANTICS) {
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
617 result = true;
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
618 if (threats && threatcount) {
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
619 threats[(*threatcount)++] = candidates[i];
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
620 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
621 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
622 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
623
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
624 return result;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
625 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
626
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
627 bool is_pinned(GameState *gamestate, Move *move) {
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
628 uint8_t color = move->piece & COLOR_MASK;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
629
62
564af8a16828 fixes move validation working on old king's position, when the king moves
Mike Becker <universe@uap-core.de>
parents: 55
diff changeset
630 GameState simulation = gamestate_copy_sim(gamestate);
564af8a16828 fixes move validation working on old king's position, when the king moves
Mike Becker <universe@uap-core.de>
parents: 55
diff changeset
631 Move simmove = *move;
564af8a16828 fixes move validation working on old king's position, when the king moves
Mike Becker <universe@uap-core.de>
parents: 55
diff changeset
632 apply_move(&simulation, &simmove);
564af8a16828 fixes move validation working on old king's position, when the king moves
Mike Becker <universe@uap-core.de>
parents: 55
diff changeset
633
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
634 uint8_t kingfile = 0, kingrow = 0;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
635 for (uint8_t row = 0 ; row < 8 ; row++) {
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
636 for (uint8_t file = 0 ; file < 8 ; file++) {
62
564af8a16828 fixes move validation working on old king's position, when the king moves
Mike Becker <universe@uap-core.de>
parents: 55
diff changeset
637 if (simulation.board[row][file] == (color|KING)) {
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
638 kingfile = file;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
639 kingrow = row;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
640 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
641 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
642 }
62
564af8a16828 fixes move validation working on old king's position, when the king moves
Mike Becker <universe@uap-core.de>
parents: 55
diff changeset
643
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
644 bool covered = is_covered(&simulation,
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
645 kingrow, kingfile, opponent_color(color));
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
646 gamestate_cleanup(&simulation);
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
647
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
648 return covered;
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
649 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
650
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
651 bool get_real_threats(GameState *gamestate, uint8_t row, uint8_t file,
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
652 uint8_t color, Move *threats, uint8_t *threatcount) {
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
653
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
654 if (threatcount) {
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
655 *threatcount = 0;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
656 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
657
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
658 Move candidates[16];
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
659 uint8_t candidatecount;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
660 if (get_threats(gamestate, row, file, color, candidates, &candidatecount)) {
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
661
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
662 bool result = false;
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
663 uint8_t kingfile = 0, kingrow = 0;
87
d4d67105d4e1 minor code improvements
Mike Becker <universe@uap-core.de>
parents: 80
diff changeset
664 for (uint8_t r = 0 ; r < 8 ; r++) {
d4d67105d4e1 minor code improvements
Mike Becker <universe@uap-core.de>
parents: 80
diff changeset
665 for (uint8_t f = 0 ; f < 8 ; f++) {
d4d67105d4e1 minor code improvements
Mike Becker <universe@uap-core.de>
parents: 80
diff changeset
666 if (gamestate->board[r][f] == (color|KING)) {
d4d67105d4e1 minor code improvements
Mike Becker <universe@uap-core.de>
parents: 80
diff changeset
667 kingfile = f;
d4d67105d4e1 minor code improvements
Mike Becker <universe@uap-core.de>
parents: 80
diff changeset
668 kingrow = r;
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
669 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
670 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
671 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
672
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
673 for (uint8_t i = 0 ; i < candidatecount ; i++) {
137
43d1b3c33369 fix memory leak when simulating real threats
Mike Becker <universe@uap-core.de>
parents: 136
diff changeset
674 // TODO: check if we really need full-blown simulations here
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
675 GameState simulation = gamestate_copy_sim(gamestate);
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
676 Move simmove = candidates[i];
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
677 apply_move(&simulation, &simmove);
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
678 if (!is_covered(&simulation, kingrow, kingfile,
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
679 opponent_color(color))) {
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
680 result = true;
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
681 if (threats && threatcount) {
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
682 threats[(*threatcount)++] = candidates[i];
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
683 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
684 }
137
43d1b3c33369 fix memory leak when simulating real threats
Mike Becker <universe@uap-core.de>
parents: 136
diff changeset
685 gamestate_cleanup(&simulation);
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
686 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
687
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
688 return result;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
689 } else {
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
690 return false;
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
691 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
692 }
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
693
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
694 static int getlocation(GameState *gamestate, Move *move) {
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
695
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
696 uint8_t color = move->piece & COLOR_MASK;
68
b34de5ce7d0e error message when syntactically validating a King's move into a check position is now correct
Mike Becker <universe@uap-core.de>
parents: 67
diff changeset
697 uint8_t piece = move->piece & PIECE_MASK;
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 87
diff changeset
698 bool incheck = gamestate->movecount > 0 ? last_move(gamestate).check:false;
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
699
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
700 Move threats[16], *threat = NULL;
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
701 uint8_t threatcount;
135
114e764fbae5 fixes #893 - pawn could not promote
Mike Becker <universe@uap-core.de>
parents: 133
diff changeset
702
156
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
703 /* determine all threats and sort out the unreal threats on our own */
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
704 if (get_threats(gamestate, move->torow, move->tofile, color,
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
705 threats, &threatcount)) {
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
706
156
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
707 bool found = false;
49
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
708
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
709 /* find threats for the specified position */
156
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
710 for (uint8_t i = 0 ; i < threatcount ; i++) {
135
114e764fbae5 fixes #893 - pawn could not promote
Mike Becker <universe@uap-core.de>
parents: 133
diff changeset
711 if (threats[i].piece == move->piece &&
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
712 (move->fromrow == POS_UNSPECIFIED ||
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
713 move->fromrow == threats[i].fromrow) &&
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
714 (move->fromfile == POS_UNSPECIFIED ||
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
715 move->fromfile == threats[i].fromfile)) {
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
716
156
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
717 /* found a threat, here it does not matter if it's valid! */
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
718 found = true;
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
719
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
720 /* discard pinned pieces */
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
721 if (!is_pinned(gamestate, &(threats[i]))) {
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
722 if (threat) {
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
723 /* we've already found a valid threat */
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
724 return AMBIGUOUS_MOVE;
49
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
725 } else {
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
726 threat = &(threats[i]);
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
727 }
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
728 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
729 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
730 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
731
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 63
diff changeset
732 /* can't threaten specified position */
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
733 if (!threat) {
156
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
734 if (found) {
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
735 if (piece == KING) {
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
736 return KING_MOVES_INTO_CHECK;
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
737 } else if (incheck) {
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
738 return KING_IN_CHECK;
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
739 } else {
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
740 return PIECE_PINNED;
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
741 }
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
742 } else {
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
743 return PIECE_NOT_FOUND;
05fc8a454700 fix: wrong error code when king moves into check and missing auto-disambiguation when one of the candidate pieces is pinned
Mike Becker <universe@uap-core.de>
parents: 155
diff changeset
744 }
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
745 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
746
135
114e764fbae5 fixes #893 - pawn could not promote
Mike Becker <universe@uap-core.de>
parents: 133
diff changeset
747 /* found a threat, copy the source location */
114e764fbae5 fixes #893 - pawn could not promote
Mike Becker <universe@uap-core.de>
parents: 133
diff changeset
748 move->fromrow = threat->fromrow;
114e764fbae5 fixes #893 - pawn could not promote
Mike Becker <universe@uap-core.de>
parents: 133
diff changeset
749 move->fromfile = threat->fromfile;
49
02c509a44e98 logging string representation of moves in short algebraic notation
Mike Becker <universe@uap-core.de>
parents: 48
diff changeset
750 return VALID_MOVE_SYNTAX;
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
751 } else {
154
5336e985bd69 rename INVALID_POSITION to PIECE_NOT_FOUND
Mike Becker <universe@uap-core.de>
parents: 153
diff changeset
752 return PIECE_NOT_FOUND;
47
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
753 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
754 }
d726e4b46c33 refactoring of getlocation mechanism for better short algebraic notation support (does now respect pinned pieces) + fixed a bug where a pawn could advance through a piece (e.g. e2e4 could jump over a piece on e3)
Mike Becker <universe@uap-core.de>
parents: 40
diff changeset
755
147
7e3f2d462bb6 make eval_move() and check_move() not change their input string
Mike Becker <universe@uap-core.de>
parents: 144
diff changeset
756 static int eval_move1(const char *pstr, Move *move, uint8_t color) {
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
757 memset(move, 0, sizeof(Move));
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
758 move->fromfile = POS_UNSPECIFIED;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
759 move->fromrow = POS_UNSPECIFIED;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
760
147
7e3f2d462bb6 make eval_move() and check_move() not change their input string
Mike Becker <universe@uap-core.de>
parents: 144
diff changeset
761 size_t len = strlen(pstr);
48
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
762 if (len < 1 || len > 6) {
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
763 return INVALID_MOVE_SYNTAX;
0cedda2544da added return code to move validation (for more informative messages) + fixed a bug where simulations added movelist items to the original gamestate
Mike Becker <universe@uap-core.de>
parents: 47
diff changeset
764 }
147
7e3f2d462bb6 make eval_move() and check_move() not change their input string
Mike Becker <universe@uap-core.de>
parents: 144
diff changeset
765 char mstr[8];
7e3f2d462bb6 make eval_move() and check_move() not change their input string
Mike Becker <universe@uap-core.de>
parents: 144
diff changeset
766 strcpy(mstr, pstr);
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
767
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
768 /* evaluate check/checkmate flags */
144
c3ae96ed44d1 fix that checkmate notation did not set the check flag in the move
Mike Becker <universe@uap-core.de>
parents: 139
diff changeset
769 if (mstr[len-1] == '+' || mstr[len-1] == '#') {
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
770 len--; mstr[len] = '\0';
144
c3ae96ed44d1 fix that checkmate notation did not set the check flag in the move
Mike Becker <universe@uap-core.de>
parents: 139
diff changeset
771 move->check = true;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
772 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
773
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
774 /* evaluate promotion */
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
775 if (len > 3 && mstr[len-2] == '=') {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
776 move->promotion = getpiece(mstr[len-1]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
777 if (!move->promotion) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
778 return INVALID_MOVE_SYNTAX;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
779 } else {
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents: 49
diff changeset
780 move->promotion |= color;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
781 len -= 2;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
782 mstr[len] = 0;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
783 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
784 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
785
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
786 if (len == 2) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
787 /* pawn move (e.g. "e4") */
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
788 move->piece = PAWN;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
789 move->tofile = fileidx(mstr[0]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
790 move->torow = rowidx(mstr[1]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
791 } else if (len == 3) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
792 if (strcmp(mstr, "O-O") == 0) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
793 /* king side castling */
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
794 move->piece = KING;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
795 move->fromfile = fileidx('e');
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
796 move->tofile = fileidx('g');
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents: 49
diff changeset
797 move->fromrow = move->torow = color == WHITE ? 0 : 7;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
798 } else {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
799 /* move (e.g. "Nf3") */
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
800 move->piece = getpiece(mstr[0]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
801 move->tofile = fileidx(mstr[1]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
802 move->torow = rowidx(mstr[2]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
803 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
804 } else if (len == 4) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
805 move->piece = getpiece(mstr[0]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
806 if (!move->piece) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
807 move->piece = PAWN;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
808 move->fromfile = fileidx(mstr[0]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
809 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
810 if (mstr[1] == 'x') {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
811 /* capture (e.g. "Nxf3", "dxe5") */
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
812 move->capture = 1;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
813 } else {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
814 /* move (e.g. "Ndf3", "N2c3", "e2e4") */
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
815 if (isfile(mstr[1])) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
816 move->fromfile = fileidx(mstr[1]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
817 if (move->piece == PAWN) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
818 move->piece = 0;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
819 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
820 } else {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
821 move->fromrow = rowidx(mstr[1]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
822 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
823 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
824 move->tofile = fileidx(mstr[2]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
825 move->torow = rowidx(mstr[3]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
826 } else if (len == 5) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
827 if (strcmp(mstr, "O-O-O") == 0) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
828 /* queen side castling "O-O-O" */
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
829 move->piece = KING;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
830 move->fromfile = fileidx('e');
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
831 move->tofile = fileidx('c');
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents: 49
diff changeset
832 move->fromrow = move->torow = color == WHITE ? 0 : 7;
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
833 } else {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
834 move->piece = getpiece(mstr[0]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
835 if (mstr[2] == 'x') {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
836 move->capture = 1;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
837 if (move->piece) {
155
835776e0338f fix: disambiguation by row while capturing was not implemented
Mike Becker <universe@uap-core.de>
parents: 154
diff changeset
838 /* capture (e.g. "Ndxf3" or "R1xh3") */
835776e0338f fix: disambiguation by row while capturing was not implemented
Mike Becker <universe@uap-core.de>
parents: 154
diff changeset
839 if (isfile(mstr[1])) {
835776e0338f fix: disambiguation by row while capturing was not implemented
Mike Becker <universe@uap-core.de>
parents: 154
diff changeset
840 move->fromfile = fileidx(mstr[1]);
835776e0338f fix: disambiguation by row while capturing was not implemented
Mike Becker <universe@uap-core.de>
parents: 154
diff changeset
841 } else if (isrow(mstr[1])) {
835776e0338f fix: disambiguation by row while capturing was not implemented
Mike Becker <universe@uap-core.de>
parents: 154
diff changeset
842 move->fromrow = rowidx(mstr[1]);
835776e0338f fix: disambiguation by row while capturing was not implemented
Mike Becker <universe@uap-core.de>
parents: 154
diff changeset
843 } else {
835776e0338f fix: disambiguation by row while capturing was not implemented
Mike Becker <universe@uap-core.de>
parents: 154
diff changeset
844 return INVALID_MOVE_SYNTAX;
835776e0338f fix: disambiguation by row while capturing was not implemented
Mike Becker <universe@uap-core.de>
parents: 154
diff changeset
845 }
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
846 } else {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
847 /* long notation capture (e.g. "e5xf6") */
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
848 move->piece = PAWN;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
849 move->fromfile = fileidx(mstr[0]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
850 move->fromrow = rowidx(mstr[1]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
851 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
852 } else {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
853 /* long notation move (e.g. "Nc5a4") */
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
854 move->fromfile = fileidx(mstr[1]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
855 move->fromrow = rowidx(mstr[2]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
856 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
857 move->tofile = fileidx(mstr[3]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
858 move->torow = rowidx(mstr[4]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
859 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
860 } else if (len == 6) {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
861 /* long notation capture (e.g. "Nc5xf3") */
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
862 if (mstr[3] == 'x') {
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
863 move->capture = 1;
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
864 move->piece = getpiece(mstr[0]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
865 move->fromfile = fileidx(mstr[1]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
866 move->fromrow = rowidx(mstr[2]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
867 move->tofile = fileidx(mstr[4]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
868 move->torow = rowidx(mstr[5]);
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
869 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
870 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
871
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
872
115
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
873 if (!move->piece) {
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
874 return INVALID_MOVE_SYNTAX;
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
875 }
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
876
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
877 if (move->piece == PAWN
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
878 && move->torow == (color==WHITE?7:0)
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
879 && !move->promotion) {
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
880 return NEED_PROMOTION;
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
881 }
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
882
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
883 move->piece |= color;
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
884
153
bad2d6d4b861 fix wrong error message when move indices are invalid
Mike Becker <universe@uap-core.de>
parents: 152
diff changeset
885 /* up to this point
bad2d6d4b861 fix wrong error message when move indices are invalid
Mike Becker <universe@uap-core.de>
parents: 152
diff changeset
886 * destination indices must be specified and valid
bad2d6d4b861 fix wrong error message when move indices are invalid
Mike Becker <universe@uap-core.de>
parents: 152
diff changeset
887 * source indices must either be valid or unspecified
bad2d6d4b861 fix wrong error message when move indices are invalid
Mike Becker <universe@uap-core.de>
parents: 152
diff changeset
888 */
bad2d6d4b861 fix wrong error message when move indices are invalid
Mike Becker <universe@uap-core.de>
parents: 152
diff changeset
889 if (!isidxr(move->fromrow) || !isidxr(move->fromfile) ||
bad2d6d4b861 fix wrong error message when move indices are invalid
Mike Becker <universe@uap-core.de>
parents: 152
diff changeset
890 !isidx(move->torow) || !isidx(move->tofile)) {
bad2d6d4b861 fix wrong error message when move indices are invalid
Mike Becker <universe@uap-core.de>
parents: 152
diff changeset
891 return INVALID_MOVE_SYNTAX;
115
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
892 }
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
893
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
894 return VALID_MOVE_SYNTAX;
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
895 }
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
896
147
7e3f2d462bb6 make eval_move() and check_move() not change their input string
Mike Becker <universe@uap-core.de>
parents: 144
diff changeset
897 int eval_move(GameState *gamestate, const char *mstr,
7e3f2d462bb6 make eval_move() and check_move() not change their input string
Mike Becker <universe@uap-core.de>
parents: 144
diff changeset
898 Move *move, uint8_t color) {
115
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
899 int result = eval_move1(mstr, move, color);
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
900 if (result == VALID_MOVE_SYNTAX) {
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
901 if (move->fromfile == POS_UNSPECIFIED
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
902 || move->fromrow == POS_UNSPECIFIED) {
23
824c9522ce66 introduced game state structure
Mike Becker <universe@uap-core.de>
parents: 21
diff changeset
903 return getlocation(gamestate, move);
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
904 }
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
905 }
115
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
906 return result;
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
907 }
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
908
147
7e3f2d462bb6 make eval_move() and check_move() not change their input string
Mike Becker <universe@uap-core.de>
parents: 144
diff changeset
909 int check_move(const char *mstr, uint8_t color) {
115
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
910 Move move;
206201d544be relax validation of premoves to allow retaking pieces
Mike Becker <universe@uap-core.de>
parents: 110
diff changeset
911 return eval_move1(mstr, &move, color);
19
6a26114297a1 moved chess rules to separate lib
Mike Becker <universe@uap-core.de>
parents:
diff changeset
912 }
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
913
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
914 bool is_protected(GameState *gamestate, uint8_t row, uint8_t file,
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
915 uint8_t color) {
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
916
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
917 Move threats[16];
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
918 uint8_t threatcount;
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
919 if (get_real_threats(gamestate, row, file, color, threats, &threatcount)) {
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
920 for (int i = 0 ; i < threatcount ; i++) {
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
921 if (threats[i].piece != (color|KING)) {
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
922 return true;
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
923 }
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
924 }
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
925 return false;
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
926 } else {
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
927 return false;
29
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
928 }
c6a1ad6cf749 fixed checkmate and completed implementation (more testing is still advised)
Mike Becker <universe@uap-core.de>
parents: 28
diff changeset
929 }
33
866025982aa9 implemented time control
Mike Becker <universe@uap-core.de>
parents: 29
diff changeset
930
130
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
931 uint16_t remaining_movetime(GameState *gamestate, uint8_t color) {
99
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
932 unsigned move_number = gamestate->movecount;
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
933 if (color == BLACK) {
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
934 move_number |= 1;
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
935 } else {
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
936 move_number = (move_number + 1) & ~1;
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
937 }
130
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
938 return remaining_movetime2(gamestate, move_number);
99
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
939 }
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
940
130
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
941 uint16_t remaining_movetime2(GameState *gamestate, unsigned move_number) {
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
942 if (!gamestate->info.timecontrol) {
33
866025982aa9 implemented time control
Mike Becker <universe@uap-core.de>
parents: 29
diff changeset
943 return 0;
866025982aa9 implemented time control
Mike Becker <universe@uap-core.de>
parents: 29
diff changeset
944 }
99
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
945
130
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
946 unsigned total_time = gamestate->info.time;
99
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
947 unsigned used_time = 0;
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
948 suseconds_t micros = 0;
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
949
103
a2a68fd9f6cc fix missing support for 0+X time control
Mike Becker <universe@uap-core.de>
parents: 100
diff changeset
950 /* when this is a 0+X game, the clock starts with the increment */
130
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
951 if (gamestate->info.time == 0) {
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
952 total_time += gamestate->info.addtime;
103
a2a68fd9f6cc fix missing support for 0+X time control
Mike Becker <universe@uap-core.de>
parents: 100
diff changeset
953 }
a2a68fd9f6cc fix missing support for 0+X time control
Mike Becker <universe@uap-core.de>
parents: 100
diff changeset
954
99
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
955 /* go through all already played moves */
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
956 unsigned first_move = move_number % 2;
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
957 unsigned next_move = move_number;
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
958 if (next_move > gamestate->movecount) next_move = gamestate->movecount;
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
959 for (unsigned i = first_move ; i < next_move ; i += 2) {
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
960 used_time += gamestate->moves[i].movetime.tv_sec;
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
961 micros += gamestate->moves[i].movetime.tv_usec;
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
962 /* add increments starting with move 2 */
130
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
963 if (i > 1) total_time += gamestate->info.addtime;
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
964 }
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
965
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
966 /* apply microseconds */
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
967 while (micros >= 1000000) {
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
968 micros -= 1000000;
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
969 used_time++;
99
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
970 }
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 87
diff changeset
971
99
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
972 /* when the player is currently playing, count down the clock */
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
973 if (is_game_running(gamestate) && move_number > 1 &&
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
974 move_number == gamestate->movecount) {
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
975 struct movetimeval lastmovetstamp =
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
976 gamestate->moves[move_number - 1].timestamp;
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
977 struct timeval currenttstamp;
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
978 gettimeofday(&currenttstamp, NULL);
130
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
979
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
980 /* calculate current move time */
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
981 unsigned cmsec = currenttstamp.tv_sec - lastmovetstamp.tv_sec;
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
982 suseconds_t cmusec = currenttstamp.tv_usec - lastmovetstamp.tv_usec;
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
983
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
984 /* add microseconds carried over from last move and apply both */
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
985 cmusec += micros;
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
986 cmsec += cmusec / 1000000;
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
987
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
988 /* add the time and respect a possible dealy */
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
989 if (cmsec >= gamestate->info.delay) {
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
990 used_time += cmsec - gamestate->info.delay;
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 129
diff changeset
991 }
99
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
992 }
33
866025982aa9 implemented time control
Mike Becker <universe@uap-core.de>
parents: 29
diff changeset
993
99
231a79d93c0c add API for calculating the clock for a specific move + fixes wrong handling of move time and increment in move 1
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
994 return used_time >= total_time ? 0 : total_time - used_time;
33
866025982aa9 implemented time control
Mike Becker <universe@uap-core.de>
parents: 29
diff changeset
995 }
100
685af47592b5 add API for formatting clocks
Mike Becker <universe@uap-core.de>
parents: 99
diff changeset
996
107
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 105
diff changeset
997 int print_clk(uint16_t time, char *str, bool always_hours) {
100
685af47592b5 add API for formatting clocks
Mike Becker <universe@uap-core.de>
parents: 99
diff changeset
998 unsigned hours = time / 3600;
685af47592b5 add API for formatting clocks
Mike Becker <universe@uap-core.de>
parents: 99
diff changeset
999 unsigned minutes = (time % 3600) / 60;
685af47592b5 add API for formatting clocks
Mike Becker <universe@uap-core.de>
parents: 99
diff changeset
1000 unsigned seconds = time % 60;
685af47592b5 add API for formatting clocks
Mike Becker <universe@uap-core.de>
parents: 99
diff changeset
1001 if (hours > 0 || always_hours) {
107
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 105
diff changeset
1002 return snprintf(str, 9, "%u:%02u:%02u", hours, minutes, seconds);
100
685af47592b5 add API for formatting clocks
Mike Becker <universe@uap-core.de>
parents: 99
diff changeset
1003 } else {
107
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 105
diff changeset
1004 return snprintf(str, 6, "%02u:%02u", minutes, seconds);
100
685af47592b5 add API for formatting clocks
Mike Becker <universe@uap-core.de>
parents: 99
diff changeset
1005 }
685af47592b5 add API for formatting clocks
Mike Becker <universe@uap-core.de>
parents: 99
diff changeset
1006 }
131
c33567d61ba7 prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents: 130
diff changeset
1007
c33567d61ba7 prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents: 130
diff changeset
1008 bool check_threefold_repetition(GameState *gamestate) {
c33567d61ba7 prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents: 130
diff changeset
1009 // TODO: implement threefold repetition detection
c33567d61ba7 prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents: 130
diff changeset
1010 return false;
c33567d61ba7 prepare netcode for claiming threefold repetition
Mike Becker <universe@uap-core.de>
parents: 130
diff changeset
1011 }

mercurial