mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 03:47:35 +00:00
Chess: Display appropriate dialog when engine move ends the game
A dialog is now displayed when an engine move results in a checkmate or a draw. In the case of threefold repetition or the fifty move rule, the engine will always accept a draw. A human player is asked if they would like to accept a draw.
This commit is contained in:
parent
d9f0c2a806
commit
e1de31a3fe
2 changed files with 55 additions and 56 deletions
|
@ -262,62 +262,10 @@ void ChessWidget::mouseup_event(GUI::MouseEvent& event)
|
||||||
m_playback_move_number = board().moves().size();
|
m_playback_move_number = board().moves().size();
|
||||||
m_playback = false;
|
m_playback = false;
|
||||||
m_board_playback = m_board;
|
m_board_playback = m_board;
|
||||||
|
// If two humans are playing, ask whether they wish to accept a draw.
|
||||||
if (board().game_result() != Chess::Board::Result::NotFinished) {
|
auto claim_draw_behavior = m_engine.is_null() ? ClaimDrawBehavior::Prompt : ClaimDrawBehavior::Always;
|
||||||
bool over = true;
|
if (!check_game_over(claim_draw_behavior))
|
||||||
StringView msg;
|
|
||||||
switch (board().game_result()) {
|
|
||||||
case Chess::Board::Result::CheckMate:
|
|
||||||
if (board().turn() == Chess::Color::White) {
|
|
||||||
msg = "Black wins by Checkmate."sv;
|
|
||||||
} else {
|
|
||||||
msg = "White wins by Checkmate."sv;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Chess::Board::Result::StaleMate:
|
|
||||||
msg = "Draw by Stalemate."sv;
|
|
||||||
break;
|
|
||||||
case Chess::Board::Result::FiftyMoveRule:
|
|
||||||
update();
|
|
||||||
if (GUI::MessageBox::show(window(), "50 moves have elapsed without a capture. Claim Draw?"sv, "Claim Draw?"sv,
|
|
||||||
GUI::MessageBox::Type::Information, GUI::MessageBox::InputType::YesNo)
|
|
||||||
== GUI::Dialog::ExecResult::Yes) {
|
|
||||||
msg = "Draw by 50 move rule."sv;
|
|
||||||
} else {
|
|
||||||
over = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Chess::Board::Result::SeventyFiveMoveRule:
|
|
||||||
msg = "Draw by 75 move rule."sv;
|
|
||||||
break;
|
|
||||||
case Chess::Board::Result::ThreeFoldRepetition:
|
|
||||||
update();
|
|
||||||
if (GUI::MessageBox::show(window(), "The same board state has repeated three times. Claim Draw?"sv, "Claim Draw?"sv,
|
|
||||||
GUI::MessageBox::Type::Information, GUI::MessageBox::InputType::YesNo)
|
|
||||||
== GUI::Dialog::ExecResult::Yes) {
|
|
||||||
msg = "Draw by threefold repetition."sv;
|
|
||||||
} else {
|
|
||||||
over = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Chess::Board::Result::FiveFoldRepetition:
|
|
||||||
msg = "Draw by fivefold repetition."sv;
|
|
||||||
break;
|
|
||||||
case Chess::Board::Result::InsufficientMaterial:
|
|
||||||
msg = "Draw by insufficient material."sv;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
VERIFY_NOT_REACHED();
|
|
||||||
}
|
|
||||||
if (over) {
|
|
||||||
set_override_cursor(Gfx::StandardCursor::None);
|
|
||||||
set_drag_enabled(false);
|
|
||||||
update();
|
|
||||||
GUI::MessageBox::show(window(), msg, "Game Over"sv, GUI::MessageBox::Type::Information);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
input_engine_move();
|
input_engine_move();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
@ -485,8 +433,11 @@ void ChessWidget::input_engine_move()
|
||||||
if (!want_engine_move())
|
if (!want_engine_move())
|
||||||
return;
|
return;
|
||||||
set_drag_enabled(drag_was_enabled);
|
set_drag_enabled(drag_was_enabled);
|
||||||
if (!move.is_error())
|
if (!move.is_error()) {
|
||||||
VERIFY(board().apply_move(move.release_value()));
|
VERIFY(board().apply_move(move.release_value()));
|
||||||
|
if (check_game_over(ClaimDrawBehavior::Prompt))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_playback_move_number = m_board.moves().size();
|
m_playback_move_number = m_board.moves().size();
|
||||||
m_playback = false;
|
m_playback = false;
|
||||||
|
@ -713,6 +664,47 @@ int ChessWidget::resign()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ChessWidget::check_game_over(ClaimDrawBehavior claim_draw_behavior)
|
||||||
|
{
|
||||||
|
if (board().game_result() == Chess::Board::Result::NotFinished)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto over = true;
|
||||||
|
switch (board().game_result()) {
|
||||||
|
case Chess::Board::Result::FiftyMoveRule:
|
||||||
|
if (claim_draw_behavior == ClaimDrawBehavior::Prompt) {
|
||||||
|
update();
|
||||||
|
auto dialog_result = GUI::MessageBox::show(window(), "50 moves have elapsed without a capture. Claim Draw?"sv, "Claim Draw?"sv,
|
||||||
|
GUI::MessageBox::Type::Information, GUI::MessageBox::InputType::YesNo);
|
||||||
|
|
||||||
|
if (dialog_result != GUI::Dialog::ExecResult::Yes)
|
||||||
|
over = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Chess::Board::Result::ThreeFoldRepetition:
|
||||||
|
if (claim_draw_behavior == ClaimDrawBehavior::Prompt) {
|
||||||
|
update();
|
||||||
|
auto dialog_result = GUI::MessageBox::show(window(), "The same board state has repeated three times. Claim Draw?"sv, "Claim Draw?"sv,
|
||||||
|
GUI::MessageBox::Type::Information, GUI::MessageBox::InputType::YesNo);
|
||||||
|
if (dialog_result != GUI::Dialog::ExecResult::Yes)
|
||||||
|
over = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!over)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
set_override_cursor(Gfx::StandardCursor::None);
|
||||||
|
set_drag_enabled(false);
|
||||||
|
update();
|
||||||
|
auto msg = Chess::Board::result_to_string(board().game_result(), board().turn());
|
||||||
|
GUI::MessageBox::show(window(), msg, "Game Over"sv, GUI::MessageBox::Type::Information);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void ChessWidget::config_string_did_change(DeprecatedString const& domain, DeprecatedString const& group, DeprecatedString const& key, DeprecatedString const& value)
|
void ChessWidget::config_string_did_change(DeprecatedString const& domain, DeprecatedString const& group, DeprecatedString const& key, DeprecatedString const& value)
|
||||||
{
|
{
|
||||||
if (domain != "Games"sv && group != "Chess"sv)
|
if (domain != "Games"sv && group != "Chess"sv)
|
||||||
|
|
|
@ -111,11 +111,18 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum class ClaimDrawBehavior {
|
||||||
|
Always,
|
||||||
|
Prompt
|
||||||
|
};
|
||||||
|
|
||||||
ChessWidget() = default;
|
ChessWidget() = default;
|
||||||
|
|
||||||
virtual void config_string_did_change(DeprecatedString const& domain, DeprecatedString const& group, DeprecatedString const& key, DeprecatedString const& value) override;
|
virtual void config_string_did_change(DeprecatedString const& domain, DeprecatedString const& group, DeprecatedString const& key, DeprecatedString const& value) override;
|
||||||
virtual void config_bool_did_change(DeprecatedString const& domain, DeprecatedString const& group, DeprecatedString const& key, bool value) override;
|
virtual void config_bool_did_change(DeprecatedString const& domain, DeprecatedString const& group, DeprecatedString const& key, bool value) override;
|
||||||
|
|
||||||
|
bool check_game_over(ClaimDrawBehavior);
|
||||||
|
|
||||||
Chess::Board m_board;
|
Chess::Board m_board;
|
||||||
Chess::Board m_board_playback;
|
Chess::Board m_board_playback;
|
||||||
bool m_playback { false };
|
bool m_playback { false };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue