From 6c2d0dea91d054b627714d223d7ffd78683704c9 Mon Sep 17 00:00:00 2001 From: Peter Elliott Date: Mon, 17 Aug 2020 15:40:55 -0600 Subject: [PATCH] Chess: Fix generation of promotion moves --- Games/Chess/Chess.cpp | 17 +++++++++++++++-- Games/Chess/Chess.h | 22 ++++++++++++---------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/Games/Chess/Chess.cpp b/Games/Chess/Chess.cpp index 88a8c220f2..c0a3f55807 100644 --- a/Games/Chess/Chess.cpp +++ b/Games/Chess/Chess.cpp @@ -153,7 +153,10 @@ bool Chess::is_legal_no_check(const Move& move, Colour colour) const if (move.to.rank > 7 || move.to.file > 7) return false; - if (move.promote_to == Type::Pawn || move.promote_to == Type::King || move.promote_to == Type::None) + if (piece.type != Type::Pawn && move.promote_to != Type::None) + return false; + + if (move.promote_to == Type::Pawn || move.promote_to == Type::King) return false; if (piece.type == Type::Pawn) { @@ -161,6 +164,14 @@ bool Chess::is_legal_no_check(const Move& move, Colour colour) const unsigned start_rank = (colour == Colour::White) ? 1 : 6; unsigned other_start_rank = (colour == Colour::White) ? 6 : 1; unsigned en_passant_rank = (colour == Colour::White) ? 4 : 3; + unsigned promotion_rank = (colour == Colour::White) ? 7 : 0; + + if (move.to.rank == promotion_rank) { + if (move.promote_to == Type::Pawn || move.promote_to == Type::King || move.promote_to == Type::None) + return false; + } else if (move.promote_to != Type::None) { + return false; + } if (move.to.rank == move.from.rank + dir && move.to.file == move.from.file && get_piece(move.to).type == Type::None) { // Regular pawn move. @@ -457,7 +468,9 @@ bool Chess::is_promotion_move(const Move& move, Colour colour) const if (colour == Colour::None) colour = turn(); - if (!is_legal(move, colour)) + Move queen_move = move; + queen_move.promote_to = Type::Queen; + if (!is_legal(queen_move, colour)) return false; if (get_piece(move.from).type == Type::Pawn && ((colour == Colour::Black && move.to.rank == 0) || (colour == Colour::White && move.to.rank == 7))) diff --git a/Games/Chess/Chess.h b/Games/Chess/Chess.h index 60d49b4da1..920b767aae 100644 --- a/Games/Chess/Chess.h +++ b/Games/Chess/Chess.h @@ -91,7 +91,7 @@ public: Square to; Type promote_to; Move(const StringView& algebraic); - Move(const Square& from, const Square& to, const Type& promote_to = Type::Queen) + Move(const Square& from, const Square& to, const Type& promote_to = Type::None) : from(from) , to(to) , promote_to(promote_to) @@ -200,15 +200,17 @@ void Chess::generate_moves(Callback callback, Colour colour) const bool keep_going = true; if (piece.type == Type::Pawn) { - keep_going = - try_move({sq, {sq.rank+1, sq.file}}) && - try_move({sq, {sq.rank+2, sq.file}}) && - try_move({sq, {sq.rank-1, sq.file}}) && - try_move({sq, {sq.rank-2, sq.file}}) && - try_move({sq, {sq.rank+1, sq.file+1}}) && - try_move({sq, {sq.rank+1, sq.file-1}}) && - try_move({sq, {sq.rank-1, sq.file+1}}) && - try_move({sq, {sq.rank-1, sq.file-1}}); + for (auto& piece : Vector({Type::None, Type::Knight, Type::Bishop, Type::Rook, Type::Queen})) { + keep_going = + try_move({sq, {sq.rank+1, sq.file}, piece}) && + try_move({sq, {sq.rank+2, sq.file}, piece}) && + try_move({sq, {sq.rank-1, sq.file}, piece}) && + try_move({sq, {sq.rank-2, sq.file}, piece}) && + try_move({sq, {sq.rank+1, sq.file+1}}) && + try_move({sq, {sq.rank+1, sq.file-1}}) && + try_move({sq, {sq.rank-1, sq.file+1}}) && + try_move({sq, {sq.rank-1, sq.file-1}}); + } } else if (piece.type == Type::Knight) { keep_going = try_move({sq, {sq.rank+2, sq.file+1}}) &&