@@ -47,28 +47,141 @@ bool is_capture(const std::string& s)
47
47
48
48
square get_from (const game& g, const chess_move& m)
49
49
{
50
-
51
- if (is_simple_move (m))
50
+ if (!m.get_type ().empty ())
52
51
{
53
- if (m.get_type ()[0 ] == piece_type::pawn)
52
+ const piece_type pt{m.get_type ()[0 ]};
53
+ switch (pt)
54
54
{
55
- const square one_behind{get_behind (m.get_to ()[0 ], m.get_color ())};
56
- if (is_piece_at (g, one_behind))
57
- {
58
- assert (get_piece_at (g, one_behind).get_type () == piece_type::pawn);
59
- return one_behind;
60
- }
61
- const square two_behind{get_behind (one_behind, m.get_color ())};
62
- if (is_piece_at (g, two_behind))
63
- {
64
- assert (get_piece_at (g, two_behind).get_type () == piece_type::pawn);
65
- return two_behind;
66
- }
55
+ case piece_type::bishop: return get_from_for_bishop (g, m);
56
+ case piece_type::king: return get_from_for_king (g, m);
57
+ case piece_type::knight: return get_from_for_knight (g, m);
58
+ case piece_type::pawn: return get_from_for_pawn (g, m);
59
+ case piece_type::queen: return get_from_for_queen (g, m);
60
+ default :
61
+ case piece_type::rook:
62
+ assert (pt == piece_type::rook);
63
+ return get_from_for_rook (g, m);
67
64
}
68
65
}
69
66
assert (!" TODO" );
70
67
}
71
68
69
+ square get_from_for_bishop (const game& g, const chess_move& m)
70
+ {
71
+ assert (!m.get_type ().empty ());
72
+ assert (m.get_type ()[0 ] == piece_type::bishop);
73
+ const auto pieces{
74
+ find_pieces (g, piece_type::bishop, m.get_color ())
75
+ };
76
+ assert (!pieces.empty ());
77
+ assert (!m.get_to ().empty ());
78
+ const square target{m.get_to ()[0 ]};
79
+ for (const auto & piece: pieces)
80
+ {
81
+ if (are_on_same_diagonal (piece.get_current_square (), target))
82
+ {
83
+ return piece.get_current_square ();
84
+ }
85
+ }
86
+ assert (!" Should not get here: there had to be a bishop on the diagonal" );
87
+ }
88
+
89
+ square get_from_for_king (const game& g, const chess_move& m)
90
+ {
91
+ assert (!m.get_type ().empty ());
92
+ assert (m.get_type ()[0 ] == piece_type::king);
93
+ const auto pieces{
94
+ find_pieces (g, piece_type::king, m.get_color ())
95
+ };
96
+ assert (!pieces.empty ());
97
+ assert (pieces.size () == 1 ); // There is only 1 king
98
+ return pieces[0 ].get_current_square ();
99
+ }
100
+
101
+ square get_from_for_knight (const game& g, const chess_move& m)
102
+ {
103
+ assert (!m.get_type ().empty ());
104
+ assert (m.get_type ()[0 ] == piece_type::knight);
105
+ const auto pieces{
106
+ find_pieces (g, piece_type::knight, m.get_color ())
107
+ };
108
+ assert (!pieces.empty ());
109
+ assert (!m.get_to ().empty ());
110
+ const square target{m.get_to ()[0 ]};
111
+
112
+ for (const auto & piece: pieces)
113
+ {
114
+ if (are_adjacent_for_knight (piece.get_current_square (), target))
115
+ {
116
+ return piece.get_current_square ();
117
+ }
118
+ }
119
+ assert (!" Should not get here: there had to be a knight a knight's jump away" );
120
+ }
121
+
122
+ square get_from_for_pawn (const game& g, const chess_move& m)
123
+ {
124
+ assert (!m.get_type ().empty ());
125
+ assert (m.get_type ()[0 ] == piece_type::pawn);
126
+ assert (!m.is_capture ());
127
+ const square one_behind{get_behind (m.get_to ()[0 ], m.get_color ())};
128
+ if (is_piece_at (g, one_behind))
129
+ {
130
+ assert (get_piece_at (g, one_behind).get_type () == piece_type::pawn);
131
+ return one_behind;
132
+ }
133
+ const square two_behind{get_behind (one_behind, m.get_color ())};
134
+ assert (is_piece_at (g, two_behind));
135
+ assert (get_piece_at (g, two_behind).get_type () == piece_type::pawn);
136
+ return two_behind;
137
+ }
138
+
139
+ square get_from_for_queen (const game& g, const chess_move& m)
140
+ {
141
+ assert (!m.get_type ().empty ());
142
+ assert (m.get_type ()[0 ] == piece_type::queen);
143
+ const auto pieces{
144
+ find_pieces (g, piece_type::queen, m.get_color ())
145
+ };
146
+ assert (!pieces.empty ());
147
+ assert (!m.get_to ().empty ());
148
+ const square target{m.get_to ()[0 ]};
149
+ for (const auto & piece: pieces)
150
+ {
151
+ if (are_on_same_diagonal (piece.get_current_square (), target)
152
+ || are_on_same_rank (piece.get_current_square (), target)
153
+ || are_on_same_file (piece.get_current_square (), target)
154
+ )
155
+ {
156
+ return piece.get_current_square ();
157
+ }
158
+ }
159
+ assert (!" Should not get here: there had to be a queen on the same rank, file, or diagonal" );
160
+ }
161
+
162
+ square get_from_for_rook (const game& g, const chess_move& m)
163
+ {
164
+ assert (!m.get_type ().empty ());
165
+ assert (m.get_type ()[0 ] == piece_type::rook);
166
+ const auto pieces{
167
+ find_pieces (g, piece_type::rook, m.get_color ())
168
+ };
169
+ assert (!pieces.empty ());
170
+ assert (!m.get_to ().empty ());
171
+ const square target{m.get_to ()[0 ]};
172
+ for (const auto & piece: pieces)
173
+ {
174
+ if (are_on_same_rank (piece.get_current_square (), target)
175
+ || are_on_same_file (piece.get_current_square (), target)
176
+ )
177
+ {
178
+ return piece.get_current_square ();
179
+ }
180
+ }
181
+ assert (!" Should not get here: there had to be a rook on the same rank or file" );
182
+ }
183
+
184
+
72
185
piece_type get_piece_type (const std::string& s)
73
186
{
74
187
const std::regex e (" [BKNQR]" );
0 commit comments