| 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 } |