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'
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
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
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
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
def bfsadverse(self, state, play_num): board = state.board origin1 = state.player_locs[play_num] origin2 = state.player_locs[1 - play_num] visited1 = set() visited2 = set() score_1 = 1 score_2 = 1 Q1 = queue.Queue() Q2 = queue.Queue() Q1.put(origin1) Q2.put(origin2) visited1.add(origin1) visited2.add(origin2) isQ1 = True while (not Q1.empty()) or (not Q2.empty()): # determine which queue to draw from and and withdraw # from that queue into curr if isQ1: if Q1.empty(): curr = Q2.get() isQ1 = False else: curr = Q1.get() else: if Q2.empty(): curr = Q1.get() isQ1 = True else: curr = Q2.get() valid_moves = _get_safe_actions_random(board, curr) for direction in valid_moves: neighbor = TronProblem.move(curr, direction) #if its a neighbor we haven't visited, add 1 to the score for #the player of the queue we took from if (neighbor not in visited1 and neighbor not in visited2): if isQ1: Q1.put(neighbor) visited1.add(neighbor) score_1 += 1 else: Q2.put(neighbor) visited2.add(neighbor) score_2 += 1 #alternate which queue we try to take from isQ1 = not isQ1 assert Q1.empty() assert Q2.empty() return score_1 - score_2
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 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
def separated(self, state, asp): myboard = np.array(state.board) locs = state.player_locs myloc = locs[state.ptm] myQ = Queue.Queue() myQ.put(myloc) myvisited = {myloc} enemyloc = locs[state.ptm - 1] while not myQ.empty(): mycur = myQ.get() allmoves = list(asp.get_available_actions(state)) for direction in allmoves: neighbor = TronProblem.move(mycur, direction) if neighbor in myvisited: continue if neighbor == enemyloc: # if enemy is accessible, then not seperated return False elif myboard[neighbor] == ' ' or myboard[neighbor] == '*': myQ.put(neighbor) myvisited.add(neighbor) return True
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
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
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