def test_get_valid_moves_for_player(self):
        test_board = [[None, None, None, None, None, None, None, None],
                      [None, self.b, None, self.b, None, None, None, None],
                      [None, None, self.kw, None, None, None, None, None],
                      [None, self.b, None, self.b, None, None, None, None],
                      [None, None, None, None, None, None, None, None],
                      [None, None, None, None, None, None, None, None],
                      [None, None, None, None, None, None, None, None],
                      [None, None, None, None, None, None, None, None]]
        board = CheckersBoard()
        board.current_state = test_board
        move = CheckersMove(2, 2, 0, 0)
        self.assertTrue(
            len(CheckerGameUtil.get_valid_moves_for_player(board, self.w)) is 4
        )
        self.assertTrue(CheckerGameUtil.is_valid_move(move, self.w, board))
        self.assertTrue(
            len(CheckerGameUtil.get_jumps_from_position(self.w, 2, 2, board)))

        test_board = [[None, None, None, None, None, None, None, None],
                      [None, None, None, None, None, None, None, None],
                      [None, None, self.kw, None, None, None, None, None],
                      [None, None, None, None, None, None, None, None],
                      [None, None, None, None, None, None, None, None],
                      [None, None, None, None, self.kw, None, None, None],
                      [None, None, None, None, None, None, None, None],
                      [None, None, None, None, None, None, None, None]]
        board = CheckersBoard()
        board.current_state = test_board
        self.assertTrue(
            len(CheckerGameUtil.get_valid_moves_for_player(board, self.w)) is 8
        )
        self.assertFalse(CheckerGameUtil.is_valid_move(move, self.w, board))
    def get_valid_moves_for_player(board: CheckersBoard,
                                   player_color: str) -> list:
        """
        This method gets a list of legal moves
        :param board:
        :param player_color:
        :return: a list of legal moves
        """
        legal_moves = []
        if player_color is CHECKERS_TOKENS[1]:
            player_king = board.kw
        else:
            player_king = board.kb
        current_state = board.current_state

        # First it checks if the player can jump
        for r, row in enumerate(current_state):
            for c, col in enumerate(row):
                if current_state[r][c] is player_color or current_state[r][
                        c] is player_king:
                    if CheckerGameUtil.can_jump(player_color, r, c, r + 1,
                                                c + 1, r + 2, c + 2, board):
                        legal_moves.append(CheckersMove(r, c, r + 2, c + 2))
                    if CheckerGameUtil.can_jump(player_color, r, c, r - 1,
                                                c - 1, r - 2, c - 2, board):
                        legal_moves.append(CheckersMove(r, c, r - 2, c - 2))
                    if CheckerGameUtil.can_jump(player_color, r, c, r + 1,
                                                c - 1, r + 2, c - 2, board):
                        legal_moves.append(CheckersMove(r, c, r + 2, c - 2))
                    if CheckerGameUtil.can_jump(player_color, r, c, r - 1,
                                                c - 1, r - 2, c - 2, board):
                        legal_moves.append(CheckersMove(r, c, r - 2, c - 2))

        # if legal_moves has any item, that means the player is forced to jump, so not other kind of move is legal.
        # we check moves without jumps.
        if len(legal_moves) is 0:
            for r, row in enumerate(current_state):
                for c, col in enumerate(row):
                    if current_state[r][c] is player_color or current_state[r][
                            c] is player_king:
                        if CheckerGameUtil.can_move(player_color, r, c, r + 1,
                                                    c + 1, board):
                            legal_moves.append(CheckersMove(
                                r, c, r + 1, c + 1))
                        if CheckerGameUtil.can_move(player_color, r, c, r - 1,
                                                    c + 1, board):
                            legal_moves.append(CheckersMove(
                                r, c, r - 1, c + 1))
                        if CheckerGameUtil.can_move(player_color, r, c, r + 1,
                                                    c - 1, board):
                            legal_moves.append(CheckersMove(
                                r, c, r + 1, c - 1))
                        if CheckerGameUtil.can_move(player_color, r, c, r - 1,
                                                    c - 1, board):
                            legal_moves.append(CheckersMove(
                                r, c, r - 1, c - 1))
        return legal_moves
 def is_valid_move(self, move: dict, player: Player) -> bool:
     r1, c1, r2, c2 = move[MOVE]
     if player.game_token is "kw":
         player_color = "w"
     elif player.game_token is "kb":
         player_color = "b"
     else:
         player_color = player.game_token
     move = CheckersMove(r1, c1, r2, c2)
     return CheckerGameUtil.is_valid_move(move, player_color, self.board)
 def make_move(self, move: dict, player: Player) -> bool:
     origin_x, origin_y, move_x, move_y = move[MOVE]
     legal_moves = CheckerGameUtil.get_valid_moves_for_player(
         self.board, player.game_token)
     checkers_move = CheckersMove(origin_x, origin_y, move_x, move_y)
     i = legal_moves.index(checkers_move)
     checkers_move = legal_moves[i]
     self.board.current_state[checkers_move.fr][checkers_move.fc] = None
     self.board.current_state[checkers_move.tr][
         checkers_move.tc] = move[GAME_TOKEN]
     if checkers_move.is_jump:
         self.board.current_state[checkers_move.jumped_enemy_row][
             checkers_move.jumped_enemy_col] = None
     return len(
         CheckerGameUtil.get_jumps_from_position(player.game_token, move_x,
                                                 move_y, self.board)) > 0
    def get_jumps_from_position(player_color, r, c,
                                board: CheckersBoard) -> list:
        current_state = board.current_state
        legal_jumps = []
        if player_color is CHECKERS_TOKENS[1]:
            player_king = board.kw
        else:
            player_king = board.kb
        if current_state[r][c] is player_color or current_state[r][
                c] is player_king:
            if CheckerGameUtil.can_jump(player_color, r, c, r + 1, c + 1,
                                        r + 2, c + 2, board):
                move = CheckersMove(r, c, r + 2, c + 2)
                move.is_jump = True
                move.jumped_enemy_col = c + 1
                move.jumped_enemy_row = r + 1
                legal_jumps.append(move)
            if CheckerGameUtil.can_jump(player_color, r, c, r - 1, c - 1,
                                        r - 2, c - 2, board):
                move = CheckersMove(r, c, r - 2, c - 2)
                move.is_jump = True
                move.jumped_enemy_row = r - 1
                move.jumped_enemy_col = c - 1
                legal_jumps.append(move)
            if CheckerGameUtil.can_jump(player_color, r, c, r + 1, c - 1,
                                        r + 2, c - 2, board):
                move = CheckersMove(r, c, r + 2, c - 2)
                move.is_jump = True
                move.jumped_enemy_row = r + 1
                move.jumped_enemy_col = c - 1
                legal_jumps.append(move)

            if CheckerGameUtil.can_jump(player_color, r, c, r - 1, c - 1,
                                        r - 2, c - 2, board):
                move = CheckersMove(r, c, r - 2, c - 2)
                move.is_jump = True
                move.jumped_enemy_col = c - 1
                move.jumped_enemy_row = r - 1
                legal_jumps.append(move)
        return legal_jumps