def execute(self, board): start = time.clock() goal = board.them() closedSet = [] openSet = dict() startPath = AStar.Path(board.me(), [], 0, board.distance(board.me(), goal)) openSet[board.me()] = startPath queue = [startPath] tron.log("goal: " + str(goal)) shortestPath = [] while len(queue) > 0 and time.clock() - start < 0.9: path = heappop(queue) shortestPath = path.visited if path.node == goal: break closedSet.append(path.node) destinations = [dest for dest in board.adjacent(path.node) if board.passable(dest) or dest == goal] for dest in destinations: if dest in closedSet: continue newScore = path.score + 1 if dest not in openSet.keys() or openSet[dest] not in queue: newPath = AStar.Path(dest, list(path.visited), newScore, board.distance(dest, goal)) openSet[dest] = newPath heappush(queue, newPath) elif newScore < openSet[dest].score and openSet[dest] in queue: openSet[dest].node = dest openSet[dest].score = newScore newVisited = list(path.visited) newVisited.append(dest) openSet[dest].visited = newVisited openSet[dest].estimate = board.distance(dest, goal) tron.log("Shortest path took: " + str(float(time.clock() - start))) return shortestPath
def closeCombatMode(board, minimaxSpaceCount, shortestPath): maxScore = max([score for score in minimaxSpaceCount.values()]) bestDirs = [ dir for dir in board.moves() if minimaxSpaceCount[dir] == maxScore ] choice = None if len(bestDirs) == 1: choice = bestDirs[0] if choice is None: for dir in bestDirs: if board.rel(dir) == shortestPath[0]: choice = dir break if choice is None: shortestDist = None for dir in bestDirs: distance = board.distance(board.rel(dir), board.them()) if shortestDist == None or distance < shortestDist: choice = dir shortestDist = distance tron.log("Choice: " + str(choice)) return choice
def farAwayMode(board, shortestPath, minimaxSpaceCount): choice = None bestChoices = [] maxScore = max([score for score in minimaxSpaceCount.values()]) minScore = min([score for score in minimaxSpaceCount.values()]) for dir in board.moves(): if board.rel(dir) == shortestPath[0]: choice = dir if ((minScore <= -5 and maxScore > minScore) or maxScore >= 10) and minimaxSpaceCount[dir] == maxScore: bestChoices.append(dir) if len(bestChoices) > 0 and choice not in bestChoices: choice = None if len(bestChoices) == 1: choice = bestChoices[0] if choice == None: shortestDist = None for dir in bestChoices: distance = board.distance(board.rel(dir), board.them()) if shortestDist == None or distance < shortestDist: choice = dir shortestDist = distance tron.log("Choice: " + str(choice)) return choice
def longestPathFloodfill(self, board, spaceCount): queue = self.cachedPaths origin = board.me() originScore = tron.floodfill.floodfillScore(board, origin, []) startnodes = set([path.visited[0] for path in queue if path.visited]) directions = [dir for dir in board.moves(origin) if board.rel(dir, origin) not in startnodes] for dir in directions: path = OptimizeSpaceAlgorithm.Path(board, board.rel(dir, origin), [], originScore, [], spaceCount[dir]) heappush(queue, path) newAllPaths = [] while queue and time.clock() - board.startTime < 0.82: path = heappop(queue) destinations = board.moveableDestinations(path.node, path.visited) if not destinations: heappush(newAllPaths, path) continue for dest in destinations: newScore = tron.floodfill.floodfillScore(board, dest, path.visited) newPath = OptimizeSpaceAlgorithm.Path(board, dest, list(path.visited), path.score, list(path.diffSequence), newScore) heappush(queue, newPath) for path in queue: heappush(newAllPaths, path) self.cachedPaths = newAllPaths maxPath = newAllPaths[0] for path in newAllPaths: if len(path.visited) > len(maxPath.visited): maxPath = path tron.log(maxPath.visited) tron.log(maxPath.score) return maxPath.visited
def execute(self, board, spaceCount): timer = time.clock() path = self.longestPathFloodfill(board, spaceCount) tron.log("Longestpath: " + str(len(path))) dest = path[0] choice = [dir for dir in board.moves() if board.rel(dir) == dest][0] self.cachedPaths = self.prepareCachedPaths(dest) tron.log("Survival algorithm took: " + str(time.clock() - timer)) return choice
def execute(self, board): levels = self.minimax(board) root = levels[0].nodes[0] tron.log("Minimax level: " + str(len(levels)-1)) minimaxSpaceCount = dict() for node in root.children: for dir in board.moves(board.me()): if board.rel(dir) == node.me: minimaxSpaceCount[dir] = node.score return minimaxSpaceCount
def execute(self, board): levels = self.minimax(board) root = levels[0].nodes[0] tron.log("Minimax level: " + str(len(levels)-1)) # Compute the minimax score for each direction we can take. minimaxSpaceCount = dict() for node in root.children: for dir in board.moves(board.me()): if board.rel(dir) == node.me: minimaxSpaceCount[dir] = node.score return minimaxSpaceCount
def survivalMode(board): spaceCount = dict() for dir in board.moves(): dest = board.rel(dir) floodfilled = tron.floodfill.execute(board, dest) #enemyReachable = enemyReachable or dest in enemyMoves or len(filter(lambda node : node in enemyMoves, floodfilled)) > 0 deadCorners = [node for node in floodfilled if len(board.adjacentImpassable(node)) == 3] spaceCount[dir] = len(floodfilled) - len(deadCorners) + 1 tron.log("Spacecount: " + str(spaceCount)) choice = tron.optimizeSpaceAlgorithm.execute(board, spaceCount) tron.log("Choice: " + str(choice)) return choice
def execute(self, board, origin, exclude=[]): ''' Compute all nodes that can be reached from the provided origin. Returns a list of all these nodes. The exclude parameter can be used to ignore certain nodes and consider them impassable. ''' start = time.clock() visited = [] queue = deque() queue.append(origin) while queue: node = queue.popleft() if node in visited: continue west = self.findFurthestNodeInDirection(board, node, tron.WEST, exclude) east = self.findFurthestNodeInDirection(board, node, tron.EAST, exclude) westToEast = west northInterrupted = True southInterrupted = True while westToEast != board.rel(tron.EAST, east): north = board.rel(tron.NORTH, westToEast) if not northInterrupted and (not board.passable(north) or north in exclude or north in visited): northInterrupted = True elif northInterrupted and board.passable( north ) and north not in exclude and north not in visited: queue.append(north) northInterrupted = False south = board.rel(tron.SOUTH, westToEast) if not southInterrupted and (not board.passable(south) or south in exclude or south in visited): southInterrupted = True elif southInterrupted and board.passable( south ) and south not in exclude and south not in visited: queue.append(south) southInterrupted = False visited.append(westToEast) westToEast = board.rel(tron.EAST, westToEast) tron.log("FLOODFILL TOOK: " + str(time.clock() - start)) return visited
def floodfillMode(board): spaceCount = dict() for dir in board.moves(): dest = board.rel(dir) floodfilled = tron.floodfill.execute(board, dest) #enemyReachable = enemyReachable or dest in enemyMoves or len(filter(lambda node : node in enemyMoves, floodfilled)) > 0 deadCorners = [node for node in floodfilled if len(board.adjacentImpassable(node)) == 3] spaceCount[dir] = len(floodfilled) - len(deadCorners) + 1 tron.log("Spacecount: " + str(spaceCount)) enemySpaceCount = dict() for dir in board.moves(): myPos = board.rel(dir) floodfilled = tron.floodfill.execute(board, board.them(), [myPos]) deadCorners = [node for node in floodfilled if len(board.adjacentImpassable(node)) == 3] enemySpaceCount[dir] = len(floodfilled) - len(deadCorners) + 1 tron.log("EnemySpacecount: " + str(enemySpaceCount)) bestchoices = [] maxscore = None for dir in spaceCount.keys(): score = spaceCount[dir] - enemySpaceCount[dir] if score == maxscore: bestchoices.append(dir) elif maxscore == None or score > maxscore: maxscore = score bestchoices = [dir] bestchoices = findLongestPathDirections(board.me(), bestchoices) tron.log("Bestchoices: " + str(bestchoices)) choice = bestchoices[0] tron.log("Choice: " + str(choice)) return choice
def execute(self, board, spaceCount, enemySpaceCount): #self.prepareCache(board, spaceCount, enemySpaceCount) levels = self.minimax(board, spaceCount, enemySpaceCount) #self.cachedLevels = levels root = levels[0].nodes[0] tron.log("Minimax level: " + str(len(levels)-1)) minimaxSpaceCount = dict() for node in root.children: for dir in spaceCount.keys(): if board.rel(dir) == node.me: minimaxSpaceCount[dir] = node.score return minimaxSpaceCount
def execute(self, board, spaceCount): timer = time.clock() # Find longest path path = self.longestPathFloodfill(board, spaceCount) tron.log("Longestpath: " + str(len(path))) dest = path[0] # Find which direction is relevant for the computed destination choice = [dir for dir in board.moves() if board.rel(dir) == dest][0] # Prepare cached paths for next decision round self.cachedPaths = self.prepareCachedPaths(dest) tron.log("Survival algorithm took: " + str(time.clock() - timer)) return choice
def survivalMode(board): spaceCount = dict() for dir in board.moves(): dest = board.rel(dir) floodfilled = tron.floodfill.execute(board, dest) #enemyReachable = enemyReachable or dest in enemyMoves or len(filter(lambda node : node in enemyMoves, floodfilled)) > 0 deadCorners = [ node for node in floodfilled if len(board.adjacentImpassable(node)) == 3 ] spaceCount[dir] = len(floodfilled) - len(deadCorners) + 1 tron.log("Spacecount: " + str(spaceCount)) choice = tron.optimizeSpaceAlgorithm.execute(board, spaceCount) tron.log("Choice: " + str(choice)) return choice
def which_move(board): start = time.clock() if len(board.moves()) == 0: return tron.SOUTH enemyMoves = [ board.rel(dir, board.them()) for dir in board.moves(board.them()) ] enemyReachable = False spaceCount = dict() for dir in board.moves(): dest = board.rel(dir) floodfilled = tron.floodfill.execute(board, dest) enemyReachable = enemyReachable or dest in enemyMoves or len( filter(lambda node: node in enemyMoves, floodfilled)) > 0 deadCorners = [ node for node in floodfilled if len(board.adjacentImpassable(node)) == 3 ] spaceCount[dir] = len(floodfilled) - len(deadCorners) + 1 tron.debug("Spacecount: " + str(spaceCount) + "\n") tron.debug("EnemyReachable: " + str(enemyReachable) + "\n") #enemyReachable = False if not enemyReachable: return survivalMode(board, spaceCount) enemySpaceCount = dict() for dir in board.moves(): enemySpaceCount[dir] = tron.floodfill.floodfillScore( board, board.them(), [board.rel(dir)]) #tron.log("EnemySpaceCount: " + str(enemySpaceCount)) shortestPath = attack_algorithms.AStar().execute(board) minimaxSpaceCount = tron.minimax.execute(board, spaceCount, enemySpaceCount) tron.log("minimaxspacecount: " + str(minimaxSpaceCount)) #tron.log(len(shortestPath)) #tron.log("Shortest path: " + str(shortestPath)) if len(shortestPath) >= 6: return farAwayMode(board, shortestPath, minimaxSpaceCount) return closeCombatMode(board, minimaxSpaceCount, shortestPath) '''
def survivalMode(board): ''' Enter survival mode; try to fill the board as efficiently as possible. ''' # Count the number of spaces we can reach. spaceCount = dict() for dir in board.moves(): dest = board.rel(dir) floodfilled = tron.floodfill.execute(board, dest) #enemyReachable = enemyReachable or dest in enemyMoves or len(filter(lambda node : node in enemyMoves, floodfilled)) > 0 deadCorners = [node for node in floodfilled if len(board.adjacentImpassable(node)) == 3] spaceCount[dir] = len(floodfilled) - len(deadCorners) + 1 tron.log("Spacecount: " + str(spaceCount)) choice = tron.optimizeSpaceAlgorithm.execute(board, spaceCount) tron.log("Choice: " + str(choice)) return choice
def farAwayMode(board, shortestPath, spaceCount, enemySpaceCount): choice = None bestchoices = [] maxscore = None for dir in board.moves(): if board.rel(dir) == shortestPath[1]: choice = dir score = spaceCount[dir] - enemySpaceCount[dir] if score == maxscore: bestchoices.append(dir) elif maxscore == None or score > maxscore: maxscore = score bestchoices = [dir] if choice == None or choice not in bestchoices: choice = random.choice(bestchoices) tron.log("Choice: " + str(choice)) return choice
def longestPathFloodIterative(self, board): currLevel = [] nextLevel = [] origin = board.me() originScore = len(tron.floodfill.execute(board, origin, [])) startnodes = set( [path.visited[0] for path in currLevel if len(path.visited) > 0]) destinations = [ dest for dest in board.moveableDestinations(origin) if dest not in startnodes ] for dest in destinations: path = OptimizeSpaceAlgorithm.PathIt(dest, [], board) heappush(currLevel, path) maxPath = currLevel[0] newAllPaths = [] while len(currLevel) > 0 and time.clock() - board.startTime < 0.9: path = heappop(currLevel) destinations = [ dest for dest in board.moveableDestinations(path.node) if dest not in path.visited ] if len(destinations) == 0: #newAllPaths.append(path) continue for dest in destinations: newVisited = list(path.visited) newPath = OptimizeSpaceAlgorithm.PathIt( dest, newVisited, board) heappush(nextLevel, newPath) if len(currLevel) == 0: for nextPath in nextLevel: heappush(currLevel, nextPath) nextLevel = [] tron.log("nextlevel") newAllPaths.extend(currLevel) newAllPaths.extend(nextLevel) for path in newAllPaths: if len(path.visited) > len(maxPath.visited): maxPath = path elif len(path.visited) == len( maxPath.visited) and path.score > maxPath.score: maxPath = path return maxPath.visited
def execute(self, board, origin, exclude=[]): start = time.clock() visited = [] queue = deque() queue.append(origin) while queue: node = queue.popleft() if node in visited: continue west = self.findFurthestNodeInDirection(board, node, tron.WEST, exclude) east = self.findFurthestNodeInDirection(board, node, tron.EAST, exclude) westToEast = west northInterrupted = True southInterrupted = True while westToEast != board.rel(tron.EAST, east): north = board.rel(tron.NORTH, westToEast) if not northInterrupted and (not board.passable(north) or north in exclude or north in visited): northInterrupted = True elif northInterrupted and board.passable( north ) and north not in exclude and north not in visited: queue.append(north) northInterrupted = False south = board.rel(tron.SOUTH, westToEast) if not southInterrupted and (not board.passable(south) or south in exclude or south in visited): southInterrupted = True elif southInterrupted and board.passable( south ) and south not in exclude and south not in visited: queue.append(south) southInterrupted = False visited.append(westToEast) westToEast = board.rel(tron.EAST, westToEast) tron.log("FLOODFILL TOOK: " + str(time.clock() - start)) return visited
def execute(self, board, origin, exclude=[]): ''' Compute all nodes that can be reached from the provided origin. Returns a list of all these nodes. The exclude parameter can be used to ignore certain nodes and consider them impassable. ''' start = time.clock() visited = [] queue = deque() queue.append(origin) while queue: node = queue.popleft() if node in visited: continue west = self.findFurthestNodeInDirection(board, node, tron.WEST, exclude) east = self.findFurthestNodeInDirection(board, node, tron.EAST, exclude) westToEast = west northInterrupted = True southInterrupted = True while westToEast != board.rel(tron.EAST, east): north = board.rel(tron.NORTH, westToEast) if not northInterrupted and (not board.passable(north) or north in exclude or north in visited): northInterrupted = True elif northInterrupted and board.passable(north) and north not in exclude and north not in visited: queue.append(north) northInterrupted = False south = board.rel(tron.SOUTH, westToEast) if not southInterrupted and (not board.passable(south) or south in exclude or south in visited): southInterrupted = True elif southInterrupted and board.passable(south) and south not in exclude and south not in visited: queue.append(south) southInterrupted = False visited.append(westToEast) westToEast = board.rel(tron.EAST, westToEast) tron.log("FLOODFILL TOOK: " + str(time.clock() - start)) return visited
def computeDistances(self, board, origin, exclude=[]): ''' Compute the distances to all points on the board from point origin, including the distance to origin itself (always 0). Optionally, an exclude parameter can be given to exclude certain points on the board. ''' start = time.clock() vertices = [] allVertices = [] distances = dict() for y in xrange(board.height): for x in xrange(board.width): coords = (y, x) if board.passable(coords) and coords not in exclude: distances[coords] = sys.maxint vertices.append(coords) distances[origin] = 0 vertices.append(origin) while vertices: minScore = sys.maxint vertex = None for v in vertices: if distances[v] < minScore: minScore = distances[v] vertex = v if vertex is None: break vertices.remove(vertex) neighbours = [ dest for dest in board.moveableDestinations(vertex) if dest in vertices and dest not in exclude ] newScore = distances[vertex] + 1 for neighbour in neighbours: if newScore < distances[neighbour]: distances[neighbour] = newScore tron.log("Dijkstra took: " + str(float(time.clock() - start))) tron.log(distances) return distances
def longestPathFloodfill(self, board, spaceCount): queue = self.cachedPaths origin = board.me() originScore = tron.floodfill.floodfillScore(board, origin, []) startnodes = set([path.visited[0] for path in queue if path.visited]) directions = [ dir for dir in board.moves(origin) if board.rel(dir, origin) not in startnodes ] for dir in directions: path = OptimizeSpaceAlgorithm.Path(board, board.rel(dir, origin), [], originScore, [], spaceCount[dir]) heappush(queue, path) newAllPaths = [] while queue and time.clock() - board.startTime < 0.82: path = heappop(queue) destinations = board.moveableDestinations(path.node, path.visited) if not destinations: heappush(newAllPaths, path) continue for dest in destinations: newScore = tron.floodfill.floodfillScore( board, dest, path.visited) newPath = OptimizeSpaceAlgorithm.Path(board, dest, list(path.visited), path.score, list(path.diffSequence), newScore) heappush(queue, newPath) for path in queue: heappush(newAllPaths, path) self.cachedPaths = newAllPaths maxPath = newAllPaths[0] for path in newAllPaths: if len(path.visited) > len(maxPath.visited): maxPath = path tron.log(maxPath.visited) tron.log(maxPath.score) return maxPath.visited
def which_move(board): start = time.clock() if len(board.moves()) == 0: return tron.SOUTH enemyMoves = [board.rel(dir, board.them()) for dir in board.moves(board.them())] enemyReachable = False spaceCount = dict() for dir in board.moves(): dest = board.rel(dir) floodfilled = tron.floodfill.execute(board, dest) enemyReachable = enemyReachable or dest in enemyMoves or len(filter(lambda node : node in enemyMoves, floodfilled)) > 0 deadCorners = [node for node in floodfilled if len(board.adjacentImpassable(node)) == 3] spaceCount[dir] = len(floodfilled) - len(deadCorners) + 1 tron.debug("Spacecount: " + str(spaceCount) + "\n") tron.debug("EnemyReachable: " + str(enemyReachable) + "\n") #enemyReachable = False if not enemyReachable: return survivalMode(board, spaceCount) enemySpaceCount = dict() for dir in board.moves(): enemySpaceCount[dir] = tron.floodfill.floodfillScore(board, board.them(), [board.rel(dir)]) #tron.log("EnemySpaceCount: " + str(enemySpaceCount)) shortestPath = attack_algorithms.AStar().execute(board) minimaxSpaceCount = tron.minimax.execute(board, spaceCount, enemySpaceCount) tron.log("minimaxspacecount: " + str(minimaxSpaceCount)) #tron.log(len(shortestPath)) #tron.log("Shortest path: " + str(shortestPath)) if len(shortestPath) >= 6: return farAwayMode(board, shortestPath, minimaxSpaceCount) return closeCombatMode(board, minimaxSpaceCount, shortestPath) '''
def computeDistances(self, board, origin, exclude=[]): ''' Compute the distances to all points on the board from point origin, including the distance to origin itself (always 0). Optionally, an exclude parameter can be given to exclude certain points on the board. ''' start = time.clock() vertices = [] allVertices = [] distances = dict() for y in xrange(board.height): for x in xrange(board.width): coords = (y, x) if board.passable(coords) and coords not in exclude: distances[coords] = sys.maxint vertices.append(coords) distances[origin] = 0 vertices.append(origin) while vertices: minScore = sys.maxint vertex = None for v in vertices: if distances[v] < minScore: minScore = distances[v] vertex = v if vertex is None: break vertices.remove(vertex) neighbours = [dest for dest in board.moveableDestinations(vertex) if dest in vertices and dest not in exclude] newScore = distances[vertex] + 1 for neighbour in neighbours: if newScore < distances[neighbour]: distances[neighbour] = newScore tron.log("Dijkstra took: " + str(float(time.clock() - start))) tron.log(distances) return distances
def closeCombatMode(board, minimaxSpaceCount, shortestPath): maxScore = max([score for score in minimaxSpaceCount.values()]) bestDirs = [dir for dir in board.moves() if minimaxSpaceCount[dir] == maxScore] choice = None if len(bestDirs) == 1: choice = bestDirs[0] if choice is None: for dir in bestDirs: if board.rel(dir) == shortestPath[0]: choice = dir break if choice is None: shortestDist = None for dir in bestDirs: distance = board.distance(board.rel(dir), board.them()) if shortestDist == None or distance < shortestDist: choice = dir shortestDist = distance tron.log("Choice: " + str(choice)) return choice
def execute(self, board, origin, exclude=[]): start = time.clock() visited = [] queue = deque() queue.append(origin) while queue: node = queue.popleft() if node in visited: continue west = self.findFurthestNodeInDirection(board, node, tron.WEST, exclude) east = self.findFurthestNodeInDirection(board, node, tron.EAST, exclude) westToEast = west northInterrupted = True southInterrupted = True while westToEast != board.rel(tron.EAST, east): north = board.rel(tron.NORTH, westToEast) if not northInterrupted and (not board.passable(north) or north in exclude or north in visited): northInterrupted = True elif northInterrupted and board.passable(north) and north not in exclude and north not in visited: queue.append(north) northInterrupted = False south = board.rel(tron.SOUTH, westToEast) if not southInterrupted and (not board.passable(south) or south in exclude or south in visited): southInterrupted = True elif southInterrupted and board.passable(south) and south not in exclude and south not in visited: queue.append(south) southInterrupted = False visited.append(westToEast) westToEast = board.rel(tron.EAST, westToEast) tron.log("FLOODFILL TOOK: " + str(time.clock() - start)) return visited
def floodfillMode(board): spaceCount = dict() for dir in board.moves(): dest = board.rel(dir) floodfilled = tron.floodfill.execute(board, dest) #enemyReachable = enemyReachable or dest in enemyMoves or len(filter(lambda node : node in enemyMoves, floodfilled)) > 0 deadCorners = [ node for node in floodfilled if len(board.adjacentImpassable(node)) == 3 ] spaceCount[dir] = len(floodfilled) - len(deadCorners) + 1 tron.log("Spacecount: " + str(spaceCount)) enemySpaceCount = dict() for dir in board.moves(): myPos = board.rel(dir) floodfilled = tron.floodfill.execute(board, board.them(), [myPos]) deadCorners = [ node for node in floodfilled if len(board.adjacentImpassable(node)) == 3 ] enemySpaceCount[dir] = len(floodfilled) - len(deadCorners) + 1 tron.log("EnemySpacecount: " + str(enemySpaceCount)) bestchoices = [] maxscore = None for dir in spaceCount.keys(): score = spaceCount[dir] - enemySpaceCount[dir] if score == maxscore: bestchoices.append(dir) elif maxscore == None or score > maxscore: maxscore = score bestchoices = [dir] bestchoices = findLongestPathDirections(board.me(), bestchoices) tron.log("Bestchoices: " + str(bestchoices)) choice = bestchoices[0] tron.log("Choice: " + str(choice)) return choice
def execute(self, board, spaceCount, deadCorners): self.timer = time.clock() spaceUpperBound = max(spaceCount.values()) - len(deadCorners) path = self.longestPathFloodfill(board) tron.debug("Longestpath: " + str(len(path)) + "\n") dest = path[0] choice = None for dir in board.moves(): if board.rel(dir) == dest: choice = dir tron.log(len(self.allPaths)) self.allPaths = self.prepareQueue(dest) tron.log(len(self.allPaths)) tron.log("Optimize space algorithm time: " + str(time.clock() - self.timer)) self.timer = 0 return choice
def longestPathFloodfill(self, board): queue = self.allPaths #queue = [] origin = board.me() originScore = len(tron.floodfill.execute(board, origin, [])) startnodes = set( [path.visited[0] for path in queue if len(path.visited) > 0]) destinations = [ dest for dest in board.moveableDestinations(origin) if dest not in startnodes ] tron.log(destinations) for dest in destinations: path = OptimizeSpaceAlgorithm.Path(dest, [], originScore, [], board) heappush(queue, path) maxPath = queue[0] newAllPaths = [] while len(queue) > 0 and time.clock() - self.timer < 0.93: path = heappop(queue) destinations = [ dest for dest in board.moveableDestinations(path.node) if dest not in path.visited ] if len(destinations) == 0: newAllPaths.append(path) continue for dest in destinations: newVisited = list(path.visited) newDiffSequence = list(path.diffSequence) newPath = OptimizeSpaceAlgorithm.Path(dest, newVisited, path.score, newDiffSequence, board) heappush(queue, newPath) newAllPaths.extend(queue) self.allPaths = newAllPaths for path in newAllPaths: if len(path.visited) >= len(maxPath.visited): maxPath = path tron.log(maxPath.visited) tron.log(maxPath.score) return maxPath.visited
def which_move(board): if not board.moves(): # If we have nowhere to go, don't bother thinking about it. return tron.SOUTH # If the board is too large, our usual approach is simply too slow. Simpler # modes will then have to be used. if board.width >= 40 and board.height >= 40: return wallhugMode(board) if board.width >= 20 and board.height >= 20: return floodfillMode(board) shortestPath = tron.aStar.execute(board) tron.log("ShortestPath: " + str(shortestPath)) # Can we reach the enemy? enemyReachable = shortestPath is not None tron.log("EnemyReachable: " + str(enemyReachable)) #enemyReachable = False if not enemyReachable: return survivalMode(board) shortestPath = shortestPath[1:] #if shortestPath[-1] != board.them() or time.clock() - board.startTime > 0.2: # return shortestPathMode(board, shortestPath) #enemySpaceCount = dict() #for dir in board.moves(): # enemySpaceCount[dir] = tron.floodfill.floodfillScore(board, board.them(), [board.rel(dir)]) #tron.log("EnemySpaceCount: " + str(enemySpaceCount)) minimaxSpaceCount = tron.minimax.execute(board) tron.log("minimaxspacecount: " + str(minimaxSpaceCount)) #if not minimaxSpaceCount: # return shortestPathMode(board, shortestPath) #if len(shortestPath) >= 6: # return farAwayMode(board, shortestPath, minimaxSpaceCount) return minimaxMode(board, minimaxSpaceCount, shortestPath)
def execute(self, board): start = time.clock() goal = board.them() closedSet = [] openSet = [board.me()] came_from = {} travelledScore = {board.me(): 0} finalScore = {board.me(): board.distance(board.me(), goal)} finalNode = None while openSet: node = openSet[0] minScore = finalScore[node] for n in openSet: if finalScore[n] < minScore: minScore = finalScore[n] node = n finalNode = node if node == goal or time.clock() - board.startTime > 0.9: tron.log("Shortest path took: " + str(float(time.clock() - start))) return self.reconstructPath(finalNode, came_from) openSet.remove(node) closedSet.append(node) neighbours = [dest for dest in board.adjacent(node) if board.passable(dest) and dest not in closedSet or dest == goal] newTravelledScore = travelledScore[node] + 1 for neighbour in neighbours: if neighbour not in openSet: openSet.append(neighbour) tentative = True elif newTravelledScore < travelledScore[neighbour]: tentative = True else: tentative = False if tentative: came_from[neighbour] = node travelledScore[neighbour] = newTravelledScore finalScore[neighbour] = newTravelledScore + board.distance(neighbour, goal) tron.log("Shortest path took: " + str(float(time.clock() - start))) tron.log("Shortest path failed.") return None
def which_move(board): if not board.moves(): return tron.SOUTH if board.width >= 40 and board.height >= 40: return wallhugMode(board) if board.width >= 20 and board.height >= 20: return floodfillMode(board) enemyMoves = [ board.rel(dir, board.them()) for dir in board.moves(board.them()) ] shortestPath = tron.aStar.execute(board) tron.log("ShortestPath: " + str(shortestPath)) enemyReachable = shortestPath is not None tron.log("EnemyReachable: " + str(enemyReachable)) #enemyReachable = False if not enemyReachable: return survivalMode(board) shortestPath = shortestPath[1:] #if shortestPath[-1] != board.them() or time.clock() - board.startTime > 0.2: # return shortestPathMode(board, shortestPath) #enemySpaceCount = dict() #for dir in board.moves(): # enemySpaceCount[dir] = tron.floodfill.floodfillScore(board, board.them(), [board.rel(dir)]) #tron.log("EnemySpaceCount: " + str(enemySpaceCount)) minimaxSpaceCount = tron.minimax.execute(board) tron.log("minimaxspacecount: " + str(minimaxSpaceCount)) #if not minimaxSpaceCount: # return shortestPathMode(board, shortestPath) #if len(shortestPath) >= 6: # return farAwayMode(board, shortestPath, minimaxSpaceCount) return minimaxMode(board, minimaxSpaceCount, shortestPath)
def longestPathFloodIterative(self, board): currLevel = [] nextLevel = [] origin = board.me() originScore = len(tron.floodfill.execute(board, origin, [])) startnodes = set([path.visited[0] for path in currLevel if len(path.visited) > 0]) destinations = [dest for dest in board.moveableDestinations(origin) if dest not in startnodes] for dest in destinations: path = OptimizeSpaceAlgorithm.PathIt(dest, [], board) heappush(currLevel, path) maxPath = currLevel[0] newAllPaths = [] while len(currLevel) > 0 and time.clock() - self.timer < 0.9: path = heappop(currLevel) destinations = [dest for dest in board.moveableDestinations(path.node) if dest not in path.visited] if len(destinations) == 0: #newAllPaths.append(path) continue for dest in destinations: newVisited = list(path.visited) newPath = OptimizeSpaceAlgorithm.PathIt(dest, newVisited, board) heappush(nextLevel, newPath) if len(currLevel) == 0: for nextPath in nextLevel: heappush(currLevel, nextPath) nextLevel = [] tron.log("nextlevel") newAllPaths.extend(currLevel) newAllPaths.extend(nextLevel) for path in newAllPaths: if len(path.visited) > len(maxPath.visited): maxPath = path elif len(path.visited) == len(maxPath.visited) and path.score > maxPath.score: maxPath = path tron.log(maxPath.visited) tron.log(maxPath.score) return maxPath.visited
def minimaxMode(board, minimaxSpaceCount, shortestPath): maxScore = max(minimaxSpaceCount.values()) bestDirs = [ dir for dir in board.moves() if minimaxSpaceCount[dir] == maxScore ] if len(bestDirs) == 1: tron.log("Minimax Choice: " + str(bestDirs[0])) return bestDirs[0] for dir in bestDirs: if board.rel(dir) == shortestPath[0]: tron.log("Minimax/Shortestpath Choice: " + str(dir)) return dir newBestDirs = [] minHeuristic = None for dir in bestDirs: heuristic = board.distance(board.rel(dir), board.them()) - len( board.adjacentImpassable(board.rel(dir))) * 2 if minHeuristic is None or heuristic < minHeuristic: newBestDirs = [dir] minHeuristic = heuristic elif heuristic == minHeuristic: newBestDirs.append(dir) ''' if len(newBestDirs) == 1: tron.log("Minimax/Heuristic 1 choice: " + str(newBestDirs[0])) return newBestDirs[0] for dir in newBestDirs: if board.rel(dir) == shortestPath[0]: tron.log("Minimax/Heuristic/Shortestpath Choice: " + str(dir)) return dir ''' choice = newBestDirs[0] tron.log("Minimax/Heuristic 2 choice: " + str(choice)) return choice
def which_move(board): if not board.moves(): return tron.SOUTH if board.width >= 40 and board.height >= 40: return wallhugMode(board) if board.width >= 20 and board.height >= 20: return floodfillMode(board) enemyMoves = [board.rel(dir, board.them()) for dir in board.moves(board.them())] shortestPath = tron.aStar.execute(board) tron.log("ShortestPath: " + str(shortestPath)) enemyReachable = shortestPath is not None tron.log("EnemyReachable: " + str(enemyReachable)) #enemyReachable = False if not enemyReachable: return survivalMode(board) shortestPath = shortestPath[1:] #if shortestPath[-1] != board.them() or time.clock() - board.startTime > 0.2: # return shortestPathMode(board, shortestPath) #enemySpaceCount = dict() #for dir in board.moves(): # enemySpaceCount[dir] = tron.floodfill.floodfillScore(board, board.them(), [board.rel(dir)]) #tron.log("EnemySpaceCount: " + str(enemySpaceCount)) minimaxSpaceCount = tron.minimax.execute(board) tron.log("minimaxspacecount: " + str(minimaxSpaceCount)) #if not minimaxSpaceCount: # return shortestPathMode(board, shortestPath) #if len(shortestPath) >= 6: # return farAwayMode(board, shortestPath, minimaxSpaceCount) return minimaxMode(board, minimaxSpaceCount, shortestPath)
def longestPathFloodfill(self, board): queue = self.allPaths #queue = [] origin = board.me() originScore = len(tron.floodfill.execute(board, origin, [])) startnodes = set([path.visited[0] for path in queue if len(path.visited) > 0]) destinations = [dest for dest in board.moveableDestinations(origin) if dest not in startnodes] tron.log(destinations) for dest in destinations: path = OptimizeSpaceAlgorithm.Path(dest, [], originScore, [], board) heappush(queue, path) maxPath = queue[0] newAllPaths = [] while len(queue) > 0 and time.clock() - self.timer < 0.93: path = heappop(queue) destinations = [dest for dest in board.moveableDestinations(path.node) if dest not in path.visited] if len(destinations) == 0: newAllPaths.append(path) continue for dest in destinations: newVisited = list(path.visited) newDiffSequence = list(path.diffSequence) newPath = OptimizeSpaceAlgorithm.Path(dest, newVisited, path.score, newDiffSequence, board) heappush(queue, newPath) newAllPaths.extend(queue) self.allPaths = newAllPaths for path in newAllPaths: if len(path.visited) >= len(maxPath.visited): maxPath = path tron.log(maxPath.visited) tron.log(maxPath.score) return maxPath.visited
def minimaxMode(board, minimaxSpaceCount, shortestPath): ''' Use the input of the minimax algorithm to enter minimax mode. ''' maxScore = max(minimaxSpaceCount.values()) bestDirs = [dir for dir in board.moves() if minimaxSpaceCount[dir] == maxScore] if len(bestDirs) == 1: # There's a clear best direction; take it. tron.log("Minimax Choice: " + str(bestDirs[0])) return bestDirs[0] # There are multiple best directions (minimax score is the same). for dir in bestDirs: if board.rel(dir) == shortestPath[0]: # If a best direction coincides with the computed shortest path to # the enemy, take this (heuristic approach 1). tron.log("Minimax/Shortestpath Choice: " + str(dir)) return dir # Heuristic approach 2: go in the direction that has the shortest absolute # distance to the enemy. An extra weight is calculated in for possible dead # corners. newBestDirs = [] minHeuristic = None for dir in bestDirs: heuristic = board.distance(board.rel(dir), board.them()) - len(board.adjacentImpassable(board.rel(dir))) * 2 if minHeuristic is None or heuristic < minHeuristic: newBestDirs = [dir] minHeuristic = heuristic elif heuristic == minHeuristic: newBestDirs.append(dir) # If we still have multiple best directions: Just pick the first. choice = newBestDirs[0] tron.log("Minimax/Heuristic 2 choice: " + str(choice)) return choice
def minimaxMode(board, minimaxSpaceCount, shortestPath): maxScore = max(minimaxSpaceCount.values()) bestDirs = [dir for dir in board.moves() if minimaxSpaceCount[dir] == maxScore] if len(bestDirs) == 1: tron.log("Minimax Choice: " + str(bestDirs[0])) return bestDirs[0] for dir in bestDirs: if board.rel(dir) == shortestPath[0]: tron.log("Minimax/Shortestpath Choice: " + str(dir)) return dir newBestDirs = [] minHeuristic = None for dir in bestDirs: heuristic = board.distance(board.rel(dir), board.them()) - len(board.adjacentImpassable(board.rel(dir))) * 2 if minHeuristic is None or heuristic < minHeuristic: newBestDirs = [dir] minHeuristic = heuristic elif heuristic == minHeuristic: newBestDirs.append(dir) ''' if len(newBestDirs) == 1: tron.log("Minimax/Heuristic 1 choice: " + str(newBestDirs[0])) return newBestDirs[0] for dir in newBestDirs: if board.rel(dir) == shortestPath[0]: tron.log("Minimax/Heuristic/Shortestpath Choice: " + str(dir)) return dir ''' choice = newBestDirs[0] tron.log("Minimax/Heuristic 2 choice: " + str(choice)) return choice
def survivalMode(board, spaceCount): choice = tron.optimizeSpaceAlgorithm.execute(board, spaceCount) tron.log("Choice: " + str(choice)) return choice def findLongestPathDirections(start, directions): longestDirections = directions if len(directions) > 1: maxpathlength = -1 longestDirections = [] for dir in directions: pathlength = 0 node = start while board.passable(board.rel(dir, node)): pathlength += 1 node = board.rel(dir, node) if pathlength == maxpathlength: longestDirections.append(dir) elif pathlength > maxpathlength: maxpathlength = pathlength longestDirections = [dir] return longestDirections # you do not need to modify this part for board in tron.Board.generate(): tron.move(which_move(board)) tron.log("Turn took: " + str(float(time.clock() - board.startTime)))
def survivalMode(board, spaceCount): choice = tron.optimizeSpaceAlgorithm.execute(board, spaceCount) tron.log("Choice: " + str(choice)) return choice
tron.log("Choice: " + str(choice)) return choice def survivalMode(board, spaceCount): choice = tron.optimizeSpaceAlgorithm.execute(board, spaceCount) tron.log("Choice: " + str(choice)) return choice def findLongestPathDirections(start, directions): longestDirections = directions if len(directions) > 1: maxpathlength = -1 longestDirections = [] for dir in directions: pathlength = 0 node = start while board.passable(board.rel(dir, node)): pathlength += 1 node = board.rel(dir, node) if pathlength == maxpathlength: longestDirections.append(dir) elif pathlength > maxpathlength: maxpathlength = pathlength longestDirections = [dir] return longestDirections # you do not need to modify this part for board in tron.Board.generate(): tron.move(which_move(board)) tron.log("Turn took: " + str(float(time.clock() - board.startTime)))