Beispiel #1
0
 def buildGameStateFromID(self):
     """
     plays 4 moves on self.board if they're possible
     """
     # positionID = eg 4256 -> 1. Move: 4th Column, 2. Move: 2nd column
     player = self.player
     for col in self.positionID:
         action = PlayerAction(int(col))
         if move_is_possible(self.board, action):
             apply_player_action(self.board, action, player)
             player = other_player(player)
         else:
             self.status = False
             break
Beispiel #2
0
def move_seq_to_board_input_vector(move_sequences: np.array) -> np.array:
    """
    takes X-Matrix with move sequences and convert each sequence into the board.
    """

    boards = np.ndarray((0, 42), int)
    for move_seq in move_sequences:
        player = PLAYER1
        board = initialize_game_state()
        for col in move_seq:
            apply_player_action(board, col - 1, player)
            player = other_player(player)

        boards = np.vstack([boards, board.flatten()])

    return boards
Beispiel #3
0
 def __init__(self, player: BoardPiece, positionID: str, board: np.ndarray):
     """
     recursively building game tree, every middle node (those who are less than depth 4) has list of children,
     building when GameState with root is called. All nodes on depth 4 get a board copy, it'll get modified later by
     buildGameStateFromID and the score of all nodes is None at the beginning.
     """
     self.positionID = positionID
     self.player = player
     self.possible = True
     self.score = 0
     if len(positionID) < 4:
         # print('positionID <4:', positionID)
         self.children = []
         for i in range(7):
             self.children.append(GameState(other_player(player), positionID + str(i), board))
     else:
         # print('positionID >= 4: ', positionID)
         self.board = board.copy()
Beispiel #4
0
def generate_move_supervised(
    board: np.ndarray, player: BoardPiece, saved_state: Optional[SavedState]
) -> Tuple[PlayerAction, Optional[SavedState]]:
    """
    Choose a valid, non-full column with the prediction of a supervised ml trained model, checks for possibility to win
    or requirement to block first, predict and check if the predicted move is actually possible, if not do middle column
    and if this is also not possible pick a random of the possible moves.
    :param board:
    :param player:
    :param saved_state:
    :return:
    """
    # Choose a valid, non-full column with supervised ml algorithm and return it as `action`

    # if agent can win
    win = column_to_be_played_for_win(board, player)
    if win > -1:
        return win, saved_state

    # if agent has to block
    block = column_to_be_played_for_win(board, other_player(player))
    if block > -1:
        return block, saved_state

    action = np.int8(predict_move(board))

    if move_is_possible(board, action):
        return action, saved_state
    else:
        print('prediction error')
        possible_moves = []
        if move_is_possible(board, np.int8(3)):
            return np.int8(3), saved_state
        else:
            for i in range(7):
                if move_is_possible(board, np.int8(i)):
                    possible_moves = np.append(possible_moves, i)

    action = np.random.choice(possible_moves, 1)
    action = action.astype(np.int8)

    return action, saved_state
Beispiel #5
0
def evaluate_heuristic(board: np.ndarray, action: PlayerAction,
                       player: BoardPiece) -> int:
    """
    Calculates a score for a board

    Parameters
    ----------
    board : np.ndarray
            Board that the move is performed on
    action: PlayerAction
            Column of the move that is performed
    player: BoardPiece
            Player who performs the move

    Return
    ------
    Aggregated Score of all Moves that are possible after the action is performed

    """

    board_copy = board.copy()
    board_copy = apply_player_action(board_copy, action, player, False)

    heuristic = 0
    # check if player can win with this action
    if connected_four(board_copy, player, None):
        heuristic = 99
        return heuristic

    # check if other player can win with this action
    board_copy2 = board.copy()
    apply_player_action(board_copy2, action, other_player(player), False)

    if connected_four(board_copy2, other_player(player), None):
        heuristic = -99
        return heuristic

    # find lowest open row
    for row in range(6):
        if board[row, action] == NO_PLAYER:
            break
        if row == 5:
            raise ValueError("column can't be played")

    # initialize calculation values
    skip_a, skip_b, skip_c, skip_d, skip_e, skip_f, skip_g, skip_h = False, False, False, False, False, False, False, False
    streak_ab, streak_cd, streak_ef, streak_gh = 1, 1, 1, 1
    heuristic_a, heuristic_b, heuristic_c, heuristic_d, heuristic_e, heuristic_f, heuristic_g, heuristic_h = 0, 0, 0, 0, 0, 0, 0, 0

    for i in range(1, 4):
        if (action + i) < 7 and not skip_a:
            if board[row, action + i] == player:
                heuristic_a += 1
                streak_ab += 1
            elif board[row, action + i] == NO_PLAYER:
                streak_ab += 1
            else:
                skip_a = True

        if (action - i) > -1 and not skip_b:
            if board[row, action - i] == player:
                heuristic_b += 1
                streak_ab += 1
            elif board[row, action - i] == NO_PLAYER:
                streak_ab += 1
            else:
                skip_b = True

        if (row + i) < 6 and not skip_c:
            if board[row + i, action] == player:
                heuristic_c += 1
                streak_cd += 1
            elif board[row + i, action] == NO_PLAYER:
                streak_cd += 1
            else:
                skip_c = True

        if (row - i) > -1 and not skip_d:
            if board[row - i, action] == player:
                heuristic_d += 1
                streak_cd += 1
            elif board[row - i, action] == NO_PLAYER:
                streak_cd += 1
            else:
                skip_d = True

        if ((action + i) < 7 and (row + i) < 6) and not skip_e:
            if board[row + i, action + i] == player:
                heuristic_e += 1
                streak_ef += 1
            elif board[row + i, action + i] == NO_PLAYER:
                streak_ef += 1
            else:
                skip_e = True

        if ((action - i) > -1 and (row - i) > -1) and not skip_f:
            if board[row - i, action - i] == player:
                heuristic_f += 1
                streak_ef += 1
            elif board[row - i, action - i] == NO_PLAYER:
                streak_ef += 1
            else:
                skip_f = True

        if ((action + i) < 7 and (row - i) > -1) and not skip_g:
            if board[row - i, action + i] == player:
                heuristic_g += 1
                streak_gh += 1
            elif board[row - i, action + i] == NO_PLAYER:
                streak_gh += 1
            else:
                skip_g = True

        if ((action - i) > -1 and (row + i) < 6) and not skip_h:
            if board[row + i, action - i] == player:
                heuristic_h += 1
                streak_gh += 1
            elif board[row + i, action - i] == NO_PLAYER:
                streak_gh += 1
            else:
                skip_h = True

    if streak_ab < 4:
        # wenn mit dem move in einer Reihe keine 4 erreicht werden können
        heuristic_a = 0
        heuristic_b = 0
    elif streak_ab == 7:
        heuristic += 2
    else:
        # (streak_ab > 3) and (streak_ab < 7):
        heuristic += 1

    if streak_cd < 4:
        # wenn mit dem move in einer Spalte keine 4 erreicht werden können
        heuristic_c = 0
        heuristic_d = 0
    elif streak_cd == 7:
        heuristic += 2
    else:
        # (streak_cd > 3) and (streak_cd < 7):
        heuristic += 1

    if streak_ef < 4:
        # wenn mit dem move in einer rechts-Diagonalen keine 4 erreicht werden können
        heuristic_e = 0
        heuristic_f = 0
    elif streak_ef == 7:
        heuristic += 2
    else:
        # (streak_ef > 3) and (streak_ef < 7):
        heuristic += 1

    if streak_gh < 4:
        # wenn mit dem move in einer links-Diagonalen keine 4 erreicht werden können
        heuristic_g = 0
        heuristic_h = 0
    elif streak_gh == 7:
        heuristic += 2
    else:
        # (streak_gh > 3) and (streak_gh < 7):
        heuristic += 1

    heuristic += heuristic_a + heuristic_b + heuristic_c + heuristic_d + heuristic_e + heuristic_f + heuristic_g + heuristic_h

    return heuristic