diff options
author | Peter Elliott <pelliott@ualberta.ca> | 2020-08-20 17:04:08 -0600 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-08-21 12:26:30 +0200 |
commit | 1e57e32a93f96cf40f29e9388bd2cb4b99782675 (patch) | |
tree | 31fbc6fa9768d5d8373e305ac5ae557091a2057d /Libraries | |
parent | fb62eed05889b1fef9373843ac048e4b05056a4b (diff) | |
download | serenity-1e57e32a93f96cf40f29e9388bd2cb4b99782675.zip |
ChessEngine: Add ChessEngine
This engine is pretty bad, but doesn't let itself get checkmated
Diffstat (limited to 'Libraries')
-rw-r--r-- | Libraries/LibChess/Chess.cpp | 80 | ||||
-rw-r--r-- | Libraries/LibChess/Chess.h | 5 |
2 files changed, 83 insertions, 2 deletions
diff --git a/Libraries/LibChess/Chess.cpp b/Libraries/LibChess/Chess.cpp index 7495acf0fb..6e332e3cc4 100644 --- a/Libraries/LibChess/Chess.cpp +++ b/Libraries/LibChess/Chess.cpp @@ -425,8 +425,8 @@ bool Board::apply_illegal_move(const Move& move, Colour colour) if (move.to == Square("a8") || move.to == Square("c8")) { set_piece(Square("e8"), EmptyPiece); set_piece(Square("a8"), EmptyPiece); - set_piece(Square("c8"), { Colour::White, Type::King }); - set_piece(Square("d8"), { Colour::White, Type::Rook }); + set_piece(Square("c8"), { Colour::Black, Type::King }); + set_piece(Square("d8"), { Colour::Black, Type::Rook }); return true; } else if (move.to == Square("h8") || move.to == Square("g8")) { set_piece(Square("e8"), EmptyPiece); @@ -463,6 +463,23 @@ bool Board::apply_illegal_move(const Move& move, Colour colour) return true; } +Move Board::random_move(Colour colour) const +{ + if (colour == Colour::None) + colour = turn(); + + Move move = { { 50, 50 }, { 50, 50 } }; + int probability = 1; + generate_moves([&](Move m) { + if (rand() % probability == 0) + move = m; + ++probability; + return IterationDecision::Continue; + }); + + return move; +} + Board::Result Board::game_result() const { bool sufficient_material = false; @@ -533,6 +550,65 @@ Board::Result Board::game_result() const return Result::StaleMate; } +Colour Board::game_winner() const +{ + if (game_result() == Result::CheckMate) + return opposing_colour(turn()); + + return Colour::None; +} + +int Board::game_score() const +{ + switch (game_winner()) { + case Colour::White: + return +1; + case Colour::Black: + return -1; + case Colour::None: + return 0; + } + return 0; +} + +bool Board::game_finished() const +{ + return game_result() != Result::NotFinished; +} + +int Board::material_imbalance() const +{ + int imbalance = 0; + Square::for_each([&](Square square) { + int value = 0; + switch (get_piece(square).type) { + case Type::Pawn: + value = 1; + break; + case Type::Knight: + case Type::Bishop: + value = 3; + break; + case Type::Rook: + value = 5; + break; + case Type::Queen: + value = 9; + break; + default: + break; + } + + if (get_piece(square).colour == Colour::White) { + imbalance += value; + } else { + imbalance -= value; + } + return IterationDecision::Continue; + }); + return imbalance; +} + bool Board::is_promotion_move(const Move& move, Colour colour) const { if (colour == Colour::None) diff --git a/Libraries/LibChess/Chess.h b/Libraries/LibChess/Chess.h index 2e9c078f78..f0e0b91aab 100644 --- a/Libraries/LibChess/Chess.h +++ b/Libraries/LibChess/Chess.h @@ -135,7 +135,12 @@ public: template<typename Callback> void generate_moves(Callback callback, Colour colour = Colour::None) const; + Move random_move(Colour colour = Colour::None) const; Result game_result() const; + Colour game_winner() const; + int game_score() const; + bool game_finished() const; + int material_imbalance() const; Colour turn() const { return m_turn; } const Vector<Move>& moves() const { return m_moves; } |