def getOrderedScore(position, board): ''' position refers to one of the potential new positions we could occupy in the next round give bonuses to each position wrt to our ability to eat humans/ennemies in a close future ''' bonus = 0 my_unit = board.getBiggestPosition()[1] # first type of bonus - if we eat enemies if (tuple(position) in board.getOpponentCurrentPositions()): if board.getOpponentDict()[tuple(position)] <= board.getBiggestPosition()[1]: bonus += 1000 * board.getOpponentDict()[tuple(position)] # second type - if we eat humans if (tuple(position) in board.humansPos): if board.humansPos[tuple(position)] <= board.getBiggestPosition()[1]: bonus += 100 * board.humansPos[tuple(position)] # third type of bonus : we get closer to possibly eatable humans or enemies eatable = [k for k, v in board.humansPos.items() if my_unit >= v] + [k for k, v in board.getOpponentDict().items() if my_unit >= 1.5 * v] if len(eatable) > 0: maxDistance = max(board.board_w, board.board_h) maxNumber = board.getOpponentUnitsNumberSum() + sum(list(board.humansPos.values())) distance = [10 - 9 * np.max(np.abs(np.subtract(list(enemy), position))) / maxDistance for enemy in eatable] number = [9 * unit / maxNumber for unit in board.humansPos.values() if my_unit >= unit] + [9 * unit / maxNumber for unit in board.getOpponentUnitsNumber() if my_unit >= 1.5 * unit] combined = [10 * dist + num for dist, num in zip(distance, number)] bonus += (maxDistance - np.min(combined)) return bonus
def getSmarterAvailableMoves(board, size, split=False): ''' attributes a score to each potential move we can make This score takes into an up-to-date number of humans as we will move across the map and the ennemies deals with the split Returns a dictionnary sorted by score (value), where the key is the position investigated ''' Positions = board.getAvailableMoves(split) size = min(size, len(Positions)) # how many positions we return scoreDict = {} unit = board.getBiggestPosition()[1] # for split, do a loop for position in Positions: # loop through possible positions (for one unit) score = 0 # if humans are on our next potential position if (tuple(position) in board.humansPos): if (board.humansPos[tuple(position)] > unit): # don't want to go if they are more than us score = -100 else: score += 50 + 5 * board.humansPos[tuple( position)] # give incentive to go eat asap # if ennemy are on our next potential position if (tuple(position) in board.getOpponentDict()): if (board.getOpponentDict().get(tuple(position)) > 1.5 * unit): score -= 500 if (board.getOpponentDict().get(tuple(position)) > unit): score += 10 else: score += 500 # Compute key metrics about us # distanceHumans = [np.max(np.abs(np.subtract(list(human), position))) for human in board.humansPos] distanceEnemies = [ np.max(np.abs(np.subtract(list(enemy), position))) for enemy in board.getOpponentDict() ] total_units_nb = board.getCurrentUnitsNumberSum() potential_units = unit # Call function - takes into account potential number of units and distance to ennemies score = board.PotentialUnits(score, position, potential_units) # Study eatable ennemies and proximity weight_dist = 5 for dist, enemy_unit in zip(distanceEnemies, board.getOpponentDict().values()): if (enemy_unit >= 1.5 * total_units_nb): score -= (enemy_unit - total_units_nb) / weight_dist * ( dist + 1) # avoid elif (total_units_nb > 1.5 * enemy_unit): score += (total_units_nb - enemy_unit) / weight_dist * ( dist + 1) # go towards else: score += 1 / weight_dist * (dist + 1 ) # if no humans left, go attack scoreDict[tuple(position)] = score sortedDict = dict( sorted(scoreDict.items(), key=lambda kv: kv[1], reverse=True)[:size]) # dico with value=score, key:position #sortedScores = sorted(scoreDict.values(), reverse=True)[:size] # sortedPos = sorted(scoreDict, key=scoreDict.get, reverse=True)[:4] # sort the dictionnary by score # sortedList = list(map(list, sortedDict))[:4] # list best potential positions, by order in format [[i,j],...] return sortedDict
def getAvailableMovesScore(board, position, unit): ''' compute a score that defines how desirable each position is given how many units you can eat for certain and when (time - dist) ''' eatableOpponents = [k for k in board.humansPos if unit >= board.humansPos[k]] + [k for k in board.getOpponentDict() if unit >= 1.5*board.getOpponentDict()[k]] number = [u for u in board.humansPos.values() if unit >= u] + [u for u in board.getOpponentUnitsNumber() if unit >= 1.5 * u] distance = [np.max(np.abs(np.subtract(list(enemy), position))) for enemy in eatableOpponents] score = np.sum([n/(d+1) for n, d in zip(number, distance)]) return score