1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 09:48:11 +00:00

Chess: Added abilty to import PGN files

This patch allows the user to load games using PGN files. The parsing
is not complete and has a bunch of work left to be done, but it's
okay for our use case here. It can load all of the games our PGN
exporter can save. As the Chess program impoves so can the PGN parser.
This commit is contained in:
AnicJov 2020-12-10 17:34:06 +01:00 committed by Andreas Kling
parent 4d9837d792
commit f631e73519
5 changed files with 200 additions and 7 deletions

View file

@ -106,10 +106,10 @@ String Square::to_algebraic() const
return builder.build();
}
Move::Move(const StringView& algebraic)
: from(algebraic.substring_view(0, 2))
, to(algebraic.substring_view(2, 2))
, promote_to(piece_for_char_promotion((algebraic.length() >= 5) ? algebraic.substring_view(4, 1) : ""))
Move::Move(const StringView& long_algebraic)
: from(long_algebraic.substring_view(0, 2))
, to(long_algebraic.substring_view(2, 2))
, promote_to(piece_for_char_promotion((long_algebraic.length() >= 5) ? long_algebraic.substring_view(4, 1) : ""))
{
}
@ -122,6 +122,81 @@ String Move::to_long_algebraic() const
return builder.build();
}
Move Move::from_algebraic(const StringView& algebraic, const Colour turn, const Board& board)
{
String move_string = algebraic;
Move move({ 50, 50 }, { 50, 50 });
if (move_string.contains("-")) {
move.from = Square(turn == Colour::White ? 0 : 7, 4);
move.to = Square(turn == Colour::White ? 0 : 7, move_string == "O-O" ? 6 : 2);
move.promote_to = Type::None;
move.piece = { turn, Type::King };
return move;
}
if (algebraic.contains("#")) {
move.is_mate = true;
move_string = move_string.substring(0, move_string.length() - 1);
} else if (algebraic.contains("+")) {
move.is_check = true;
move_string = move_string.substring(0, move_string.length() - 1);
}
if (algebraic.contains("=")) {
move.promote_to = piece_for_char_promotion(move_string.split('=').at(1).substring(0, 1));
move_string = move_string.split('=').at(0);
}
move.to = Square(move_string.substring(move_string.length() - 2, 2));
move_string = move_string.substring(0, move_string.length() - 2);
if (move_string.contains("x")) {
move.is_capture = true;
move_string = move_string.substring(0, move_string.length() - 1);
}
if (move_string.is_empty() || move_string.characters()[0] >= 'a') {
move.piece = Piece(turn, Type::Pawn);
} else {
move.piece = Piece(turn, piece_for_char_promotion(move_string.substring(0, 1)));
move_string = move_string.substring(1, move_string.length() - 1);
}
Square::for_each([&](const Square& square) {
if (!move_string.is_empty()) {
if (board.get_piece(square).type == move.piece.type && board.is_legal(Move(square, move.to), turn)) {
if (move_string.length() >= 2) {
if (square == Square(move_string.substring(0, 2))) {
move.from = square;
return IterationDecision::Break;
}
} else if (move_string.characters()[0] <= 57) {
if (square.rank == (unsigned)(move_string.characters()[0] - '0')) {
move.from = square;
return IterationDecision::Break;
}
} else {
if (square.file == (unsigned)(move_string.characters()[0] - 'a')) {
move.from = square;
return IterationDecision::Break;
}
}
}
return IterationDecision::Continue;
} else {
if (board.get_piece(square).type == move.piece.type && board.is_legal(Move(square, move.to), turn)) {
move.from = square;
return IterationDecision::Break;
}
return IterationDecision::Continue;
}
});
return move;
}
String Move::to_algebraic() const
{
if (piece.type == Type::King && from.file == 4) {