def getHeuristicFor(board): position_x, position_y = board.getCurrentPositions()[0] number = board.getCurrentUnitsNumber()[0] max_heuristic = 0 for position in board.humansPos: if (number >= board.humansPos[position]): heuristic = board.humansPos[position] / ( max(np.abs(position_x - position[0]), np.abs(position_y - position[1])) + 1) max_heuristic = max(max_heuristic, heuristic) #closest distance from ennemy + current_unit #print("heuristic value", max_heuristic + number) return max_heuristic + number
def getSmartAvailableMoves(board, size, split=False): ''' Orders the positions we can move to in a list, where the first one has the highest score It should be explored first during the Tree Search ''' originalPositions = board.getAvailableMoves(split) size = min(size, len(originalPositions)) scoreDict = {} # evaluate the score for each position for unit in board.getCurrentUnitsNumber(): for position in originalPositions: scoreDict[tuple(position)] = getAvailableMovesScore(board, position, unit) # return only the n best positions sortedDict = sorted(scoreDict, key = scoreDict.get, reverse = True) sortedList = list(map(list, sortedDict))[:size] return sortedList
def getHeuristic(board): #print('Board :', board.getBoard()) our_unit_nb = board.getCurrentUnitsNumber()[0] humans_pos = np.array(list(board.humansPos.keys()), dtype=(int, int)) humans_nb = np.array(list(board.humansPos.values()), dtype=int) #filter human position where we are not at least equal to them in number humans_pos = humans_pos[humans_nb <= our_unit_nb] humans_nb = humans_nb[humans_nb <= our_unit_nb] if len(humans_pos) > 0: positions_tile = np.tile(board.getCurrentPositions()[0], (len(humans_pos), 1)) #compute the distance with humans #print("positions_tile", positions_tile) #print("humans_pos", humans_pos) max_dist = np.max(np.abs(positions_tile - humans_pos), axis=1) max_heuristic_humans = humans_nb / (max_dist + 1) else: max_heuristic_humans = [0] #our heuristic is human heuristic + our current unit_nb return max(max_heuristic_humans) + our_unit_nb
def getSmarterHeuristic(board, heuristicHistory, Smart_score): """ Heuristic function """ hash = board.hash() if (hash in heuristicHistory): heuristic = heuristicHistory[hash] else: score = 0 # Store essential information our_position, our_unit_nb = board.getBiggestPosition() units_nb = board.getCurrentUnitsNumber() total_units_nb = board.getCurrentUnitsNumberSum() our_pos = board.getCurrentPositions() humans_pos = np.array(list(board.humansPos.keys()), dtype=(int, int)) humans_nb = np.array(list(board.humansPos.values()), dtype=int) total_humans_nb = np.sum(humans_nb) enemy_pos = np.array(board.getOpponentCurrentPositions(), dtype=(int, int)) enemy_nb = np.array(board.getOpponentUnitsNumber(), dtype=int) opponents_unit_nb = board.getOpponentUnitsNumberSum() distanceEnemies = [ np.max(np.abs(np.subtract(list(enemy), our_position))) for enemy in enemy_pos ] # distanceHumans = [np.max(np.abs(np.subtract(list(human_loc), our_position))) """ # Consider the case where there is no human left if total_humans_nb == 0: for dist, enemy_unit in zip(distanceEnemies, enemy_nb): if (enemy_unit < 1.5 * total_units_nb): score += 10000 / ((dist+1)*(enemy_unit)) else: score -= 10 /(dist+1) heuristic = score heuristicHistory[hash] = heuristic # consider distance of ennemy with our units --> if = 1, bad. else: """ # Consider eatable humans and proximity - does not deal with split yet potential_units = total_units_nb for humans_loc, human_unit in zip(humans_pos, humans_nb): dist = np.max(np.abs(np.subtract(humans_loc, our_position))) if (human_unit > potential_units): p = 0 elif (total_units_nb >= human_unit): p = 1 else: p = 2 / 3 distEH = min([ np.max(np.abs(np.subtract(list(enemy), humans_loc))) for enemy in enemy_pos ]) if ((distEH) / (dist + 1) <= 1 / 4): q = 0.5 elif (0.9 < (distEH + 1) / (dist + 1) and (distEH + 1) / (dist + 1) < 1.2): q = 1.2 else: q = 1 score += p * q * human_unit / (dist + 1) potential_units += human_unit # Consider ennemies for dist, enemy_unit in zip(distanceEnemies, enemy_nb): if (enemy_unit >= 1.5 * total_units_nb): score -= (enemy_unit - total_units_nb) / (dist + 1) # avoid elif (total_units_nb > 1.5 * enemy_unit): score += (total_units_nb - enemy_unit) / (dist + 1 ) # go towards else: score += 1 / (dist + 1) # if no humans left, go attack # consider distance of ennemy with our units --> if = 1, bad. # Compute heuristic greedy = 4 # how greedy we want our bot to be, meaning how much does it values the units gained within tree search # score is weighted by 1, Smart_score by 3.5. heuristic = score + Smart_score - greedy * opponents_unit_nb + greedy * total_units_nb heuristicHistory[hash] = heuristic return heuristic