Browse Source

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.
AnicJov 4 years ago
parent
commit
01b62cc7f4

+ 21 - 0
Games/Chess/ChessWidget.cpp

@@ -288,3 +288,24 @@ void ChessWidget::maybe_input_engine_move()
         update();
         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);
+}

+ 2 - 0
Games/Chess/ChessWidget.h

@@ -61,6 +61,8 @@ public:
     void set_drag_enabled(bool e) { m_drag_enabled = e; }
     void set_drag_enabled(bool e) { m_drag_enabled = e; }
     RefPtr<Gfx::Bitmap> get_piece_graphic(const Chess::Piece& piece) const;
     RefPtr<Gfx::Bitmap> get_piece_graphic(const Chess::Piece& piece) const;
 
 
+    void resign();
+    void flip_board();
     void reset();
     void reset();
 
 
     struct BoardTheme {
     struct BoardTheme {

+ 8 - 0
Games/Chess/main.cpp

@@ -85,6 +85,14 @@ int main(int argc, char** argv)
     auto menubar = GUI::MenuBar::construct();
     auto menubar = GUI::MenuBar::construct();
     auto& app_menu = menubar->add_menu("Chess");
     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&) {
     app_menu.add_action(GUI::Action::create("New game", { Mod_None, Key_F2 }, [&](auto&) {
         widget.reset();
         widget.reset();
     }));
     }));

+ 39 - 0
Libraries/LibChess/Chess.cpp

@@ -512,6 +512,9 @@ Move Board::random_move(Colour colour) const
 
 
 Board::Result Board::game_result() 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 sufficient_material = false;
     bool no_more_pieces_allowed = false;
     bool no_more_pieces_allowed = false;
     Optional<Square> bishop;
     Optional<Square> bishop;
@@ -684,4 +687,40 @@ bool Board::operator==(const Board& other) const
     return turn() == other.turn();
     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();
+    }
+}
+
 }
 }

+ 6 - 0
Libraries/LibChess/Chess.h

@@ -135,6 +135,8 @@ public:
     enum class Result {
     enum class Result {
         CheckMate,
         CheckMate,
         StaleMate,
         StaleMate,
+        WhiteResign,
+        BlackResign,
         FiftyMoveRule,
         FiftyMoveRule,
         SeventyFiveMoveRule,
         SeventyFiveMoveRule,
         ThreeFoldRepetition,
         ThreeFoldRepetition,
@@ -143,6 +145,8 @@ public:
         NotFinished,
         NotFinished,
     };
     };
 
 
+    String result_to_string(Result) const;
+
     template<typename Callback>
     template<typename Callback>
     void generate_moves(Callback callback, Colour colour = Colour::None) const;
     void generate_moves(Callback callback, Colour colour = Colour::None) const;
     Move random_move(Colour colour = Colour::None) const;
     Move random_move(Colour colour = Colour::None) const;
@@ -150,6 +154,7 @@ public:
     Colour game_winner() const;
     Colour game_winner() const;
     int game_score() const;
     int game_score() const;
     bool game_finished() const;
     bool game_finished() const;
+    void set_resigned(Colour);
     int material_imbalance() const;
     int material_imbalance() const;
 
 
     Colour turn() const { return m_turn; }
     Colour turn() const { return m_turn; }
@@ -164,6 +169,7 @@ private:
 
 
     Piece m_board[8][8];
     Piece m_board[8][8];
     Colour m_turn { Colour::White };
     Colour m_turn { Colour::White };
+    Colour m_resigned { Colour::None };
     Optional<Move> m_last_move;
     Optional<Move> m_last_move;
     int m_moves_since_capture { 0 };
     int m_moves_since_capture { 0 };