Exemplo n.º 1
0
    def check_game_over(
        self,
        message: Dict[str, str],
        bot_handler: Any,
        new_board: chess.Board
    ) -> bool:
        """Checks if a game is over due to
         - checkmate,
         - stalemate,
         - insufficient material,
         - 50 moves without a capture or pawn move, or
         - 3-fold repetition.
        Replies to the bot handler if it is game over.

        Parameters:
             - message: The Zulip Bots message object.
             - bot_handler: The Zulip Bots bot handler object.
             - new_board: The board object.

        Returns: True if it is game over, false if it's not.
        """
        # This assumes that the players will claim a draw after 3-fold
        # repetition or 50 moves go by without a capture or pawn move.
        # According to the official rules, the game is only guaranteed to
        # be over if it's  *5*-fold or *75* moves, but if either player
        # wants the game to be a draw, after 3 or 75 it a draw. For now,
        # just assume that the players would want the draw.
        if new_board.is_game_over(True):
            game_over_output = ''

            if new_board.is_checkmate():
                game_over_output = make_loss_response(
                    new_board,
                    'was checkmated'
                )
            elif new_board.is_stalemate():
                game_over_output = make_draw_response('stalemate')
            elif new_board.is_insufficient_material():
                game_over_output = make_draw_response(
                    'insufficient material'
                )
            elif new_board.can_claim_fifty_moves():
                game_over_output = make_draw_response(
                    '50 moves without a capture or pawn move'
                )
            elif new_board.can_claim_threefold_repetition():
                game_over_output = make_draw_response('3-fold repetition')

            bot_handler.send_reply(
                message,
                game_over_output
            )

            return True

        return False
Exemplo n.º 2
0
    def write_json(self, board: chess.Board):
        """
        Writes all of the board info in json
        """

        best_move = self.get_best_move(board)

        output = OrderedDict([
            ('fen', board.fen()),
            ('fullmoveNumber', board.fullmove_number),
            ('result', board.result()),
            ('isGameOver', board.is_game_over()),
            ('isCheckmate', board.is_checkmate()),
            ('isStalemate', board.is_stalemate()),
            ('isInsufficientMaterial', board.is_insufficient_material()),
            ('isSeventyfiveMoves', board.is_seventyfive_moves()),
            ('isFivefoldRepetition', board.is_fivefold_repetition()),
            ('white',
             OrderedDict([
                 ('hasKingsideCastlingRights',
                  board.has_kingside_castling_rights(chess.WHITE)),
                 ('hasQueensideCastlingRights',
                  board.has_queenside_castling_rights(chess.WHITE)),
             ])),
            ('black',
             OrderedDict([
                 ('hasKingsideCastlingRights',
                  board.has_kingside_castling_rights(chess.BLACK)),
                 ('hasQueensideCastlingRights',
                  board.has_queenside_castling_rights(chess.BLACK)),
             ])),
            ('turn',
             OrderedDict([
                 ('color', 'white' if board.turn is chess.WHITE else 'black'),
                 ('isInCheck', board.is_check()),
                 ('bestMove', best_move),
                 ('legalMoves', [move.uci() for move in board.legal_moves]),
                 ('canClaimDraw', board.can_claim_draw()),
                 ('canClaimFiftyMoves', board.can_claim_fifty_moves()),
                 ('canClaimThreefoldRepetition',
                  board.can_claim_threefold_repetition()),
             ])),
        ])

        self.finish(output)
Exemplo n.º 3
0
def get_game_over_reason(board: chess.Board,
                         claim_draw: bool = False,
                         both_agreed: bool = False) -> str:
    if claim_draw and both_agreed:
        return "Both opponents agreed to a draw"

    reasons = [
        "Checkmate",
        "Stalemate",
        "Insufficient material",
        "Draw by the seventyfive-move rule",
        "Draw by the fivefold repetition rule",
    ]
    checks = [
        board.is_checkmate(),
        board.is_stalemate(),
        board.is_insufficient_material(),
        board.is_seventyfive_moves(),
        board.is_fivefold_repetition(),
    ]

    if claim_draw:
        reasons = [
            *reasons,
            *[
                "Draw by the fifty-move rule",
                "Draw by the threefold repetition rule"
            ],
        ]
        checks = [
            *checks,
            *[
                board.can_claim_fifty_moves(),
                board.can_claim_threefold_repetition()
            ],
        ]

    possible = [reason for reason, check in zip(reasons, checks) if check]

    if len(possible) > 0:
        return possible[0]
    else:
        raise RuntimeError("No possible game over reason")