Пример #1
0
    def predetermined_random(board_state: BoardState, params: dict = None):
        # get the pre-determined set of random moves if it hasn't already been loaded
        if len(AutoPlayMethods.directions) == 0:
            rnd_filename = "random.dat"
            rnd_file = open(rnd_filename, "r")
            AutoPlayMethods.directions = [
                Direction[str.rstrip(line)]
                for idx, line in enumerate(rnd_file.readlines())
            ]

        #run the random simulation
        i = 0
        while not board_state.Lost:
            board_state.move(AutoPlayMethods.directions[i])
            i += 1
Пример #2
0
    def branch(board_state: BoardState, params: dict = None):
        layers: int = params.get("LAYERS")
        if not layers:
            layers = 2
        if layers < 1: return

        move_num = 1
        root: Move = Move.as_root_node(board_state)
        while not board_state.Lost:
            print(f"Move: {move_num}")
            print(str(board_state.field))
            move_num += 1
            current_layer = []
            next_layer = [root]
            for _ in range(layers):
                current_layer = next_layer
                next_layer = []
                for move in current_layer:
                    next_layer.extend(move.generate_children())
                if not any(next_layer):
                    next_layer = current_layer
                    break

            # when we're done, the last layer is the final set of children
            weights = {d: 0 for d in Direction}
            for d in Direction:
                scores = [
                    move.get_reward() for move in filter(
                        lambda mv: mv.reward_direction() == d, next_layer)
                ]
                if len(scores) > 0:
                    weights[d] = mean(scores)

            top_score = max(weights.values())
            # get options with weights equivalent to top scorer;
            # if there are more than one, pick a random one
            top_scorers = [
                key for key, value in weights.items() if value == top_score
            ]
            rec_dir = top_scorers[0] if len(
                top_scorers) == 1 else random.choice(top_scorers)

            board_state.move(rec_dir, weights)

            # find the move that represents what actually happened and make it the new root
            root = next(move for move in root.children
                        if move.end_state == board_state.field)
            root.parent = None
Пример #3
0
    def pseudo_ML(board_state: BoardState, params: dict = None):
        pml = Pseudo_ML() if params == None else Pseudo_ML(params)
        while not board_state.Lost:
            weights = pml.get_direction_weights(board_state)
            direction_rec = pml.get_direction_recommendation(weights)
            this_dir = direction_rec[0]

            # get options with weights equivalent to top scorer;
            # if there are more than one, pick a random one
            top_scorers = [
                key for key, value in weights.items()
                if value == direction_rec[1]
            ]
            if (len(top_scorers) > 1):
                this_dir = random.choice(top_scorers)

            board_state.move(this_dir, weights.copy())
Пример #4
0
    def get_direction_weights(self, board_state: BoardState):
        statesAfterMove = []
        direction_scores = {d: 0 for d in Direction}
        squares_array = flatten(board_state.field)
        # get a list of the board state after making all legal moves
        for direction in Direction:
            dir_move = board_state.move(direction, {}, False, False)
            if dir_move.changed_board(
            ):  # ignore moves that do not change the board
                possible_states = self.enumerate_possible_outcomes(
                    squares_array, board_state.FOUR_CHANCE,
                    board_state.BOARD_SIZE)
                for state, prob in possible_states:
                    score = self.score_board_state2(board_state)
                    direction_scores[direction] += prob * score
                    statesAfterMove.append([direction, state, prob, score])

        return {key: val for key, val in direction_scores.items() if val != 0}
Пример #5
0
def run_method(x, method_to_call, log_path: str = '', params: dict = {}):
    new_board = BoardState()
    start_time = time.time()
    method_to_call(new_board, params)
    end_time = time.time()

    print(f'End: {x}')

    # save the detailed log, if appropriate
    if log_path:
        #create a log file
        log_file = open(log_path, 'w')
        log_file.writelines(
            [entry.as_log_entry() + '\n' for entry in new_board.move_history])
        log_file.close()

    # return the results
    return [
        x,
        len(new_board.move_history),
        new_board.field.get_score(), end_time - start_time, *params.values()
    ]
Пример #6
0
    def score_board_state2(self, board: BoardState):
        scores = []
        base_score = board.get_score() * (self.BASE_SCORE_MULTIPLIER / 10)
        scores.append(base_score)

        #add scores that don't change based on direction
        items = flatten(board.field)
        bonus = sum([
            item * self.POINTS_PER_FREE_SQUARE for item in items if item == 0
        ])
        bonus += max(items) * self.HIGHEST_TILE_MULTIPLER
        scores.append(bonus)

        # get the corner into the 0,0 spot
        corner = self.get_corner_by_tiles(board)
        working_board = array_2d_copy(board.field)
        if corner[0] > 0:
            working_board = invert(working_board)
        if corner[1] > 0:
            working_board = flip(working_board)

        # get the order score
        order_score = self.get_board_order_score(working_board)
        scores.append(order_score)

        # get the high value on the board (closest to the corner)
        (h_x, h_y, high_val) = self.get_high_val(working_board)
        high_score = high_val * self.HIGHEST_TILE_MULTIPLER
        scores.append(high_score)

        # get the count of tiles between the high_val and the corner
        bad_tile_count = len([(x,y) for x in range(h_x + 1) \
                                    for y in range(h_y + 1) \
                                    if (x > 0 or y > 0) and working_board[x][y] > 0])
        bad_tile_score = bad_tile_count * self.TILE_BETWEEN_HIGH_AND_CORNER_MULT * -1
        scores.append(bad_tile_score)

        return sum(scores)
Пример #7
0
from game.BoardDisplay import BoardDisplay
from game.BoardState import BoardState

board = BoardDisplay(BoardState())
Пример #8
0
 def reset(self):
     self.board.reset_board()
     self.board = BoardState()
     self.title(TITLE)
Пример #9
0
from autoplay.BoardReplay import BoardReplay
from game.BoardState import BoardState
from game.Move import Move
import numpy as np

# put in a filename from the log folder
file_to_import = 'logs/branch_20181005_140715.392990.log'  # 'logs/random_20180906_095102.239753.log'

log_file = open(file_to_import, "r")
moves = list(map(Move.from_log_entry, log_file.readlines()))
log_file.close()
board = BoardState()
board.import_from_log(moves)
replay = BoardReplay(board)