def find_best_moves(self, current_board): ''' From a given board, evaluate all the missions in mission list And for all the mission, generate all the outputs for this mission and make a first clean ''' print "\n"+"-"*120+"\nStuxnet::find_best_moves" # Receiver for all the alternatives we may find all_positions = [] print 'find_best_moves - current_board', current_board all_positions.extend(current_board.our_positions()) all_positions.extend(current_board.human_positions()) all_positions.extend(current_board.ennemy_positions()) alternatives = [] fmt="%11s%12s%10s%13s%13s%15s%14s" print fmt % ('coord_start', 'coord_goal', 'distance', 'target_type', 'board_score', 'mission_score', 'mission_type') # Let's go throught all possibilites ! for our_position in current_board.our_positions(): for other_position in all_positions: # Let's consider the distincts cases if other_position.coord != our_position.coord: for mission in self.mission_list: # We should not try not attack our_positions if self.is_mission_compliant(other_position.kind, mission): target_board, next_order, delta_our = self.compute_mission_result(current_board, mission, our_position, other_position) if target_board.score() > 0: mission_score = float(target_board.score()/(computeMinDistance(our_position.coord, other_position.coord)**2)) * delta_our else: if delta_our > 0: mission_score = float(target_board.score())*(computeMinDistance(our_position.coord, other_position.coord)**2)/ delta_our else: mission_score = float(target_board.score()*(computeMinDistance(our_position.coord, other_position.coord)**2))*abs(delta_our) print fmt % (our_position.coord, other_position.coord, computeMinDistance(our_position.coord, other_position.coord), other_position.kind, round(target_board.score(),1), round(mission_score,1),mission) alternatives.append((target_board, next_order, mission_score,other_position.coord,other_position.kind)) print "-"*120 # Sort the list based on the score alternatives = sorted(alternatives, key=itemgetter(2), reverse=True) alternatives = self.alternatives_same_target_clean(alternatives) orders = self.generate_move(alternatives, current_board) print 'find_best_moves - orders', orders result = [] for order in orders: order_to_send = self.generate_order_format(order) target_board = self.generate_target_board(order, current_board) #target_board = self.generate_next_board(order, current_board) result.append([order_to_send, target_board]) print 'find_best_moves - order_to_send', order_to_send print 'find_best_moves - target_board', target_board return result
def compute_mission_result(self, current_board, mission, our_position, other_position): ''' From the current board, the mission and the 2 considered elements compute the targeted board and the next order ''' #print "\n"+"#"*50+"\nStuxnet::compute_mission_result" new_board = copy.deepcopy(current_board) next_order = [] delta_our = 0.0 if mission == 'attack': # Remove our position from the board del new_board.grid[our_position.coord] # Remove their position from the board del new_board.grid[other_position.coord] # Add our team on the ennemy position if other_position.kind == 'h': if our_position.number >= other_position.number: new_board.grid[other_position.coord] = (our_position.kind, our_position.number + other_position.number) delta_our = float(other_position.number) else: # We will die new_board.grid[other_position.coord] = (other_position.kind, other_position.number) delta_our = float(-our_position.number) # Send the same number of human is enough number_needed = int(other_position.number) elif other_position.kind == self.other_kind: if our_position.number >= other_position.number: if our_position.number >= int(1.5 * other_position.number) + 1: # Use the probability given by the pdf to compute the estimate survivors new_board.grid[other_position.coord] = (our_position.kind, our_position.number) delta_our = 1.0 else: new_board.grid[other_position.coord] = (our_position.kind, float((2.0/3)*our_position.number)) delta_our = float((1.0/3)*our_position.number) else: if other_position.number >= 1.5 * our_position.number: new_board.grid[other_position.coord] = (other_position.kind, other_position.number) delta_our = float(-our_position.number) else: new_board.grid[other_position.coord] = (other_position.kind, float(other_position.number - (2.0/3)*our_position.number)) delta_our = float(-our_position.number) # We should send at least 1.5 time the number of ennemies number_needed = int(1.5 * other_position.number) + 1 elif other_position.kind == self.our_kind: new_board.grid[other_position.coord] = (our_position.kind, our_position.number + other_position.number) number_needed = our_position.number if other_position.number > our_position.number: delta_our = max(min(float(3*config.nb_of_h_positions_at_start/(current_board.x_max * current_board.y_max)),1),0) # test needed else: delta_our = 0.0 else: number_needed = 0 print "'number_needed = 0' -> That should not happen :/" number_sent = min(number_needed, our_position.number) next_coord = findNextMove(our_position.coord, other_position.coord) if computeMinDistance(our_position.coord, other_position.coord) == 1: next_order = ['MOV', 1, our_position.coord[0], our_position.coord[1], number_sent, next_coord[0], next_coord[1]] else: next_coord_optimized = self.optimize_next_move(current_board, our_position, other_position, next_coord) next_order = ['MOV', 1, our_position.coord[0], our_position.coord[1], number_sent, next_coord_optimized[0], next_coord_optimized[1]] elif mission == 'escape' : # maybe add 'and self.our_number() > ennemies around' # Remove our position from the board del new_board.grid[our_position.coord] # Compute the 8 possible positions minus out-of-board positions escape_scope = {} x_range=[i for i in range(config.Xsize)] y_range=[i for i in range(config.Ysize)] if (our_position.x-1) in x_range and (our_position.y-1) in y_range : escape_scope[(our_position.x-1,our_position.y-1)] = [] if (our_position.x) in x_range and (our_position.y-1) in y_range : escape_scope[(our_position.x,our_position.y-1)]= [] if (our_position.x+1) in x_range and (our_position.y-1) in y_range : escape_scope[(our_position.x+1,our_position.y-1)]= [] if (our_position.x+1) in x_range and (our_position.y) in y_range : escape_scope[(our_position.x+1,our_position.y)]= [] if (our_position.x+1) in x_range and (our_position.y+1) in y_range : escape_scope[(our_position.x+1,our_position.y+1)]= [] if (our_position.x) in x_range and (our_position.y+1) in y_range : escape_scope[(our_position.x,our_position.y+1)]= [] if (our_position.x-1) in x_range and (our_position.y+1) in y_range : escape_scope[(our_position.x-1,our_position.y+1)]= [] if (our_position.x-1) in x_range and (our_position.y) in y_range : escape_scope[(our_position.x-1,our_position.y)]= [] # add distance to ennemy for position in escape_scope.keys(): escape_scope[position].append(computeMinDistance(position, other_position.coord)) # create list of friends' positions our_other_positions=[position.coord for position in current_board.our_positions()] #print our_other_positions our_other_positions.remove(our_position.coord) #print our_other_positions # determine distance to closest friend and add it to escape scope for position in escape_scope.keys(): dist = float('inf') for our_other_position in our_other_positions: if computeMinDistance(position,our_other_position) < dist: dist = computeMinDistance(position,our_other_position) escape_scope[position].append(100.0/(1+dist)) #to sort in te right order, see below # Compute escape position by sorting escape_scope by ennemy_distance and then by friend_distance (dic is flattened in the process) -> the escape coord selected is the furthest from the ennemy, the closest from a friend escape_coord = sorted(([k]+v for k,v in escape_scope.iteritems()), key=itemgetter(1,2), reverse=True)[0][0] # sorted -> [(x,y),ennemy_distance, friend_distance] sorted by ennemy_distance and then by 100/(1+friend_distance), from biggest to smallest # Add our team on the escape position on new_board new_board.grid[escape_coord] = (our_position.kind, our_position.number) # set next order: next_order = ['MOV', 1, our_position.coord[0], our_position.coord[1], our_position.number, escape_coord[0], escape_coord[1]] print "generated escape_coord", escape_coord print "ennemy position: ", other_position.coord # set delta_our if other_position.kind == config.eux: delta_our = 1.0 #to be checked !!!!!!!!!!! else: delta_our = 0.0 else: pass return new_board, next_order, delta_our