diff options
author | AnicJov <contact.andrija@gmail.com> | 2020-12-04 13:17:00 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-12-06 15:51:34 +0100 |
commit | 01b62cc7f495e25f783b97a5b021067c817d65a5 (patch) | |
tree | 0f750fc9e2b90aef5528b286577b0022a252a335 | |
parent | 694f68ab8694fb50cd177ae29e932ece50d9dbce (diff) | |
download | serenity-01b62cc7f495e25f783b97a5b021067c817d65a5.zip |
Chess: Added ability to resign and flip the board
This patch adds options to the app's menubar to resign the game and
flip the board.
-rw-r--r-- | Games/Chess/ChessWidget.cpp | 21 | ||||
-rw-r--r-- | Games/Chess/ChessWidget.h | 2 | ||||
-rw-r--r-- | Games/Chess/main.cpp | 8 | ||||
-rw-r--r-- | Libraries/LibChess/Chess.cpp | 39 | ||||
-rw-r--r-- | Libraries/LibChess/Chess.h | 6 |
5 files changed, 76 insertions, 0 deletions
diff --git a/Games/Chess/ChessWidget.cpp b/Games/Chess/ChessWidget.cpp index 1c965bcf2c..053d0c7e55 100644 --- a/Games/Chess/ChessWidget.cpp +++ b/Games/Chess/ChessWidget.cpp @@ -288,3 +288,24 @@ void ChessWidget::maybe_input_engine_move() update(); }); } + +void ChessWidget::flip_board() +{ + m_side = Chess::opposing_colour(m_side); + update(); +} + +void ChessWidget::resign() +{ + if (m_engine && m_board.turn() != m_side) { + GUI::MessageBox::show(window(), "You can only resign on your turn.", "Resign", GUI::MessageBox::Type::Information); + return; + } + + board().set_resigned(m_board.turn()); + + set_drag_enabled(false); + update(); + const String msg = m_board.result_to_string(m_board.game_result()); + GUI::MessageBox::show(window(), msg, "Game Over", GUI::MessageBox::Type::Information); +} diff --git a/Games/Chess/ChessWidget.h b/Games/Chess/ChessWidget.h index 7dd53b2edb..657caeefbd 100644 --- a/Games/Chess/ChessWidget.h +++ b/Games/Chess/ChessWidget.h @@ -61,6 +61,8 @@ public: void set_drag_enabled(bool e) { m_drag_enabled = e; } RefPtr<Gfx::Bitmap> get_piece_graphic(const Chess::Piece& piece) const; + void resign(); + void flip_board(); void reset(); struct BoardTheme { diff --git a/Games/Chess/main.cpp b/Games/Chess/main.cpp index 198ec54289..97a5de81f7 100644 --- a/Games/Chess/main.cpp +++ b/Games/Chess/main.cpp @@ -85,6 +85,14 @@ int main(int argc, char** argv) auto menubar = GUI::MenuBar::construct(); auto& app_menu = menubar->add_menu("Chess"); + app_menu.add_action(GUI::Action::create("Resign", { Mod_None, Key_F3 }, [&](auto&) { + widget.resign(); + })); + app_menu.add_action(GUI::Action::create("Flip Board", { Mod_None, Key_F4 }, [&](auto&) { + widget.flip_board(); + })); + app_menu.add_separator(); + app_menu.add_action(GUI::Action::create("New game", { Mod_None, Key_F2 }, [&](auto&) { widget.reset(); })); diff --git a/Libraries/LibChess/Chess.cpp b/Libraries/LibChess/Chess.cpp index 8c65f34b42..7a10049a39 100644 --- a/Libraries/LibChess/Chess.cpp +++ b/Libraries/LibChess/Chess.cpp @@ -512,6 +512,9 @@ Move Board::random_move(Colour colour) const Board::Result Board::game_result() const { + if (m_resigned != Colour::None) + return (m_resigned == Colour::White) ? Result::WhiteResign : Result::BlackResign; + bool sufficient_material = false; bool no_more_pieces_allowed = false; Optional<Square> bishop; @@ -684,4 +687,40 @@ bool Board::operator==(const Board& other) const return turn() == other.turn(); } +void Board::set_resigned(Chess::Colour c) +{ + m_resigned = c; +} + +String Board::result_to_string(Result r) const +{ + switch (r) { + case Result::CheckMate: + if (m_turn == Chess::Colour::White) + return "Black wins by Checkmate"; + else + return "White wins by Checkmate"; + case Result::WhiteResign: + return "Black wins by Resignation"; + case Result::BlackResign: + return "White wins by Resignation"; + case Result::StaleMate: + return "Draw by Stalemate"; + case Chess::Board::Result::FiftyMoveRule: + return "Draw by 50 move rule"; + case Chess::Board::Result::SeventyFiveMoveRule: + return "Draw by 75 move rule"; + case Chess::Board::Result::ThreeFoldRepetition: + return "Draw by threefold repetition"; + case Chess::Board::Result::FiveFoldRepetition: + return "Draw by fivefold repetition"; + case Chess::Board::Result::InsufficientMaterial: + return "Draw by insufficient material"; + case Chess::Board::Result::NotFinished: + return "Game not finished"; + default: + ASSERT_NOT_REACHED(); + } +} + } diff --git a/Libraries/LibChess/Chess.h b/Libraries/LibChess/Chess.h index d10c6ff758..787a6ed4b2 100644 --- a/Libraries/LibChess/Chess.h +++ b/Libraries/LibChess/Chess.h @@ -135,6 +135,8 @@ public: enum class Result { CheckMate, StaleMate, + WhiteResign, + BlackResign, FiftyMoveRule, SeventyFiveMoveRule, ThreeFoldRepetition, @@ -143,6 +145,8 @@ public: NotFinished, }; + String result_to_string(Result) const; + template<typename Callback> void generate_moves(Callback callback, Colour colour = Colour::None) const; Move random_move(Colour colour = Colour::None) const; @@ -150,6 +154,7 @@ public: Colour game_winner() const; int game_score() const; bool game_finished() const; + void set_resigned(Colour); int material_imbalance() const; Colour turn() const { return m_turn; } @@ -164,6 +169,7 @@ private: Piece m_board[8][8]; Colour m_turn { Colour::White }; + Colour m_resigned { Colour::None }; Optional<Move> m_last_move; int m_moves_since_capture { 0 }; |