src/chess/pawn.c

changeset 194
619f07c95894
parent 193
d1420f5c5704
child 195
27d02ccb0cef
equal deleted inserted replaced
193:d1420f5c5704 194:619f07c95894
31 #include "rules.h" 31 #include "rules.h"
32 32
33 bool pawn_chkrules(const GameState *gamestate, const Move *move) { 33 bool pawn_chkrules(const GameState *gamestate, const Move *move) {
34 int8_t d = piece_color(move->piece) == WHITE ? -1 : 1; 34 int8_t d = piece_color(move->piece) == WHITE ? -1 : 1;
35 35
36 if (move->torow == (d < 0 ? 7 : 0)) { 36 if (move->torank == (d < 0 ? 7 : 0)) {
37 if (move->promotion) { 37 if (move->promotion) {
38 unsigned ppiecetype = piece_type(move->promotion); 38 unsigned ppiecetype = piece_type(move->promotion);
39 if (!ppiecetype || ppiecetype == PAWN || ppiecetype == KING) { 39 if (!ppiecetype || ppiecetype == PAWN || ppiecetype == KING) {
40 return false; 40 return false;
41 } 41 }
47 return false; 47 return false;
48 } 48 }
49 } 49 }
50 50
51 if (move->capture) { 51 if (move->capture) {
52 if (move->fromrow == move->torow + d && ( 52 if (move->fromrank == move->torank + d && (
53 move->fromfile == move->tofile + 1 || 53 move->fromfile == move->tofile + 1 ||
54 move->fromfile == move->tofile - 1)) { 54 move->fromfile == move->tofile - 1)) {
55 55
56 return piece_at(gamestate, mdst(move)) || 56 return piece_at(gamestate, move->torank, move->tofile) ||
57 enpassant_threat_exists(gamestate, move->fromrow, move->tofile); 57 enpassant_threat_exists(gamestate, move->fromrank, move->tofile);
58 } else { 58 } else {
59 return false; 59 return false;
60 } 60 }
61 } else { 61 } else {
62 if (move->fromfile == move->tofile) { 62 if (move->fromfile == move->tofile) {
63 return (move->fromrow == move->torow + d) || 63 return (move->fromrank == move->torank + d) ||
64 (move->fromrow == (d < 0 ? 1 : 6) && /* advanced first move */ 64 (move->fromrank == (d < 0 ? 1 : 6) && /* advanced first move */
65 move->fromrow == move->torow + d*2); 65 move->fromrank == move->torank + d*2);
66 } else { 66 } else {
67 return false; 67 return false;
68 } 68 }
69 } 69 }
70 } 70 }
71 71
72 bool pawn_isblocked(const GameState *gamestate, const Move *move) { 72 bool pawn_isblocked(const GameState *gamestate, const Move *move) {
73 if (move->torow == move->fromrow + 1 || move->torow == move->fromrow - 1) { 73 if (move->torank == move->fromrank + 1
74 return piece_at(gamestate, mdst(move)) && !move->capture; 74 || move->torank == move->fromrank - 1) {
75 return piece_at(gamestate, move->torank, move->tofile)
76 && !move->capture;
75 } else { 77 } else {
76 return piece_at(gamestate, mdst(move)) || 78 return piece_at(gamestate, move->torank, move->tofile) ||
77 gamestate->board[(move->fromrow+move->torow)/2][move->tofile]; 79 gamestate->board[(move->fromrank + move->torank) / 2][move->tofile];
78 } 80 }
79 } 81 }
80 82
81 size_t pawn_moves(const GameState *gamestate, 83 size_t pawn_moves(const GameState *gamestate,
82 Color c, Row r, File f, Move *moves) { 84 Color c, Rank r, File f, Move *moves) {
83 (void) gamestate; /* no (theoretical) move depends on the game state */ 85 (void) gamestate; /* no (theoretical) move depends on the game state */
84 size_t count = 0; 86 size_t count = 0;
85 int rowdelta = c == WHITE ? 1 : -1; 87 int rankdelta = c == WHITE ? 1 : -1;
86 int promotionrow = c == WHITE ? 7 : 0; 88 int promotionrank = c == WHITE ? 7 : 0;
87 int startrow = c == WHITE ? 1 : 6; 89 int startrank = c == WHITE ? 1 : 6;
88 const int targets[4][3] = { 90 const int targets[4][3] = {
89 {r + rowdelta, f, 0}, 91 {r + rankdelta, f, 0},
90 {r + rowdelta, f - 1, 1}, 92 {r + rankdelta, f - 1, 1},
91 {r + rowdelta, f + 1, 1}, 93 {r + rankdelta, f + 1, 1},
92 {r + rowdelta * 2, f, 0} 94 {r + rankdelta * 2, f, 0}
93 }; 95 };
94 96
95 for (size_t i = 0 ; i < 4 ; i++) { 97 for (size_t i = 0 ; i < 4 ; i++) {
96 int row = targets[i][0]; 98 Rank rank = targets[i][0];
97 int file = targets[i][1]; 99 File file = targets[i][1];
98 100
99 if (i == 3 && r != startrow) { 101 if (i == 3 && r != startrank) {
100 continue; 102 continue;
101 } 103 }
102 104
103 if (isidx(row) && isidx(file)) { 105 if (isidx(rank) && isidx(file)) {
104 moves[count] = (Move){0}; 106 moves[count] = (Move){0};
105 moves[count].piece = mkpiece(PAWN, c); 107 moves[count].piece = mkpiece(PAWN, c);
106 moves[count].fromrow = r; 108 moves[count].fromrank = r;
107 moves[count].fromfile = f; 109 moves[count].fromfile = f;
108 moves[count].torow = row; 110 moves[count].torank = rank;
109 moves[count].tofile = file; 111 moves[count].tofile = file;
110 moves[count].capture = targets[i][2]; 112 moves[count].capture = targets[i][2];
111 113
112 if (row == promotionrow) { 114 if (rank == promotionrank) {
113 moves[count].promotion = mkpiece(QUEEN, c); 115 moves[count].promotion = mkpiece(QUEEN, c);
114 } 116 }
115 117
116 count++; 118 count++;
117 } 119 }

mercurial