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
Notes: sideshowbarker 2024-07-18 03:23:00 +09:00
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
{
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)
@ -659,10 +659,10 @@ ErrorOr<void> ChessWidget::export_pgn(Core::File& file) const
// Movetext Section
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()) {
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()));
} else {
TRY(file.write_until_depleted(DeprecatedString::formatted("{}. {} ", move_no, white).bytes()));

View File

@ -7,7 +7,7 @@
#include <AK/Assertions.h>
#include <AK/CharacterTypes.h>
#include <AK/DeprecatedString.h>
#include <AK/String.h>
#include <AK/StringBuilder.h>
#include <AK/Vector.h>
#include <LibChess/Chess.h>
@ -94,12 +94,9 @@ char Square::rank_char() const
return rank + '1';
}
DeprecatedString Square::to_algebraic() const
ErrorOr<String> Square::to_algebraic() const
{
StringBuilder builder;
builder.append(file + 'a');
builder.append(rank + '1');
return builder.to_deprecated_string();
return String::formatted("{}{}", file_char(), rank_char());
}
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;
builder.append(from.to_algebraic());
builder.append(to.to_algebraic());
TRY(builder.try_append(TRY(from.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())
builder.append(to_ascii_lowercase(promoted_char.value()));
return builder.to_deprecated_string();
TRY(builder.try_append(to_ascii_lowercase(promoted_char.value())));
return builder.to_string();
}
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;
}
DeprecatedString Move::to_algebraic() const
ErrorOr<String> Move::to_algebraic() const
{
if (piece.type == Type::King && from.file == 4) {
if (to.file == 2)
return "O-O-O";
return "O-O-O"_short_string;
if (to.file == 6)
return "O-O";
return "O-O"_short_string;
}
StringBuilder builder;
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 (from.file != ambiguous.file)
builder.append(from.file_char());
TRY(builder.try_append(from.file_char()));
else if (from.rank != ambiguous.rank)
builder.append(from.rank_char());
TRY(builder.try_append(from.rank_char()));
else
builder.append(from.to_algebraic());
TRY(builder.try_append(TRY(from.to_algebraic())));
}
if (is_capture) {
if (piece.type == Type::Pawn && !is_ambiguous)
builder.append(from.file_char());
builder.append('x');
TRY(builder.try_append(from.file_char()));
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) {
builder.append('=');
builder.append(char_for_piece(promote_to, Notation::Algebraic).value());
TRY(builder.try_append('='));
TRY(builder.try_append(char_for_piece(promote_to, Notation::Algebraic).value()));
}
if (is_mate)
builder.append('#');
TRY(builder.try_append('#'));
else if (is_check)
builder.append('+');
TRY(builder.try_append('+'));
return builder.to_deprecated_string();
return builder.to_string();
}
Board::Board()
@ -289,7 +286,7 @@ Board Board::clone_without_history() const
return result;
}
DeprecatedString Board::to_fen() const
ErrorOr<String> Board::to_fen() const
{
StringBuilder builder;
@ -303,57 +300,61 @@ DeprecatedString Board::to_fen() const
continue;
}
if (empty > 0) {
builder.append(DeprecatedString::number(empty));
TRY(builder.try_appendff("{}", empty));
empty = 0;
}
auto const piece = char_for_piece(p.type, Notation::FEN).value();
if (p.color == Color::Black)
builder.append(to_ascii_lowercase(piece));
TRY(builder.try_append(to_ascii_lowercase(piece)));
else
builder.append(piece);
TRY(builder.try_append(piece));
}
if (empty > 0) {
builder.append(DeprecatedString::number(empty));
TRY(builder.try_appendff("{}", empty));
empty = 0;
}
if (rank < 7)
builder.append('/');
TRY(builder.try_append('/'));
}
// 2. Active color
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
builder.append(m_white_can_castle_kingside ? "K"sv : ""sv);
builder.append(m_white_can_castle_queenside ? "Q"sv : ""sv);
builder.append(m_black_can_castle_kingside ? "k"sv : ""sv);
builder.append(m_black_can_castle_queenside ? "q"sv : ""sv);
builder.append(' ');
if (m_white_can_castle_kingside)
TRY(builder.try_append('K'));
if (m_white_can_castle_queenside)
TRY(builder.try_append('Q'));
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
if (!m_last_move.has_value())
builder.append('-');
TRY(builder.try_append('-'));
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)
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)
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
builder.append('-');
TRY(builder.try_append('-'));
} else {
builder.append('-');
TRY(builder.try_append('-'));
}
builder.append(' ');
TRY(builder.try_append(' '));
// 5. Halfmove clock
builder.append(DeprecatedString::number(min(m_moves_since_capture, m_moves_since_pawn_advance)));
builder.append(' ');
TRY(builder.try_appendff("{}", (min(m_moves_since_capture, m_moves_since_pawn_advance))));
TRY(builder.try_append(' '));
// 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

View File

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

View File

@ -141,7 +141,7 @@ ErrorOr<String> PositionCommand::to_string() const
TRY(builder.try_append("moves"sv));
for (auto& move : moves()) {
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'));
return builder.to_string();
@ -202,7 +202,7 @@ ErrorOr<String> GoCommand::to_string() const
TRY(builder.try_append(" searchmoves"sv));
for (auto& move : searchmoves.value()) {
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;
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'));
return builder.to_string();
}