コード例 #1
0
    def heuristic(node: Grid):
        score = 0
        num_empty_cells = len(node.getAvailableCells())

        for i in range(node.size):
            for j in range(node.size):
                val = node.getCellValue((i, j))
                score += val * 10 if val else (
                    1000 / num_empty_cells
                )  # reward empty spaces more if they are scarce

                val_up = node.getCellValue((i - 1, j))
                val_dn = node.getCellValue((i + 1, j))
                val_lt = node.getCellValue((i, j - 1))
                val_rt = node.getCellValue((i, j + 1))
                if val_up is not None and \
                   val_dn is not None and \
                   val != 0:
                    if not (val_up <= val <= val_dn
                            or val_up >= val >= val_dn):
                        score -= 75 * (abs(val_up - val) + abs(val_dn - val))
                if val_lt is not None and \
                   val_rt is not None and \
                   val != 0:
                    if not (val_lt <= val <= val_rt
                            or val_lt >= val >= val_rt):
                        score -= 75 * (abs(val_lt - val) + abs(val_rt - val))

                if j == 0:
                    row = node.map[i]
                    monotonic_row = all(x <= y for x, y in zip(row, row[1:]))
                    monotonic_row = monotonic_row or all(
                        x >= y for x, y in zip(row, row[1:]))
                    if monotonic_row:
                        score += 200 * sum(row)  # big bonus

                if i == 0:
                    col = [node.map[pos][j] for pos in range(node.size)]
                    monotonic_col = all(x <= y for x, y in zip(col, col[1:]))
                    monotonic_col = monotonic_col or all(
                        x >= y for x, y in zip(col, col[1:]))
                    if monotonic_col:
                        score += 200 * sum(col)  # big bonus

                val_order = PlayerAI.get_value_order(val)
                if val_order > 0:
                    val_up_order = PlayerAI.get_value_order(val_up)
                    val_dn_order = PlayerAI.get_value_order(val_dn)
                    val_lt_order = PlayerAI.get_value_order(val_lt)
                    val_rt_order = PlayerAI.get_value_order(val_rt)
                    if val_up_order > 0:
                        score -= abs(val_up_order - val_order) * 25
                    if val_dn_order > 0:
                        score -= abs(val_dn_order - val_order) * 25
                    if val_lt_order > 0:
                        score -= abs(val_lt_order - val_order) * 25
                    if val_rt_order > 0:
                        score -= abs(val_rt_order - val_order) * 25

        return score
コード例 #2
0
    def is_state_terminal(self, grid_to_check: Grid, min_max: str):
        if self.is_grid_depth_out_of_bound(grid_to_check.current_depth):
            return True

        if min_max == 'min':
            return len(grid_to_check.getAvailableCells()
                       ) == 0  # or grid.getMaxTile() > 100
        else:
            return not grid_to_check.canMove()  # or grid.getMaxTile() > 100
コード例 #3
0
 def set_grid_cell_numbers(self, grid: Grid):
     self.number_grid_cells = grid.size**2
     self.number_grid_cells_zero = len(grid.getAvailableCells())
     if self.number_grid_cells_zero == 0:
         self.number_grid_cells_zero = 1  # to avoid problems
     self.level_number_branches.update({
         '0': 1
     })  # default value for 0 - which is only used for this calculation
     for k in range(1, 100):
         if k % 2 == 1:  # on that level the computer's values are added to each branch
             self.level_number_branches.update({
                 str(k):
                 self.level_number_branches.get(str(k - 1)) *
                 self.number_grid_cells_zero * 2
             })
         else:  # on that level the movements are added to each branch
             self.level_number_branches.update(
                 {str(k): self.level_number_branches.get(str(k - 1)) * 4})
コード例 #4
0
    def get_grid_value(grid: Grid):
        number_cells = grid.size**2
        sum_tiles = 0
        neigbors_equal = 0
        for x in range(grid.size):
            for y in range(grid.size):
                sum_tiles += grid.map[x][y]
                if (x < grid.size - 1) and grid.map[x][y] == grid.map[x +
                                                                      1][y]:
                    neigbors_equal += 1
                if (y < grid.size - 1) and grid.map[x][y] == grid.map[x][y +
                                                                         1]:
                    neigbors_equal += 1

        average = sum_tiles / number_cells
        number_zero_cells = len(grid.getAvailableCells())

        return 2 * number_zero_cells / number_cells + average / 2048 + neigbors_equal / number_cells
コード例 #5
0
    def get_children(self, grid: Grid, min_or_max: str):
        grid_children = []

        if min_or_max == 'max':
            moves = grid.getAvailableMoves()
            for move in moves:
                child_grid = self.get_grid_for_move(grid, move)
                child_grid.current_depth = grid.current_depth + 1
                grid_children.append(child_grid)
        else:
            cells = grid.getAvailableCells()
            values = [2, 4]
            for cell in cells:
                for value in values:
                    grid_copy = grid.clone()
                    grid_copy.setCellValue(cell, value)
                    grid_copy.current_depth = grid.current_depth + 1
                    grid_children.append(grid_copy)
        return grid_children
コード例 #6
0
    def minimizing(self, alpha, beta, node: Grid, depth):
        if depth == 0:
            return self.heuristic(node)

        cells = node.getAvailableCells()
        if not cells:
            return self.get_terminal_node_value(node)

        value = math.inf
        for cell in cells:
            for i in range(2, 5, 2):
                child = node.clone()
                child.insertTile(cell, i)
                value = min(value,
                            self.maximizing(alpha, beta, child, depth - 1)[0])
                beta = min(beta, value)
                if alpha >= beta:
                    break
        return value
コード例 #7
0
ファイル: Trainer_DQN.py プロジェクト: tomseidel/2018_Agent
class GameManager:
    def __init__(self, size = 4):
        self.grid = Grid(size)
        self.possibleNewTiles = [2, 4]
        self.probability = defaultProbability
        self.initTiles  = defaultInitialTiles
        self.computerAI = None
        self.playerAI   = None
        self.displayer  = None
        self.over       = False

    def setComputerAI(self, computerAI):
        self.computerAI = computerAI

    def setPlayerAI(self, playerAI):
        self.playerAI = playerAI

    def setDisplayer(self, displayer):
        self.displayer = displayer

    def updateAlarm(self, currTime):
        if currTime - self.prevTime > timeLimit + allowance:
            self.over = True
        else:
            while time.clock() - self.prevTime < timeLimit + allowance:
                pass

            self.prevTime = time.clock()

    def gridAverage(self, grid):
        cells = []

        for x in range(4):
            for y in range(4):
                if grid.map[x][y] > 0:
                    cells.append((x,y))
        sum = 0
        for c in cells:
            sum += grid.map[c[0]][c[1]]
        return sum / len(cells)


    def play_one(self, model, tmodel, eps, gamma, copy_period):
        for i in range(self.initTiles):
            self.insertRandonTile()

        grid_array = np.array(self.grid.map).ravel()
        #observation = grid_array / np.linalg.norm(grid_array)
        observation = grid_array / 2048
        
        done = False
        totalreward = 0
        iters = 0
  
        ##self.displayer.display(self.grid)

        # Player AI Goes First
        turn = PLAYER_TURN
        maxTile = 2

        self.prevTime = time.clock()

        #while not self.isGameOver() and not self.over:
        while not self.isGameOver():
            # Copy to Ensure AI Cannot Change the Real Grid to Cheat
            gridCopy = self.grid.clone()

            move = None

            if turn == PLAYER_TURN:
                ##print("Player's Turn:", end="")
                #move = self.playerAI.getMove(gridCopy)
                move = model.sample_action(observation, eps, gridCopy)
                gridAvg = self.gridAverage(gridCopy)
                #lastMax = gridCopy.getMaxTile()
                prev_observation = observation
                last_maxTile = maxTile
                
                ##print(actionDic[move])

                # Validate Move
                if move != None and move >= 0 and move < 4:
                    if self.grid.canMove([move]):
                        self.grid.move(move)
                        maxTile = self.grid.getMaxTile()
                        
                        #observation, reward, done, info = env.step(action)
                        grid_array = np.array(self.grid.map).ravel()
                        #observation = grid_array / np.linalg.norm(grid_array)
                        observation = grid_array / maxTile
        
                        gridNewAvg = self.gridAverage(self.grid)
                        #newMax = self.grid.getMaxTile()
                        reward = gridNewAvg - gridAvg
                        
                        # Update maxTile
                        #reward = maxTile - last_maxTile
                        #reward = 1
                        
                        done = self.isGameOver()
                        if done:
                            reward = -100

                        # update the model
                        model.add_experience(prev_observation, move, reward, observation, done)
                        model.train(tmodel)
                        
                        if iters % copy_period == 0:
                            tmodel.copy_from(model)
                        
                        if reward == 1:
                            totalreward += reward
                        iters += 1

                    else:
                        print("Invalid PlayerAI Move")
                        self.over = True
                else:
                    print("Invalid PlayerAI Move - 1")
                    self.over = True
            else:
                ##print("Computer's turn:")
                move = self.computerAI.getMove(gridCopy)

                # Validate Move
                if move and self.grid.canInsert(move):
                    self.grid.setCellValue(move, self.getNewTileValue())
                else:
                    print("Invalid Computer AI Move")
                    self.over = True

            #if not self.over:
                #self.displayer.display(self.grid)

            # Exceeding the Time Allotted for Any Turn Terminates the Game
            # self.updateAlarm(time.clock())

            turn = 1 - turn
        self.maxTile = self.grid.getMaxTile()
        print(maxTile)
        return maxTile

    def isGameOver(self):
        return not self.grid.canMove()

    def getNewTileValue(self):
        if randint(0,99) < 100 * self.probability:
            return self.possibleNewTiles[0]
        else:
            return self.possibleNewTiles[1];

    def insertRandonTile(self):
        tileValue = self.getNewTileValue()
        cells = self.grid.getAvailableCells()
        cell = cells[randint(0, len(cells) - 1)]
        self.grid.setCellValue(cell, tileValue)
コード例 #8
0
class GameManager:
    def __init__(self, size=4):
        self.grid = Grid(size)
        self.possibleNewTiles = [2, 4]
        self.probability = defaultProbability
        self.initTiles = defaultInitialTiles
        self.computerAI = None
        self.playerAI = None
        self.displayer = None
        self.over = False

    def setComputerAI(self, computerAI):
        self.computerAI = computerAI

    def setPlayerAI(self, playerAI):
        self.playerAI = playerAI

    def setDisplayer(self, displayer):
        self.displayer = displayer

    def updateAlarm(self, currTime):
        if currTime - self.prevTime > timeLimit + allowance:
            #self.over = True
            print("Time over!!")
            print(currTime - self.prevTime)
        else:
            while time.clock() - self.prevTime < timeLimit + allowance:
                pass

            self.prevTime = time.clock()

    def start(self):
        for i in range(self.initTiles):
            self.insertRandonTile()

        self.displayer.display(self.grid)

        # Player AI Goes First
        turn = PLAYER_TURN
        maxTile = 0

        self.prevTime = time.clock()

        while not self.isGameOver() and not self.over:
            # Copy to Ensure AI Cannot Change the Real Grid to Cheat
            gridCopy = self.grid.clone()

            move = None

            if turn == PLAYER_TURN:
                print("Player's Turn:", end="")
                move = self.playerAI.getMove(gridCopy)
                print(actionDic[move])

                # Validate Move
                if move != None and move >= 0 and move < 4:
                    if self.grid.canMove([move]):
                        self.grid.move(move)

                        # Update maxTile
                        maxTile = self.grid.getMaxTile()
                    else:
                        print("Invalid PlayerAI Move")
                        self.over = True
                else:
                    print("Invalid PlayerAI Move - 1")
                    self.over = True
            else:
                print("Computer's turn:")
                move = self.computerAI.getMove(gridCopy)

                # Validate Move
                if move and self.grid.canInsert(move):
                    self.grid.setCellValue(move, self.getNewTileValue())
                else:
                    print("Invalid Computer AI Move")
                    self.over = True

            if not self.over:
                self.displayer.display(self.grid)

            # Exceeding the Time Allotted for Any Turn Terminates the Game
            self.updateAlarm(time.clock())

            turn = 1 - turn
        print(maxTile)

    def isGameOver(self):
        return not self.grid.canMove()

    def getNewTileValue(self):
        if randint(0, 99) < 100 * self.probability:
            return self.possibleNewTiles[0]
        else:
            return self.possibleNewTiles[1]

    def insertRandonTile(self):
        tileValue = self.getNewTileValue()
        cells = self.grid.getAvailableCells()
        cell = cells[randint(0, len(cells) - 1)]
        self.grid.setCellValue(cell, tileValue)
コード例 #9
0
class GameManager:
    def __init__(self, size=4, playerAI=None, computerAI=None, displayer=None):
        self.grid = Grid(size)
        self.possibleNewTiles = [2, 4]
        self.probability = defaultProbability
        self.initTiles = defaultInitialTiles
        self.over = False

        # Initialize the AI players
        self.computerAI = computerAI or ComputerAI()
        self.playerAI = playerAI or PlayerAI()
        self.displayer = displayer or Displayer()
        self.timedOut = False

    def updateAlarm(self) -> None:
        """ Checks if move exceeded the time limit and updates the alarm """
        if time.process_time() - self.prevTime > maxTime:
            print("timed out")
            self.over = True
            self.timedOut = True

        self.prevTime = time.process_time()

    def getNewTileValue(self) -> int:
        """ Returns 2 with probability 0.95 and 4 with 0.05 """
        return self.possibleNewTiles[random.random() > self.probability]

    def insertRandomTiles(self, numTiles: int):
        """ Insert numTiles number of random tiles. For initialization """
        for i in range(numTiles):
            tileValue = self.getNewTileValue()
            cells = self.grid.getAvailableCells()
            cell = random.choice(cells) if cells else None
            self.grid.setCellValue(cell, tileValue)

    def start(self) -> int:
        """ Main method that handles running the game of 2048 """

        # Initialize the game
        self.insertRandomTiles(self.initTiles)
        self.displayer.display(self.grid)
        turn = PLAYER_TURN  # Player AI Goes First
        self.prevTime = time.process_time()

        while self.grid.canMove() and not self.over:
            # Copy to Ensure AI Cannot Change the Real Grid to Cheat
            gridCopy = self.grid.clone()
            #time.sleep(.1)
            move = None

            if turn == PLAYER_TURN:
                print("Player's Turn: ", end="")
                move = self.playerAI.getMove(gridCopy)
                print(actionDic[move])

                # If move is valid, attempt to move the grid
                if move != None and 0 <= move < 4:
                    if self.grid.canMove([move]):
                        self.grid.move(move)

                    else:
                        print("Invalid PlayerAI Move - Cannot move")
                        self.over = True
                else:
                    print("Invalid PlayerAI Move - Invalid input")
                    self.over = True
            else:
                print("Computer's turn: ")
                move = self.computerAI.getMove(gridCopy)

                # Validate Move
                if move and self.grid.canInsert(move):
                    self.grid.setCellValue(move, self.getNewTileValue())
                else:
                    print("Invalid Computer AI Move")
                    self.over = True

            # Comment out during heuristing optimizations to increase runtimes.
            # Printing slows down computation time.
            self.displayer.display(self.grid)

            # Exceeding the Time Allotted for Any Turn Terminates the Game
            self.updateAlarm()
            turn = 1 - turn

        return self.grid.getMaxTile()

    def start_no_disp(self) -> int:
        """ Main method that handles running the game of 2048 """

        # Initialize the game
        self.insertRandomTiles(self.initTiles)
        #self.displayer.display(self.grid)
        turn = PLAYER_TURN  # Player AI Goes First
        self.prevTime = time.process_time()

        while self.grid.canMove() and not self.over:
            # Copy to Ensure AI Cannot Change the Real Grid to Cheat
            gridCopy = self.grid.clone()
            #time.sleep(.1)
            move = None

            if turn == PLAYER_TURN:
                #print("Player's Turn: ", end="")
                move = self.playerAI.getMove(gridCopy)
                #print(actionDic[move])

                # If move is valid, attempt to move the grid
                if move != None and 0 <= move < 4:
                    if self.grid.canMove([move]):
                        self.grid.move(move)

                    else:
                        #print("Invalid PlayerAI Move - Cannot move")
                        self.over = True
                else:
                    #print("Invalid PlayerAI Move - Invalid input")
                    self.over = True
            else:
                #print("Computer's turn: ")
                move = self.computerAI.getMove(gridCopy)

                # Validate Move
                if move and self.grid.canInsert(move):
                    self.grid.setCellValue(move, self.getNewTileValue())
                else:
                    #print("Invalid Computer AI Move")
                    self.over = True

            # Comment out during heuristing optimizations to increase runtimes.
            # Printing slows down computation time.
            #self.displayer.display(self.grid)

            # Exceeding the Time Allotted for Any Turn Terminates the Game
            self.updateAlarm()
            turn = 1 - turn

        return self.grid.getMaxTile()

    def start_training(self) -> int:
        """ Main method that handles running the game of 2048 """

        # Initialize the game
        self.insertRandomTiles(self.initTiles)
        #self.displayer.display(self.grid)
        turn = PLAYER_TURN  # Player AI Goes First
        self.prevTime = time.process_time()

        while self.grid.canMove() and not self.over:
            # Copy to Ensure AI Cannot Change the Real Grid to Cheat
            gridCopy = self.grid.clone()
            #time.sleep(.1)
            move = None

            if turn == PLAYER_TURN:
                #print("Player's Turn: ", end="")
                move = self.playerAI.getMoveLearning(gridCopy)
                #print(actionDic[move])

                # If move is valid, attempt to move the grid
                if move != None and 0 <= move < 4:
                    if self.grid.canMove([move]):
                        self.grid.move(move)

                    else:
                        #print("Invalid PlayerAI Move - Cannot move")
                        self.over = True
                else:
                    #print("Invalid PlayerAI Move - Invalid input")
                    self.over = True
            else:
                #print("Computer's turn: ")
                move = self.computerAI.getMove(gridCopy)

                # Validate Move
                if move and self.grid.canInsert(move):
                    self.grid.setCellValue(move, self.getNewTileValue())
                else:
                    #print("Invalid Computer AI Move")
                    self.over = True

            # Comment out during heuristing optimizations to increase runtimes.
            # Printing slows down computation time.
            #self.displayer.display(self.grid)

            # Exceeding the Time Allotted for Any Turn Terminates the Game
            self.updateAlarm()
            turn = 1 - turn

        return self.grid.getMaxTile()

    def start_reinforce(self) -> int:
        """ Main method that handles running the game of 2048 """

        # Initialize the game
        self.insertRandomTiles(self.initTiles)
        #self.displayer.display(self.grid)
        turn = PLAYER_TURN  # Player AI Goes First
        self.prevTime = time.process_time()

        while self.grid.canMove() and not self.over:
            # Copy to Ensure AI Cannot Change the Real Grid to Cheat
            gridCopy = self.grid.clone()
            #time.sleep(.1)
            move = None

            if turn == PLAYER_TURN:
                #print("Player's Turn: ", end="")
                move = self.playerAI.getMove(gridCopy)
                #print(actionDic[move])

                # If move is valid, attempt to move the grid
                if move != None and 0 <= move < 4:
                    if self.grid.canMove([move]):
                        self.grid.move(move)

                    else:
                        #print("Invalid PlayerAI Move - Cannot move")
                        self.over = True
                else:
                    #print("Invalid PlayerAI Move - Invalid input")
                    self.over = True
            else:
                #print("Computer's turn: ")
                move = self.computerAI.getMove(gridCopy)

                # Validate Move
                if move and self.grid.canInsert(move):
                    self.grid.setCellValue(move, self.getNewTileValue())
                else:
                    #print("Invalid Computer AI Move")
                    self.over = True

            # Comment out during heuristing optimizations to increase runtimes.
            # Printing slows down computation time.
            #self.displayer.display(self.grid)

            # Exceeding the Time Allotted for Any Turn Terminates the Game
            self.updateAlarm()
            turn = 1 - turn

        return self.grid.getMaxTile()
コード例 #10
0
class GameManager:
    def __init__(self, size=4):
        self.grid = Grid(size)
        self.possibleNewTiles = [2, 4]
        self.probability = defaultProbability
        self.initTiles = defaultInitialTiles
        self.computerAI = None
        self.playerAI = None
        self.displayer = None
        self.over = False
        self.max_time_for_get_move = 0
        self.next_move_counter = 0
        self.MAX_NEXT_MOVE_COUNTER = 10000

    def setComputerAI(self, computerAI):
        self.computerAI = computerAI

    def setPlayerAI(self, playerAI):
        self.playerAI = playerAI

    def setDisplayer(self, displayer):
        self.displayer = displayer

    def updateAlarm(self, currTime):
        if currTime - self.prevTime > timeLimit + allowance:
            self.over = False
        else:
            while time.clock() - self.prevTime < timeLimit + allowance:
                pass

            self.prevTime = time.clock()

    def start(self):
        for i in range(self.initTiles):
            self.insertRandonTile()

        # self.grid.map = [[4, 128, 4, 2], [64, 4, 32, 4], [8, 64, 8, 16], [16, 4, 2, 2]]
        # self.grid.map = [[2, 32, 2, 4], [4, 256, 32, 8], [16, 64, 16, 0], [4, 16, 8, 4]]
        # self.grid.map = [[2, 32, 2, 4], [4, 256, 32, 8], [2, 32, 64, 16], [4, 0, 8, 4]]  # with utility_value (min) = -inf for move 0
        # self.grid.map = [[2, 32, 2, 4], [4, 256, 32, 8], [2, 32, 64, 16], [2, 4, 8, 4]]  # for move 0 => -inf - WHY

        self.displayer.display(self.grid)

        # Player AI Goes First
        turn = PLAYER_TURN
        maxTile = 0

        self.prevTime = time.clock()

        while not self.isGameOver() and not self.over:
            # Copy to Ensure AI Cannot Change the Real Grid to Cheat
            gridCopy = self.grid.clone()

            move = None

            if turn == PLAYER_TURN:
                print("Player's Turn:", end="")
                move = self.playerAI.getMove(gridCopy)

                if self.playerAI.run_time > self.max_time_for_get_move:
                    self.max_time_for_get_move = self.playerAI.run_time
                print(actionDic[move])

                # Validate Move
                if move != None and move >= 0 and move < 4:
                    if self.grid.canMove([move]):
                        self.grid.move(move)

                        # Update maxTile
                        maxTile = self.grid.getMaxTile()
                    else:
                        print("Invalid PlayerAI Move")
                        self.over = True
                else:
                    print("Invalid PlayerAI Move - 1")
                    self.over = True

                self.next_move_counter += 1
                if self.next_move_counter > self.MAX_NEXT_MOVE_COUNTER:
                    self.over = True
                    break
            else:
                print("Computer's turn:")
                move = self.computerAI.getMove(gridCopy)

                # Validate Move
                if move and self.grid.canInsert(move):
                    self.grid.setCellValue(move, self.getNewTileValue())
                else:
                    print("Invalid Computer AI Move")
                    self.over = True

            if not self.over:
                self.displayer.display(self.grid)

            # Exceeding the Time Allotted for Any Turn Terminates the Game
            self.updateAlarm(time.clock())

            turn = 1 - turn

        print(
            'maxTile = {0} - max_time_for_get_move = {1:5.4f} - number_players_moves = {2}'
            .format(maxTile, self.max_time_for_get_move,
                    self.next_move_counter))

        self.plot_move_times()

    def plot_move_times(self):
        x = np.array([i for i in range(len(self.playerAI.run_time_list))])
        y = np.array(self.playerAI.run_time_list)
        plt.plot(x, y)
        plt.show()
        # plot with various axes scales
        plt.figure(1)
        # linear
        plt.subplot(221)
        plt.plot(x, y)
        plt.yscale('linear')
        plt.title('linear')
        plt.grid(True)

    def isGameOver(self):
        return not self.grid.canMove()

    def getNewTileValue(self):
        if randint(0, 99) < 100 * self.probability:
            return self.possibleNewTiles[0]
        else:
            return self.possibleNewTiles[1]

    def insertRandonTile(self):
        tileValue = self.getNewTileValue()
        cells = self.grid.getAvailableCells()
        cell = cells[randint(0, len(cells) - 1)]
        self.grid.setCellValue(cell, tileValue)
コード例 #11
0
ファイル: HW2_test.py プロジェクト: MattlearnPython/AI_2048
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Jun 11 16:36:48 2018

@author: jinzhao
"""

from Grid_3 import Grid

g = Grid()
g.map[0][0] = 2
g.map[1][0] = 2
g.map[3][0] = 4

empty = g.getAvailableCells()
print(empty)


def test_fun():
    return 1, 2


b = test_fun()[1]

print(b)


class test_class():
    def __init__(self):
        self.val = 100
コード例 #12
0
ファイル: Utility_3.py プロジェクト: kk-mbugua/AISummer2018
                neighbours = self.get_neighbours(pos)
                for n in neighbours:
                    if pos_value == grid.getCellValue(n):
                        merges += 1
        return merges

    def grid_eval(self, grid):
        gradients = [[[3, 2, 1, 0], [2, 1, 0, -1], [1, 0, -1, -2],
                      [0, -1, -2, -3]],
                     [[0, 1, 2, 3], [-1, 0, 1, 2], [-2, -1, 0, 1],
                      [-3, -2, -1, -0]],
                     [[0, -1, -2, -3], [1, 0, -1, -2], [2, 1, 0, -1],
                      [3, 2, 1, 0]],
                     [[-3, -2, -1, 0], [-2, -1, 0, 1], [-1, 0, 1, 2],
                      [0, 1, 2, 3]]]

        values = [0, 0, 0, 0]

        for i in range(4):
            for x in range(4):
                for y in range(4):
                    values[i] += gradients[i][x][y] * grid.map[x][y]

        return max(values)


if __name__ == "__main__":
    grid = Grid()
    a = grid.getAvailableCells()
    print(len(a))
コード例 #13
0
from random import randint
from BaseAI_3 import BaseAI
from Grid_3 import Grid
from PlayerAI_3 import PlayerAI

grid = Grid()
grid.map = [[4, 64, 8, 4], [32, 8, 64, 8], [256, 512, 32, 4], [4, 8, 4, 2]]

moves = [1, 2, 3, 4]
print(moves)
moves[2] = 7
print(moves)

print(len(grid.getAvailableCells()))
print(grid.map)
print(PlayerAI.is_state_terminal(grid, 'min'))
コード例 #14
0
class gym_2048():
    def __init__(self, size=4):
        self.size = size
        self.grid = None
        self.possible_new_tiles = [2, 4]
        self.probability = default_probability
        self.init_tiles = default_initial_tiles
        self.over = False
        self.action_space = 4
        self.reward = 0
        self.max_tile = 0
        self.score = 0
        pass

    def make(self):
        self.grid = Grid(self.size)
        for i in range(self.init_tiles):
            self.insert_random_tile()

    def get_state(self):
        return self.grid.map

    def reset(self):
        self.make()
        self.score = 0
        self.max_tile = 0
        self.reward = 0

    def get_new_tile_value(self):
        if randint(0, 99) < 100 * self.probability:
            return self.possible_new_tiles[0]
        else:
            return self.possible_new_tiles[1]

    def insert_random_tile(self):
        tile_value = self.get_new_tile_value()
        cells = self.grid.getAvailableCells()
        if len(cells) > 0:
            cell = cells[randint(0, len(cells) - 1)]
            self.grid.setCellValue(cell, tile_value)

    def close(self):
        self.grid = None

    def is_done(self):
        return not self.grid.canMove()

    def render(self, mode='human'):
        grid = self.grid
        if mode == "human":
            for i in range(grid.size):
                for j in range(grid.size):
                    print("%6d  " % grid.map[i][j], end="")
                print("")
            print("")
        # return self.get_state()

    def step(self, action):
        move = action
        # print(action_dict[move])
        # Validate Move
        if move is not None and 0 <= move < 4:
            moved, merge_points = self.grid.move(move)
            self.score = merge_points
            # Update maxTile
            self.max_tile = self.grid.getMaxTile()
            if moved:
                self.insert_random_tile()
            self.calculate_reward()
        else:
            print("Invalid PlayerAI Move - 1")
            exit(0)
        return self.get_state(), self.reward, self.is_done(), []

    def calculate_reward(self):
        # weighted_sum = self.calculate_weighted_sum()
        # penalty = self.calculate_penalty()
        # self.reward = weighted_sum - penalty
        self.reward = self.score

    def calculate_weighted_sum(self):
        score = 0
        for x in range(4):
            for y in range(4):
                score += (priority[x][y] * self.grid.map[x][y] *
                          self.grid.map[x][y])
        return score

    def calculate_penalty(self):
        # Calculate clustering penalty.
        # We want two same valued tiles to be present next to each other
        # so that it is easier to merge.
        # This penalty becomes large when high valued tiles are scattered across
        # the grid, indicating that the grid is bad.

        def within_bounds(position):
            return 0 <= position['x'] < 4 and 0 <= position['y'] < 4

        penalty = 0

        # Direction vectors for up, down, left and right
        directions = ([-1, 0], [1, 0], [0, -1], [0, 1])

        for x in range(4):
            for y in range(4):
                # if grid.map[x][y] != 0:
                for i in range(4):
                    pos = {
                        "x": x + directions[i][0],
                        "y": y + directions[i][1]
                    }
                    if within_bounds(pos):
                        neighbour = self.grid.map[pos['x']][pos['y']]
                        # if neighbour!=0:
                        penalty += math.fabs(neighbour - self.grid.map[x][y])
        return penalty
コード例 #15
0
class GameManager:
    def __init__(self, size=4):
        self.grid = Grid(size)
        self.possibleNewTiles = [2, 4]
        self.probability = defaultProbability
        self.initTiles = defaultInitialTiles
        self.computerAI = None
        self.playerAI = None
        self.displayer = None
        self.over = False
        # Load the DNN model
        self.model_NN = load_model("all_2048_8000games.h5")
        # self.result_file = open("resultRandom.txt", "a")

    def setComputerAI(self, computerAI):
        self.computerAI = computerAI

    def setPlayerAI(self, playerAI):
        self.playerAI = playerAI

    def setDisplayer(self, displayer):
        self.displayer = displayer

    def updateAlarm(self, currTime):
        if currTime - self.prevTime > timeLimit + allowance:
            self.over = True
        else:
            while time.clock() - self.prevTime < timeLimit + allowance:
                pass

            self.prevTime = time.clock()

    def start(self):
        for i in range(self.initTiles):
            self.insertRandonTile()

        self.displayer.display(self.grid)

        # Player AI Goes First
        turn = PLAYER_TURN
        maxTile = 0

        self.prevTime = time.clock()

        while not self.isGameOver() and not self.over:
            # Copy to Ensure AI Cannot Change the Real Grid to Cheat
            gridCopy = self.grid.clone()

            move = None

            if turn == PLAYER_TURN:
                print("Player's Turn:", end="")

                # move = self.playerAI.getMove(gridCopy)

                # Using NN to make move instead
                list_proba = self.model_NN.predict(
                    self.generateCurrentBoard1D(self.grid.map))[0].tolist()
                move = list_proba.index(max(list_proba))

                # availableMoves = self.grid.getAvailableMoves()
                # move = availableMoves[randint(0, len(availableMoves)-1)]
                while not self.grid.canMove([move]):
                    # print(list_proba)
                    list_proba[move] = -1
                    move = list_proba.index(max(list_proba))
                    # randint(0,3)
                print(actionDic[move])

                # Validate Move
                if move != None and move >= 0 and move < 4:
                    if self.grid.canMove([move]):
                        """TODO: This line to print out the current grid and how to move for the current state"""
                        current_board_and_move = self.generateCurrentBoardAndMoveToText(
                            self.grid.map, move)
                        print(current_board_and_move)
                        self.grid.move(move)

                        # Update maxTile
                        maxTile = self.grid.getMaxTile()
                    else:
                        print("Invalid PlayerAI Move")
                        self.over = True
                else:
                    print("Invalid PlayerAI Move - 1")
                    self.over = True
            else:
                print("Computer's turn:")
                move = self.computerAI.getMove(gridCopy)

                # Validate Move
                if move and self.grid.canInsert(move):
                    self.grid.setCellValue(move, self.getNewTileValue())
                else:
                    print("Invalid Computer AI Move")
                    self.over = True
            """
            Comment this out if do not want to have the display
            """
            if not self.over:
                self.displayer.display(self.grid)

            # Exceeding the Time Allotted for Any Turn Terminates the Game
            self.updateAlarm(time.clock())

            turn = 1 - turn
        print(maxTile)
        # self.result_file.write(str(maxTile)+"\n")
        # self.result_file.close()

    def isGameOver(self):
        return not self.grid.canMove()

    def getNewTileValue(self):
        if randint(0, 99) < 100 * self.probability:
            return self.possibleNewTiles[0]
        else:
            return self.possibleNewTiles[1]

    def insertRandonTile(self):
        tileValue = self.getNewTileValue()
        cells = self.grid.getAvailableCells()
        cell = cells[randint(0, len(cells) - 1)]
        self.grid.setCellValue(cell, tileValue)

    def generateCurrentBoardAndMoveToText(self, map, move):
        """
        Generate the current board situation and the AI's move decision for that situation into text to export to .csv
        :param map: current board situation
        :param move:
        :return:
        """
        current_board_and_move = ""
        for row in map:
            for cell in row:
                current_board_and_move += str(cell) + ","
        current_board_and_move += str(move) + "\n"
        return current_board_and_move

    def generateCurrentBoard1D(self, map):
        currentBoard = []
        for row in map:
            for cell in row:
                currentBoard.append(cell)
        return np.array([currentBoard])
コード例 #16
0
ファイル: GameManager_3.py プロジェクト: xunilrj/sandbox
class GameManager:
    def __init__(self, size = 4):
        self.grid = Grid(size)
        self.possibleNewTiles = [2, 4]
        self.probability = defaultProbability
        self.initTiles  = defaultInitialTiles
        self.computerAI = None
        self.playerAI   = None
        self.displayer  = None
        self.over       = False

    def setComputerAI(self, computerAI):
        self.computerAI = computerAI

    def setPlayerAI(self, playerAI):
        self.playerAI = playerAI

    def setDisplayer(self, displayer):
        self.displayer = displayer

    def updateAlarm(self, currTime):
        if currTime - self.prevTime > timeLimit + allowance:
            self.over = True
        else:
            while time.clock() - self.prevTime < timeLimit + allowance:
                pass

            self.prevTime = time.clock()

    def start(self):
        for i in range(self.initTiles):
            self.insertRandonTile()

        #self.displayer.display(self.grid)

        # Player AI Goes First
        turn = PLAYER_TURN
        maxTile = 0

        #self.prevTime = time.clock()

        while not self.isGameOver() and not self.over:
            # Copy to Ensure AI Cannot Change the Real Grid to Cheat
            gridCopy = self.grid.clone()

            move = None

            if turn == PLAYER_TURN:
                #print("Player's Turn:", end="")
                move = self.playerAI.getMove(gridCopy)
                #print(actionDic[move])

                # Validate Move
                if move != None and move >= 0 and move < 4:
                    if self.grid.canMove([move]):
                        self.grid.move(move)

                        # Update maxTile
                        maxTile = self.grid.getMaxTile()
                    else:
                        #print("Invalid PlayerAI Move")
                        self.over = True
                else:
                    #print("Invalid PlayerAI Move - 1")
                    self.over = True
            else:
                #print("Computer's turn:")
                move = self.computerAI.getMove(gridCopy)

                # Validate Move
                if move and self.grid.canInsert(move):
                    self.grid.setCellValue(move, self.getNewTileValue())
                else:
                    #print("Invalid Computer AI Move")
                    self.over = True

            #if not self.over:
            #    self.displayer.display(self.grid)

            # Exceeding the Time Allotted for Any Turn Terminates the Game
            #self.updateAlarm(time.clock())

            turn = 1 - turn
        print(maxTile)

    def isGameOver(self):
        return not self.grid.canMove()

    def getNewTileValue(self):
        if randint(0,99) < 100 * self.probability:
            return self.possibleNewTiles[0]
        else:
            return self.possibleNewTiles[1];

    def insertRandonTile(self):
        tileValue = self.getNewTileValue()
        cells = self.grid.getAvailableCells()
        cell = cells[randint(0, len(cells) - 1)]
        self.grid.setCellValue(cell, tileValue)