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.
This commit is contained in:
parent
694f68ab86
commit
01b62cc7f4
Notes:
sideshowbarker
2024-07-19 17:31:57 +09:00
Author: https://github.com/AnicJov Commit: https://github.com/SerenityOS/serenity/commit/01b62cc7f49 Pull-request: https://github.com/SerenityOS/serenity/pull/4321 Reviewed-by: https://github.com/bcoles Reviewed-by: https://github.com/emanuele6 Reviewed-by: https://github.com/petelliott
5 changed files with 76 additions and 0 deletions
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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();
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue