1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 11:57:35 +00:00

LibChess: Include pawns in FEN output

Previously, the initial position would look like this:

rnbqkbnr//8/8/8/8//RNBQKBNR w KQkq - 0 1

Now, we correctly give pawns the P/p character in FEN output:

rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1

Also, we only ever have 1 or 0 characters for a piece, so let's return
`Optional<char>` instead of `StringView` from `char_for_piece()`.
This commit is contained in:
Sam Atkins 2023-04-24 11:58:52 +01:00 committed by Andreas Kling
parent 8529e660ca
commit b111782f18
2 changed files with 26 additions and 15 deletions

View file

@ -5,6 +5,7 @@
*/ */
#include <AK/Assertions.h> #include <AK/Assertions.h>
#include <AK/CharacterTypes.h>
#include <AK/DeprecatedString.h> #include <AK/DeprecatedString.h>
#include <AK/StringBuilder.h> #include <AK/StringBuilder.h>
#include <AK/Vector.h> #include <AK/Vector.h>
@ -13,23 +14,27 @@
namespace Chess { namespace Chess {
StringView char_for_piece(Chess::Type type) Optional<char> char_for_piece(Type type, Notation notation)
{ {
switch (type) { switch (type) {
case Type::Knight: case Type::Knight:
return "N"sv; return 'N';
case Type::Bishop: case Type::Bishop:
return "B"sv; return 'B';
case Type::Rook: case Type::Rook:
return "R"sv; return 'R';
case Type::Queen: case Type::Queen:
return "Q"sv; return 'Q';
case Type::King: case Type::King:
return "K"sv; return 'K';
case Type::Pawn: case Type::Pawn:
default: if (notation == Notation::FEN)
return ""sv; return 'P';
return {};
case Type::None:
return {};
} }
VERIFY_NOT_REACHED();
} }
Chess::Type piece_for_char_promotion(StringView str) Chess::Type piece_for_char_promotion(StringView str)
@ -97,7 +102,8 @@ DeprecatedString Move::to_long_algebraic() const
StringBuilder builder; StringBuilder builder;
builder.append(from.to_algebraic()); builder.append(from.to_algebraic());
builder.append(to.to_algebraic()); builder.append(to.to_algebraic());
builder.append(DeprecatedString(char_for_piece(promote_to)).to_lowercase()); if (auto promoted_char = char_for_piece(promote_to, Notation::Algebraic); promoted_char.has_value())
builder.append(to_ascii_lowercase(promoted_char.value()));
return builder.to_deprecated_string(); return builder.to_deprecated_string();
} }
@ -187,7 +193,8 @@ DeprecatedString Move::to_algebraic() const
StringBuilder builder; StringBuilder builder;
builder.append(char_for_piece(piece.type)); if (auto piece_char = char_for_piece(piece.type, Notation::Algebraic); piece_char.has_value())
builder.append(*piece_char);
if (is_ambiguous) { if (is_ambiguous) {
if (from.file != ambiguous.file) if (from.file != ambiguous.file)
@ -206,9 +213,9 @@ DeprecatedString Move::to_algebraic() const
builder.append(to.to_algebraic()); builder.append(to.to_algebraic());
if (promote_to != Type::None) { if (promote_to != Type::None && promote_to != Type::Pawn) {
builder.append('='); builder.append('=');
builder.append(char_for_piece(promote_to)); builder.append(char_for_piece(promote_to, Notation::Algebraic).value());
} }
if (is_mate) if (is_mate)
@ -286,9 +293,9 @@ DeprecatedString Board::to_fen() const
builder.append(DeprecatedString::number(empty)); builder.append(DeprecatedString::number(empty));
empty = 0; empty = 0;
} }
auto const piece = char_for_piece(p.type); auto const piece = char_for_piece(p.type, Notation::FEN).value();
if (p.color == Color::Black) if (p.color == Color::Black)
builder.append(DeprecatedString(piece).to_lowercase()); builder.append(to_ascii_lowercase(piece));
else else
builder.append(piece); builder.append(piece);
} }

View file

@ -25,7 +25,11 @@ enum class Type : u8 {
None, None,
}; };
StringView char_for_piece(Type type); enum class Notation {
Algebraic,
FEN,
};
Optional<char> char_for_piece(Type, Notation);
Chess::Type piece_for_char_promotion(StringView str); Chess::Type piece_for_char_promotion(StringView str);
enum class Color : u8 { enum class Color : u8 {