Esempio n. 1
0
    def findPower(self, state, play_num):
        # a kind of bfs for the nearest powerup
        board = state.board
        origin = state.player_locs[play_num]
        visited = set()

        Q = queue.Queue()
        visited.add(origin)

        start_moves = list(TronProblem.get_safe_actions(board, origin))
        for direction in start_moves:
            neighbor = TronProblem.move(origin, direction)
            r, c = neighbor
            if board[r][c] == '*':  # powerup
                return direction
            Q.put((neighbor, direction))

        while not Q.empty():
            curr, initdir = Q.get()
            r, c = curr
            valid_moves = list(TronProblem.get_safe_actions(board, curr))
            for direction in valid_moves:
                neighbor = TronProblem.move(curr, direction)
                r, c = neighbor
                if board[r][c] == '*':  # powerup
                    return initdir
                if neighbor not in visited:
                    visited.add(neighbor)
                    Q.put((neighbor, initdir))

        # we couldn't find a powerup
        possibilities = list(TronProblem.get_safe_actions(board, origin))
        if possibilities:
            return random.choice(possibilities)
        return 'U'
Esempio n. 2
0
 def freedom(self, state, play_num):
     board = state.board
     origin = state.player_locs[play_num]
     freedom = 0
     for d1 in list(TronProblem.get_safe_actions(board, origin)):
         n1 = TronProblem.move(origin, d1)
         for d2 in list(TronProblem.get_safe_actions(board, n1)):
             n2 = TronProblem.move(origin, d2)
             for d3 in list(TronProblem.get_safe_actions(board, n2)):
                 freedom += 1
     return freedom
Esempio n. 3
0
    def bfs(self,state,play_num): #a bounded search of how many tiles are accessible
        board = state.board

        newboard = [[ -1 for elt in row] for row in state.board]
        origin = state.player_locs[play_num]
        visited = set()
        Q = Queue.Queue()
        Q.put(origin)
        visited.add(origin)
        dis = 0
        #print state.board
        while not Q.empty():
            size = Q.qsize()
            for i in range(size):
                curr = Q.get()
                i,j = curr
                newboard[i][j] = dis
                valid_moves = list(TronProblem.get_safe_actions(board,curr))
                for direction in valid_moves:
                    neighbor = TronProblem.move(curr,direction)
                    if neighbor not in visited:
                        visited.add(neighbor)
                        Q.put(neighbor)
            dis += 1
        #print score
        return newboard
Esempio n. 4
0
 def bfs_with_powerup(self,state,play_num): #a bounded search of how many tiles are accessible
     board = state.board
     origin = state.player_locs[play_num]
     opponent = state.player_locs[(play_num+1)%2]
     connected = False
     visited = set()
     Q = Queue.Queue()
     Q.put(origin)
     visited.add(origin)
     level = 0
     powerup = 0
     #print state.board
     while not Q.empty():
         size = Q.qsize()
         level += 1
         for i in range(size):
             curr = Q.get()
             i,j = curr
             #print (i,j)
             if self.board[i][j] == '*':
                 #print (i,j),origin
                 powerup += 10*math.exp(-level)
             if self.manhattan_distance(curr, opponent) == 1:
                 connected = True
             valid_moves = list(TronProblem.get_safe_actions(board,curr))
             for direction in valid_moves:
                 neighbor = TronProblem.move(curr,direction)
                 if neighbor not in visited:
                     visited.add(neighbor)
                     Q.put(neighbor)
     score = len(visited) + powerup
     #print score
     return score,connected
Esempio n. 5
0
 def decide(self,asp):
     state = asp.get_start_state()
     locs = state.player_locs
     board = state.board
     ptm = state.ptm
     loc = locs[ptm]
     possibilities = list(TronProblem.get_safe_actions(board,loc))
     if not possibilities:
         return 'U'
     decision = possibilities[0]
     for move in self.order:
         if move not in possibilities:
             continue
         next_loc = TronProblem.move(loc, move)
         if len(TronProblem.get_safe_actions(board,next_loc)) < 3:
             decision = move
             break
     return decision
Esempio n. 6
0
def voronoi_heuristic(tron_state):
    '''
    Calculates the difference between "zones of control" as defined
    by a voronoi diagram--zones defining squares that can be reached by p1
    or p2 first.
    '''
    # We make it so that p1 is the player to move and p2 is opponent

    player_locs = determine_players(tron_state)
    p1_loc = player_locs[0]
    p2_loc = player_locs[1]

    board = tron_state.board

    p1_visited = set([p1_loc])
    p1_f = []
    p1_f.append(p1_loc)
    p2_visited = set([p2_loc])
    p2_f = []
    p2_f.append(p2_loc)

    while p1_f or p2_f:
        n_p1_f = []
        for loc in p1_f:
            moves = TronProblem.get_safe_actions(board, loc)
            for move in moves:
                next_loc = action_move(loc, move)
                if (next_loc not in p1_visited) and (next_loc not in p2_visited):
                    n_p1_f.append(next_loc)
                    p1_visited.add(next_loc)

        n_p2_f = []
        for loc in p2_f:
            moves = TronProblem.get_safe_actions(board, loc)
            for move in moves:
                next_loc = action_move(loc, move)
                if (next_loc not in p1_visited) and (next_loc not in p2_visited):
                    n_p2_f.append(next_loc)
                    p2_visited.add(next_loc)

        p1_f = n_p1_f
        p2_f = n_p2_f
    
    return len(p1_visited) - len(p2_visited)
Esempio n. 7
0
 def decide(self,asp):
     state = asp.get_start_state()
     locs = state.player_locs
     board = state.board
     ptm = state.ptm
     loc = locs[ptm]
     possibilities = list(TronProblem.get_safe_actions(board,loc))
     if possibilities:
         return random.choice(possibilities)
     return 'U'
Esempio n. 8
0
    def voronoi(self, state, play_num):
        """Basic voronoi implementation"""
        origin = state.player_locs[play_num]
        visited = {}
        Q = queue.Queue()
        Q.put(origin)
        visited[origin] = 0
        while not Q.empty():
            curr = Q.get()
            valid_moves = list(TronProblem.get_safe_actions(self.board, curr))
            for direction in valid_moves:
                neighbor = TronProblem.move(curr, direction)
                if neighbor not in visited:
                    visited[neighbor] = 1 + visited[curr]
                    Q.put(neighbor)

        score = 0

        opp_visited = {}

        origin = state.player_locs[1 - play_num]
        Q.put(origin)
        opp_visited[origin] = 0
        while not Q.empty():
            curr = Q.get()
            valid_moves = list(TronProblem.get_safe_actions(self.board, curr))
            for direction in valid_moves:
                neighbor = TronProblem.move(curr, direction)
                if neighbor not in opp_visited:
                    opp_visited[neighbor] = 1 + opp_visited[curr]
                    if neighbor in visited:
                        if opp_visited[neighbor] < visited[neighbor]:
                            score -= 1
                        elif opp_visited[neighbor] > visited[neighbor]:
                            score += 1
                    Q.put(neighbor)
        for pos in list(visited.keys()):
            if pos not in opp_visited:
                score += 1
        for pos in list(opp_visited.keys()):
            if pos not in visited:
                score -= 1
        return score
Esempio n. 9
0
 def decide(self, asp):
     """
     Input: asp, a TronProblem
     Output: A direction in {'U','D','L','R'}
     """
     state = asp.get_start_state()
     locs = state.player_locs
     board = state.board
     ptm = state.ptm
     loc = locs[ptm]
     possibilities = list(TronProblem.get_safe_actions(board, loc))
     if not possibilities:
         return "U"
     decision = possibilities[0]
     for move in self.order:
         if move not in possibilities:
             continue
         next_loc = TronProblem.move(loc, move)
         if len(TronProblem.get_safe_actions(board, next_loc)) < 3:
             decision = move
             break
     return decision
Esempio n. 10
0
 def decide(self, asp):
     """
     Input: asp, a TronProblem
     Output: A direction in {'U','D','L','R'}
     """
     state = asp.get_start_state()
     locs = state.player_locs
     board = state.board
     ptm = state.ptm
     loc = locs[ptm]
     possibilities = list(TronProblem.get_safe_actions(board, loc))
     if possibilities:
         return random.choice(possibilities)
     return "U"
Esempio n. 11
0
 def bfs(self,state,play_num): #a bounded search of how many tiles are accessible
     board = state.board
     origin = state.player_locs[play_num]
     visited = set()
     Q = Queue.Queue()
     Q.put(origin)
     visited.add(origin)
     while not Q.empty():
         curr = Q.get()
         valid_moves = list(TronProblem.get_safe_actions(board,curr))
         for direction in valid_moves:
             neighbor = TronProblem.move(curr,direction)
             if neighbor not in visited:
                 visited.add(neighbor)
                 Q.put(neighbor)
     return len(visited)
def alpha_beta_cutoff(asp, cutoff_turn, eval_func):
    """
    An implementation of the alpha_beta_cutoff algorithm that is specifically
    written for the TronProblem (it only considers safe actions)
    """
    state = asp.get_start_state()
    player = state.player_to_move()
    best_action = 'D'
    best_value = -float('inf')
    a = -float('inf')
    b = float('inf')

    for action in TronProblem.get_safe_actions(state.board,
                                               state.player_locs[player]):
        next_state = asp.transition(state, action)
        value = abchelper(asp, next_state, cutoff_turn - 1, a, b, False,
                          eval_func, player)
        if value > best_value:
            best_value = value
            best_action = action
        a = max(a, best_value)
        if b <= a:
            break
    return best_action
Esempio n. 13
0
 def fillboard(self, state, me, enemy):
     board = state.board
     locs = state.player_locs
     myloc = locs[me]
     enemyloc = locs[enemy]
     floodboard = np.array(board)
     if floodboard[myloc] == '*':
         floodboard[myloc] = 'A'  #my powerup
     else:
         floodboard[myloc] = 'M'  #'M' for me
     if floodboard[enemyloc] == '*':
         floodboard[enemyloc] = 'B'  #enemy powerup
     else:
         floodboard[enemyloc] = 'E'  #'E' for enemy
     myvisited = {myloc}
     enemyvisited = {enemyloc}
     myQ = Queue.Queue()
     myQ.put(myloc)
     enemyQ = Queue.Queue()
     enemyQ.put(enemyloc)
     myneighbors = set()
     enemyneighbors = set()
     # keep going until no new positions are added to the queues
     while not myQ.empty() or not enemyQ.empty():
         while not myQ.empty():
             #I fill first
             mycur = myQ.get()
             valid_moves = list(TronProblem.get_safe_actions(board, mycur))
             for direction in valid_moves:
                 neighbor = TronProblem.move(mycur, direction)
                 if neighbor not in myvisited and not (
                         floodboard[neighbor] == 'E'
                         or floodboard[neighbor] == 'B'):
                     if floodboard[neighbor] == '*':  #if tile is a powerup
                         floodboard[
                             neighbor] = 'A'  #Let 'A' represent a 'M' space with powerup
                     else:
                         floodboard[neighbor] = 'M'
                     myvisited.add(neighbor)
                     myneighbors.add(neighbor)
         while not enemyQ.empty():
             #Then enemy fills
             enemycur = enemyQ.get()
             valid_moves = list(
                 TronProblem.get_safe_actions(board, enemycur))
             for direction in valid_moves:
                 neighbor = TronProblem.move(enemycur, direction)
                 if neighbor not in enemyvisited and not (
                         floodboard[neighbor] == 'M'
                         or floodboard[neighbor] == 'A'):
                     if floodboard[neighbor] == '*':
                         floodboard[
                             neighbor] = 'B'  #Let 'B' represent a 'E' space with powerup
                     else:
                         floodboard[neighbor] = 'E'
                     enemyvisited.add(neighbor)
                     enemyneighbors.add(neighbor)
         map(
             myQ.put, myneighbors
         )  #put all the newfound neighbors onto queue for next iteration
         myneighbors = set()  #reset neighbors set
         map(enemyQ.put, enemyneighbors)
         enemyneighbors = set()
     numM = np.count_nonzero(
         floodboard == 'M')  #count the number of tiles I reach first
     numMpwr = np.count_nonzero(
         floodboard ==
         'A')  #count the number of powerup tiles I reach first
     numE = np.count_nonzero(
         floodboard ==
         'E')  #count the number of tiles that enemy reaches first
     numEpwr = np.count_nonzero(
         floodboard ==
         'B')  #count the number of powerup tiles that enemy reaches first
     val = (numM + numMpwr) - (
         numE + numEpwr)  #maximize the difference between our spaces
     return val
Esempio n. 14
0
    def fillboard(self, state, me, enemy):
        board = state.board
        locs = state.player_locs
        myloc = locs[me]
        enemyloc = locs[enemy]
        enemyspace = self.get_surroundings(state, enemyloc, 2)
        floodboard = np.array(board)
        closebonus = 0
        if floodboard[myloc] == '*':
            floodboard[myloc] = 'A'  #my powerup
            closebonus += 2
        else:
            floodboard[myloc] = 'M'  #'M' for me
        if floodboard[enemyloc] == '*':
            floodboard[enemyloc] = 'B'  #enemy powerup
        else:
            floodboard[enemyloc] = 'E'  #'E' for enemy

        for direction in list(TronProblem.get_safe_actions(board, myloc)):
            neighbor = TronProblem.move(myloc, direction)
            if floodboard[neighbor] == '*':
                closebonus += 1

        myvisited = {myloc}
        enemyvisited = {enemyloc}
        myQ = Queue.Queue()
        myQ.put(myloc)
        enemyQ = Queue.Queue()
        enemyQ.put(enemyloc)
        myneighbors = set()
        enemyneighbors = set()
        colored = False
        # KEY
        # A powerup
        # M colored tile me
        # N non-colored tile me
        # keep going until no new positions are added to the queues
        while not myQ.empty() or not enemyQ.empty():
            while not myQ.empty():
                #I fill first
                mycur = myQ.get()
                valid_moves = list(TronProblem.get_safe_actions(board, mycur))
                for direction in valid_moves:
                    neighbor = TronProblem.move(mycur, direction)
                    if neighbor not in myvisited and not (
                            floodboard[neighbor] == 'E' or floodboard[neighbor]
                            == 'F' or floodboard[neighbor] == 'B'):
                        if floodboard[neighbor] == '*':  #if tile is a powerup
                            if colored:
                                floodboard[
                                    neighbor] = 'A'  #Let 'A' represent a 'M' space with powerup
                            else:
                                floodboard[neighbor] = 'C'  #not colored mine
                        else:
                            if colored:
                                floodboard[neighbor] = 'M'
                            else:
                                floodboard[neighbor] = 'N'
                        myvisited.add(neighbor)
                        myneighbors.add(neighbor)
            while not enemyQ.empty():
                #Then enemy fills
                enemycur = enemyQ.get()
                valid_moves = list(
                    TronProblem.get_safe_actions(board, enemycur))
                for direction in valid_moves:
                    neighbor = TronProblem.move(enemycur, direction)
                    if neighbor not in enemyvisited and not (
                            floodboard[neighbor] == 'M' or floodboard[neighbor]
                            == 'N' or floodboard[neighbor] == 'A'):
                        if floodboard[neighbor] == '*':
                            if colored:
                                floodboard[
                                    neighbor] = 'B'  #Let 'B' represent a 'E' space with powerup
                            else:
                                floodboard[neighbor] = 'D'  #not colored enemy
                        else:
                            if colored:
                                floodboard[neighbor] = 'E'
                            else:
                                floodboard[neighbor] = 'F'
                        enemyvisited.add(neighbor)
                        enemyneighbors.add(neighbor)
            colored = not colored
            map(
                myQ.put, myneighbors
            )  #put all the newfound neighbors onto queue for next iteration
            myneighbors = set()  #reset neighbors set
            map(enemyQ.put, enemyneighbors)
            enemyneighbors = set()

        numM = np.count_nonzero(
            floodboard ==
            'M')  #count the number of colored tiles I reach first
        numN = np.count_nonzero(
            floodboard ==
            'N')  #count the number of non-colored tiles I reach first
        numMpwr = np.count_nonzero(
            floodboard ==
            'A')  #count the number of powerup tiles I reach first
        numNpwr = np.count_nonzero(floodboard == 'C')
        numE = np.count_nonzero(
            floodboard ==
            'E')  #count the number of colored tiles that enemy reaches first
        numF = np.count_nonzero(
            floodboard == 'F'
        )  #count the number of non-colored tiles that enemy reaches first
        numEpwr = np.count_nonzero(
            floodboard ==
            'B')  #count the number of powerup tiles that enemy reaches first
        numFpwr = np.count_nonzero(floodboard == 'D')
        val = (min(numM + numMpwr * self.powerup_val,
                   numN + numNpwr * self.powerup_val) +
               (numMpwr + numNpwr) * self.powerup_val) - (
                   min(numE + numEpwr * self.powerup_val,
                       numF + numFpwr * self.powerup_val) +
                   (numEpwr + numFpwr) * self.powerup_val
               )  #maximize the difference between our spaces
        return val + closebonus
Esempio n. 15
0
def _get_safe_actions_random(board, loc):
    actions = list(TronProblem.get_safe_actions(board, loc))
    random.shuffle(actions)
    return actions