def getGradVicinity(self, gameState): ''' Returns a number indicating if we are moving away from the body of the snake or towards it. We calculate the negated inverse of the Manhattan distance of all points we are moving towards ''' if self.X_MAX is None: self.X_MAX = gameState.numXCell - 1 self.Y_MAX = gameState.numYCell - 1 XY_MAX = (self.X_MAX, self.Y_MAX) direction = gameState.getCurrentDirection() snakePos = gameState.getSnakeHeadCordinate() allPos = gameState.getSnakeCordinates() allPos.remove(snakePos) ret = 0.0 sX, sY = snakePos for pos in allPos: x, y = pos if direction == GameState.ACTION_RIGHT: if x > sX: md = manhattanDistance((x, y), (sX, sY)) ret += 1 / md else: md = circularManhattanDistance(snakePos, pos, XY_MAX, GameState.ACTION_RIGHT) ret += 1 / md elif direction == GameState.ACTION_LEFT: if x < sX: md = manhattanDistance((x, y), (sX, sY)) ret += 1 / md else: md = circularManhattanDistance(snakePos, pos, XY_MAX, GameState.ACTION_LEFT) ret += 1 / md elif direction == GameState.ACTION_UP: if y < sY: md = manhattanDistance((x, y), (sX, sY)) ret += 1 / md else: md = circularManhattanDistance(snakePos, pos, XY_MAX, GameState.ACTION_UP) ret += 1 / md else: if y > sY: md = manhattanDistance((x, y), (sX, sY)) ret += 1 / md else: md = circularManhattanDistance(snakePos, pos, XY_MAX, GameState.ACTION_DOWN) ret += 1 / md return ret
def getMinCircularManhattanDistance(self, gameState): ''' Returns the minimum circular manhattan distance. Where circular is defined as a motion through the ends of the grid (borders of the gird) ''' md = [] foodPos = gameState.getFoodCordinate() if None in foodPos: return None snakePos = gameState.getSnakeHeadCordinate() temp = manhattanDistance(snakePos, foodPos) md.append(temp) if self.X_MAX is None: self.X_MAX = gameState.numXCell - 1 self.Y_MAX = gameState.numYCell - 1 XY_MAX = (self.X_MAX, self.Y_MAX) # Moving Up md.append( circularManhattanDistance(snakePos, foodPos, XY_MAX, GameState.ACTION_UP)) # Moving into lower border md.append( circularManhattanDistance(snakePos, foodPos, XY_MAX, GameState.ACTION_DOWN)) # Moving into left border md.append( circularManhattanDistance(snakePos, foodPos, XY_MAX, GameState.ACTION_LEFT)) # Moving into right border md.append( circularManhattanDistance(snakePos, foodPos, XY_MAX, GameState.ACTION_RIGHT)) return min(md)
def getFeatures(self, gameState, action): # We don't want new food as we want to detect # if the snake ate the food successorGameState = gameState.generateSuccessor(action, newFood=False) foodPos = successorGameState.getFoodCordinate() if None in foodPos: return {self.FOOD_VICINITY: 2.0} snakePos = successorGameState.getSnakeHeadCordinate() from dlsnake.base.util import manhattanDistance foodVicinityFactor = manhattanDistance(foodPos, snakePos) foodVicinityFactor = 1 / foodVicinityFactor return {self.FOOD_VICINITY: foodVicinityFactor}
def getNextFoodCordinates(self, gameState): ''' Returns None if no food is possible ''' msg = 'FoodAgent.getNextFoodCordinates called even when ' msg += 'food is already present!' # Make sure we are only called when there is no food assert None in gameState.getFoodCordinate(), msg if self.X_MAX is None: self.X_MAX = gameState.numXCell self.X_MIN = 0 self.Y_MAX = gameState.numYCell self.Y_MIN = 0 self.__makeCornerCordinates() # Make sure you can fetch a new food totalCells = gameState.numXCell * gameState.numYCell snakeCells = len(gameState.getSnakeCordinates()) if totalCells - snakeCells < 1: return None, None # find which corner the snake head is in # and select the opposite corner # if invalid: # diagonally work for 5 moves # if still invalid: # select randomly and return head = gameState.snake.getHead() corners = self.corners distances = [manhattanDistance(head, corner) for corner in corners] maxIndex = distances.index(max(distances)) foodCords = corners[maxIndex] validFood = self._FoodAgent__isValidFood(foodCords, gameState) if validFood: return foodCords # The corner is occupied fx, fy = foodCords i = 0 while not validFood and i < 5: fx, fy = self.__getDiagonallyNext(fx, fy) validFood = self._FoodAgent__isValidFood((fx, fy), gameState) i += 1 if validFood: return fx, fy while not validFood: fx, fy = self._FoodAgent__randomFood() validFood = self._FoodAgent__isValidFood((fx, fy), gameState) return fx, fy
def getFeatures(self, gameState, action): # We don't want new food as we want to detect # if the snake ate the food successorGameState = gameState.generateSuccessor(action, newFood=False) foodPos = successorGameState.getFoodCordinate() if None in foodPos: foodVicinityFactor = 2.0 else: snakePos = successorGameState.getSnakeHeadCordinate() from dlsnake.base.util import manhattanDistance foodVicinityFactor = manhattanDistance(foodPos, snakePos) foodVicinityFactor = 1 / foodVicinityFactor # Factor in the number of cells of the neighbor that # are parts of the snake. neighborCellCords = self.__getNeighborCellCords(successorGameState) snakeCords = gameState.getSnakeCordinates() oneNearestFactor = 0.0 newHead = successorGameState.getSnakeHeadCordinate() # Detects if the new game state results in a crash neighborCellCords.append(newHead) for p in neighborCellCords: if p in snakeCords: oneNearestFactor -= 1.0 # How much score did we loose/gain (-1 to 1) oldScore = gameState.score newScore = successorGameState.score scoreLostFactor = (newScore - oldScore) # Can happen if gameOVer if scoreLostFactor != 0: scoreLostFactor = 1 / scoreLostFactor # Length Factor length = len(successorGameState.getSnakeCordinates()) length = 1 / length comb = length * oneNearestFactor return { self.FOOD_VICINITY: foodVicinityFactor # self.ONE_NEAREST_NEIGHBOURS: oneNearestFactor, # self.SCORE_LOST: scoreLostFactor, # self.LENGTH: length, # self.COMB_LENGTH_NEIGHBOUR: comb }
def evaluationFunction(self, gameState): """ A simple evaluation function """ msg = "No food in current game state! Did you call the evaluation " msg += "function in the correct order?" assert None not in gameState.getFoodCordinate(), msg value = 0.0 foodCord = gameState.getFoodCordinate() snakePos = gameState.getSnakeHeadCordinate() from dlsnake.base.util import manhattanDistance foodVicinityFactor = 0 if None not in foodCord: foodVicinityFactor = manhattanDistance(snakePos, foodCord) if foodVicinityFactor != 0: value += 1.0 / foodVicinityFactor else: value += 1.0 scoreFactor = 0.1 * gameState.getScore() value += scoreFactor # We don't obviously want to die if gameState.gameOver: value -= 10 return value
def evaluationFunction(self, currentGameState, action): """ A simple evaluation function """ successorGameState = currentGameState.generateSuccessor(action) value = 0.0 newFood = successorGameState.getFoodCordinate() newPos = successorGameState.getSnakeHeadCordinate() newScore = successorGameState.getScore() oldScore = currentGameState.getScore() from dlsnake.base.util import manhattanDistance foodVicinityFactor = manhattanDistance(newPos, newFood) scoreFactor = newScore - oldScore if foodVicinityFactor != 0: value += 1.0 / foodVicinityFactor else: value += 1.0 if scoreFactor != 0: value += scoreFactor # We don't obviously want to die if successorGameState.gameOver: value -= 10 return value