summaryrefslogtreecommitdiff
path: root/Games/Chess
diff options
context:
space:
mode:
authorBrendan Coles <bcoles@gmail.com>2020-12-17 03:01:58 +0000
committerAndreas Kling <kling@serenityos.org>2020-12-17 19:45:05 +0100
commit172707a94585b739cfeef4aefdddb475ed2ba6d9 (patch)
tree2f589afcf9e3a4714828da32eb869f902e127c0c /Games/Chess
parent07badd953037b49ac754a644c59ae9531754fce1 (diff)
downloadserenity-172707a94585b739cfeef4aefdddb475ed2ba6d9.zip
Chess: Prevent board changes when waiting for ChessEngine to move
Diffstat (limited to 'Games/Chess')
-rw-r--r--Games/Chess/ChessWidget.cpp36
-rw-r--r--Games/Chess/ChessWidget.h5
-rw-r--r--Games/Chess/main.cpp6
3 files changed, 37 insertions, 10 deletions
diff --git a/Games/Chess/ChessWidget.cpp b/Games/Chess/ChessWidget.cpp
index 36b3260bf8..918b0dcf50 100644
--- a/Games/Chess/ChessWidget.cpp
+++ b/Games/Chess/ChessWidget.cpp
@@ -273,7 +273,7 @@ void ChessWidget::mouseup_event(GUI::MouseEvent& event)
GUI::MessageBox::show(window(), msg, "Game Over", GUI::MessageBox::Type::Information);
}
} else {
- maybe_input_engine_move();
+ input_engine_move();
}
}
@@ -372,7 +372,7 @@ void ChessWidget::reset()
m_board = Chess::Board();
m_side = (arc4random() % 2) ? Chess::Colour::White : Chess::Colour::Black;
m_drag_enabled = true;
- maybe_input_engine_move();
+ input_engine_move();
update();
}
@@ -391,9 +391,18 @@ void ChessWidget::set_board_theme(const StringView& name)
}
}
-void ChessWidget::maybe_input_engine_move()
+bool ChessWidget::want_engine_move()
{
- if (!m_engine || board().turn() == side())
+ if (!m_engine)
+ return false;
+ if (board().turn() == side())
+ return false;
+ return true;
+}
+
+void ChessWidget::input_engine_move()
+{
+ if (!want_engine_move())
return;
bool drag_was_enabled = drag_enabled();
@@ -401,6 +410,8 @@ void ChessWidget::maybe_input_engine_move()
set_drag_enabled(false);
m_engine->get_best_move(board(), 4000, [this, drag_was_enabled](Chess::Move move) {
+ if (!want_engine_move())
+ return;
set_drag_enabled(drag_was_enabled);
ASSERT(board().apply_move(move));
m_playback_move_number = m_board.moves().size();
@@ -614,21 +625,32 @@ bool ChessWidget::export_pgn(const StringView& export_path) const
void ChessWidget::flip_board()
{
+ if (want_engine_move()) {
+ GUI::MessageBox::show(window(), "You can only flip the board on your turn.", "Flip Board", GUI::MessageBox::Type::Information);
+ return;
+ }
m_side = Chess::opposing_colour(m_side);
+ input_engine_move();
update();
}
-void ChessWidget::resign()
+int ChessWidget::resign()
{
- if (m_engine && m_board.turn() != m_side) {
+ if (want_engine_move()) {
GUI::MessageBox::show(window(), "You can only resign on your turn.", "Resign", GUI::MessageBox::Type::Information);
- return;
+ return -1;
}
+ auto result = GUI::MessageBox::show(window(), "Are you sure you wish to resign?", "Resign", GUI::MessageBox::Type::Warning, GUI::MessageBox::InputType::YesNo);
+ if (result != GUI::MessageBox::ExecYes)
+ return -1;
+
board().set_resigned(m_board.turn());
set_drag_enabled(false);
update();
const String msg = Chess::Board::result_to_string(m_board.game_result(), m_board.turn());
GUI::MessageBox::show(window(), msg, "Game Over", GUI::MessageBox::Type::Information);
+
+ return 0;
}
diff --git a/Games/Chess/ChessWidget.h b/Games/Chess/ChessWidget.h
index 493c93d25b..906bdbb7e9 100644
--- a/Games/Chess/ChessWidget.h
+++ b/Games/Chess/ChessWidget.h
@@ -70,7 +70,7 @@ public:
bool import_pgn(const StringView& import_path);
bool export_pgn(const StringView& export_path) const;
- void resign();
+ int resign();
void flip_board();
void reset();
@@ -95,7 +95,8 @@ public:
void set_engine(RefPtr<Engine> engine) { m_engine = engine; }
- void maybe_input_engine_move();
+ void input_engine_move();
+ bool want_engine_move();
void set_coordinates(bool coordinates) { m_coordinates = coordinates; }
bool coordinates() const { return m_coordinates; }
diff --git a/Games/Chess/main.cpp b/Games/Chess/main.cpp
index 150b25caaf..64545e944d 100644
--- a/Games/Chess/main.cpp
+++ b/Games/Chess/main.cpp
@@ -139,6 +139,10 @@ int main(int argc, char** argv)
app_menu.add_separator();
app_menu.add_action(GUI::Action::create("New game", { Mod_None, Key_F2 }, [&](auto&) {
+ if (widget.board().game_result() == Chess::Board::Result::NotFinished) {
+ if (widget.resign() < 0)
+ return;
+ }
widget.reset();
}));
app_menu.add_separator();
@@ -206,7 +210,7 @@ int main(int argc, char** argv)
widget.set_engine(nullptr);
} else {
widget.set_engine(Engine::construct(action.text()));
- widget.maybe_input_engine_move();
+ widget.input_engine_move();
}
});
engines_action_group.add_action(*action);