1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 17:17:44 +00:00

LibChess: Return ErrorOr<String> from to-algebraic/fen methods

Also, avoid creating temporary Strings for numbers, and stop appending
empty StringViews.
This commit is contained in:
Sam Atkins 2023-04-24 12:51:33 +01:00 committed by Andreas Kling
parent 5f6dd87163
commit a10cc37ef0
4 changed files with 59 additions and 58 deletions

View file

@ -535,7 +535,7 @@ void ChessWidget::playback_move(PlaybackDirection direction)
DeprecatedString ChessWidget::get_fen() const DeprecatedString ChessWidget::get_fen() const
{ {
return m_playback ? m_board_playback.to_fen() : m_board.to_fen(); return (m_playback ? m_board_playback.to_fen() : m_board.to_fen()).release_value_but_fixme_should_propagate_errors().to_deprecated_string();
} }
ErrorOr<void> ChessWidget::import_pgn(Core::File& file) ErrorOr<void> ChessWidget::import_pgn(Core::File& file)
@ -659,10 +659,10 @@ ErrorOr<void> ChessWidget::export_pgn(Core::File& file) const
// Movetext Section // Movetext Section
for (size_t i = 0, move_no = 1; i < m_board.moves().size(); i += 2, move_no++) { for (size_t i = 0, move_no = 1; i < m_board.moves().size(); i += 2, move_no++) {
const DeprecatedString white = m_board.moves().at(i).to_algebraic(); const DeprecatedString white = m_board.moves().at(i).to_algebraic().release_value_but_fixme_should_propagate_errors().to_deprecated_string();
if (i + 1 < m_board.moves().size()) { if (i + 1 < m_board.moves().size()) {
const DeprecatedString black = m_board.moves().at(i + 1).to_algebraic(); const DeprecatedString black = m_board.moves().at(i + 1).to_algebraic().release_value_but_fixme_should_propagate_errors().to_deprecated_string();
TRY(file.write_until_depleted(DeprecatedString::formatted("{}. {} {} ", move_no, white, black).bytes())); TRY(file.write_until_depleted(DeprecatedString::formatted("{}. {} {} ", move_no, white, black).bytes()));
} else { } else {
TRY(file.write_until_depleted(DeprecatedString::formatted("{}. {} ", move_no, white).bytes())); TRY(file.write_until_depleted(DeprecatedString::formatted("{}. {} ", move_no, white).bytes()));

View file

@ -7,7 +7,7 @@
#include <AK/Assertions.h> #include <AK/Assertions.h>
#include <AK/CharacterTypes.h> #include <AK/CharacterTypes.h>
#include <AK/DeprecatedString.h> #include <AK/String.h>
#include <AK/StringBuilder.h> #include <AK/StringBuilder.h>
#include <AK/Vector.h> #include <AK/Vector.h>
#include <LibChess/Chess.h> #include <LibChess/Chess.h>
@ -94,12 +94,9 @@ char Square::rank_char() const
return rank + '1'; return rank + '1';
} }
DeprecatedString Square::to_algebraic() const ErrorOr<String> Square::to_algebraic() const
{ {
StringBuilder builder; return String::formatted("{}{}", file_char(), rank_char());
builder.append(file + 'a');
builder.append(rank + '1');
return builder.to_deprecated_string();
} }
Move::Move(StringView long_algebraic) Move::Move(StringView long_algebraic)
@ -109,14 +106,14 @@ Move::Move(StringView long_algebraic)
{ {
} }
DeprecatedString Move::to_long_algebraic() const ErrorOr<String> Move::to_long_algebraic() const
{ {
StringBuilder builder; StringBuilder builder;
builder.append(from.to_algebraic()); TRY(builder.try_append(TRY(from.to_algebraic())));
builder.append(to.to_algebraic()); TRY(builder.try_append(TRY(to.to_algebraic())));
if (auto promoted_char = char_for_piece(promote_to, Notation::Algebraic); promoted_char.has_value()) if (auto promoted_char = char_for_piece(promote_to, Notation::Algebraic); promoted_char.has_value())
builder.append(to_ascii_lowercase(promoted_char.value())); TRY(builder.try_append(to_ascii_lowercase(promoted_char.value())));
return builder.to_deprecated_string(); return builder.to_string();
} }
Move Move::from_algebraic(StringView algebraic, const Color turn, Board const& board) Move Move::from_algebraic(StringView algebraic, const Color turn, Board const& board)
@ -195,48 +192,48 @@ Move Move::from_algebraic(StringView algebraic, const Color turn, Board const& b
return move; return move;
} }
DeprecatedString Move::to_algebraic() const ErrorOr<String> Move::to_algebraic() const
{ {
if (piece.type == Type::King && from.file == 4) { if (piece.type == Type::King && from.file == 4) {
if (to.file == 2) if (to.file == 2)
return "O-O-O"; return "O-O-O"_short_string;
if (to.file == 6) if (to.file == 6)
return "O-O"; return "O-O"_short_string;
} }
StringBuilder builder; StringBuilder builder;
if (auto piece_char = char_for_piece(piece.type, Notation::Algebraic); piece_char.has_value()) if (auto piece_char = char_for_piece(piece.type, Notation::Algebraic); piece_char.has_value())
builder.append(*piece_char); TRY(builder.try_append(*piece_char));
if (is_ambiguous) { if (is_ambiguous) {
if (from.file != ambiguous.file) if (from.file != ambiguous.file)
builder.append(from.file_char()); TRY(builder.try_append(from.file_char()));
else if (from.rank != ambiguous.rank) else if (from.rank != ambiguous.rank)
builder.append(from.rank_char()); TRY(builder.try_append(from.rank_char()));
else else
builder.append(from.to_algebraic()); TRY(builder.try_append(TRY(from.to_algebraic())));
} }
if (is_capture) { if (is_capture) {
if (piece.type == Type::Pawn && !is_ambiguous) if (piece.type == Type::Pawn && !is_ambiguous)
builder.append(from.file_char()); TRY(builder.try_append(from.file_char()));
builder.append('x'); TRY(builder.try_append('x'));
} }
builder.append(to.to_algebraic()); TRY(builder.try_append(TRY(to.to_algebraic())));
if (promote_to != Type::None && promote_to != Type::Pawn) { if (promote_to != Type::None && promote_to != Type::Pawn) {
builder.append('='); TRY(builder.try_append('='));
builder.append(char_for_piece(promote_to, Notation::Algebraic).value()); TRY(builder.try_append(char_for_piece(promote_to, Notation::Algebraic).value()));
} }
if (is_mate) if (is_mate)
builder.append('#'); TRY(builder.try_append('#'));
else if (is_check) else if (is_check)
builder.append('+'); TRY(builder.try_append('+'));
return builder.to_deprecated_string(); return builder.to_string();
} }
Board::Board() Board::Board()
@ -289,7 +286,7 @@ Board Board::clone_without_history() const
return result; return result;
} }
DeprecatedString Board::to_fen() const ErrorOr<String> Board::to_fen() const
{ {
StringBuilder builder; StringBuilder builder;
@ -303,57 +300,61 @@ DeprecatedString Board::to_fen() const
continue; continue;
} }
if (empty > 0) { if (empty > 0) {
builder.append(DeprecatedString::number(empty)); TRY(builder.try_appendff("{}", empty));
empty = 0; empty = 0;
} }
auto const piece = char_for_piece(p.type, Notation::FEN).value(); auto const piece = char_for_piece(p.type, Notation::FEN).value();
if (p.color == Color::Black) if (p.color == Color::Black)
builder.append(to_ascii_lowercase(piece)); TRY(builder.try_append(to_ascii_lowercase(piece)));
else else
builder.append(piece); TRY(builder.try_append(piece));
} }
if (empty > 0) { if (empty > 0) {
builder.append(DeprecatedString::number(empty)); TRY(builder.try_appendff("{}", empty));
empty = 0; empty = 0;
} }
if (rank < 7) if (rank < 7)
builder.append('/'); TRY(builder.try_append('/'));
} }
// 2. Active color // 2. Active color
VERIFY(m_turn != Color::None); VERIFY(m_turn != Color::None);
builder.append(m_turn == Color::White ? " w "sv : " b "sv); TRY(builder.try_append(m_turn == Color::White ? " w "sv : " b "sv));
// 3. Castling availability // 3. Castling availability
builder.append(m_white_can_castle_kingside ? "K"sv : ""sv); if (m_white_can_castle_kingside)
builder.append(m_white_can_castle_queenside ? "Q"sv : ""sv); TRY(builder.try_append('K'));
builder.append(m_black_can_castle_kingside ? "k"sv : ""sv); if (m_white_can_castle_queenside)
builder.append(m_black_can_castle_queenside ? "q"sv : ""sv); TRY(builder.try_append('Q'));
builder.append(' '); if (m_black_can_castle_kingside)
TRY(builder.try_append('k'));
if (m_black_can_castle_queenside)
TRY(builder.try_append('q'));
TRY(builder.try_append(' '));
// 4. En passant target square // 4. En passant target square
if (!m_last_move.has_value()) if (!m_last_move.has_value())
builder.append('-'); TRY(builder.try_append('-'));
else if (m_last_move.value().piece.type == Type::Pawn) { else if (m_last_move.value().piece.type == Type::Pawn) {
if (m_last_move.value().from.rank == 1 && m_last_move.value().to.rank == 3) if (m_last_move.value().from.rank == 1 && m_last_move.value().to.rank == 3)
builder.append(Square(m_last_move.value().to.rank - 1, m_last_move.value().to.file).to_algebraic()); TRY(builder.try_append(TRY(Square(m_last_move.value().to.rank - 1, m_last_move.value().to.file).to_algebraic())));
else if (m_last_move.value().from.rank == 6 && m_last_move.value().to.rank == 4) else if (m_last_move.value().from.rank == 6 && m_last_move.value().to.rank == 4)
builder.append(Square(m_last_move.value().to.rank + 1, m_last_move.value().to.file).to_algebraic()); TRY(builder.try_append(TRY(Square(m_last_move.value().to.rank + 1, m_last_move.value().to.file).to_algebraic())));
else else
builder.append('-'); TRY(builder.try_append('-'));
} else { } else {
builder.append('-'); TRY(builder.try_append('-'));
} }
builder.append(' '); TRY(builder.try_append(' '));
// 5. Halfmove clock // 5. Halfmove clock
builder.append(DeprecatedString::number(min(m_moves_since_capture, m_moves_since_pawn_advance))); TRY(builder.try_appendff("{}", (min(m_moves_since_capture, m_moves_since_pawn_advance))));
builder.append(' '); TRY(builder.try_append(' '));
// 6. Fullmove number // 6. Fullmove number
builder.append(DeprecatedString::number(1 + m_moves.size() / 2)); TRY(builder.try_appendff("{}", (1 + m_moves.size() / 2)));
return builder.to_deprecated_string(); return builder.to_string();
} }
Piece Board::get_piece(Square const& square) const Piece Board::get_piece(Square const& square) const

View file

@ -93,7 +93,7 @@ struct Square {
char file_char() const; char file_char() const;
char rank_char() const; char rank_char() const;
DeprecatedString to_algebraic() const; ErrorOr<String> to_algebraic() const;
}; };
class Board; class Board;
@ -118,8 +118,8 @@ struct Move {
bool operator==(Move const& other) const { return from == other.from && to == other.to && promote_to == other.promote_to; } bool operator==(Move const& other) const { return from == other.from && to == other.to && promote_to == other.promote_to; }
static Move from_algebraic(StringView algebraic, const Color turn, Board const& board); static Move from_algebraic(StringView algebraic, const Color turn, Board const& board);
DeprecatedString to_long_algebraic() const; ErrorOr<String> to_long_algebraic() const;
DeprecatedString to_algebraic() const; ErrorOr<String> to_algebraic() const;
}; };
class Board { class Board {
@ -138,7 +138,7 @@ public:
bool apply_move(Move const&, Color color = Color::None); bool apply_move(Move const&, Color color = Color::None);
Optional<Move> const& last_move() const { return m_last_move; } Optional<Move> const& last_move() const { return m_last_move; }
DeprecatedString to_fen() const; ErrorOr<String> to_fen() const;
enum class Result { enum class Result {
CheckMate, CheckMate,

View file

@ -141,7 +141,7 @@ ErrorOr<String> PositionCommand::to_string() const
TRY(builder.try_append("moves"sv)); TRY(builder.try_append("moves"sv));
for (auto& move : moves()) { for (auto& move : moves()) {
TRY(builder.try_append(' ')); TRY(builder.try_append(' '));
TRY(builder.try_append(move.to_long_algebraic())); TRY(builder.try_append(TRY(move.to_long_algebraic())));
} }
TRY(builder.try_append('\n')); TRY(builder.try_append('\n'));
return builder.to_string(); return builder.to_string();
@ -202,7 +202,7 @@ ErrorOr<String> GoCommand::to_string() const
TRY(builder.try_append(" searchmoves"sv)); TRY(builder.try_append(" searchmoves"sv));
for (auto& move : searchmoves.value()) { for (auto& move : searchmoves.value()) {
TRY(builder.try_append(' ')); TRY(builder.try_append(' '));
TRY(builder.try_append(move.to_long_algebraic())); TRY(builder.try_append(TRY(move.to_long_algebraic())));
} }
} }
@ -318,7 +318,7 @@ ErrorOr<String> BestMoveCommand::to_string() const
{ {
StringBuilder builder; StringBuilder builder;
TRY(builder.try_append("bestmove "sv)); TRY(builder.try_append("bestmove "sv));
TRY(builder.try_append(move().to_long_algebraic())); TRY(builder.try_append(TRY(move().to_long_algebraic())));
TRY(builder.try_append('\n')); TRY(builder.try_append('\n'));
return builder.to_string(); return builder.to_string();
} }