def assign_move(square): # Select direction with best production/strength or most damage target, direction = max( ((neighbor, direction) for direction, neighbor in enumerate(game_map.neighbors(square)) if neighbor.owner != myID), default=(None, None), key=lambda t: heuristic(t[0])) # Attack if enough strength if (target != None) and (target.strength < square.strength): return Move(square, direction) # Keep producing if strength still too little if square.strength < 10 * square.production and square.strength < 50: return Move(square, STILL) # If not at border (around by allies) then transport strength to nearest border border = any(neighbor.owner != myID for neighbor in game_map.neighbors(square)) if (not border): return Move(square, nearest_enemy_direction(square)) # Wait until stronger than enemy else: return Move(square, STILL)
def get_move_before_settling(square): # Yes, it can occur oO if square.production == 0: if any(n.owner == myID for n in game_map.neighbors( s)): # We have already settle somewhere else return Move(square, STILL) return Move( square, max([(n, d) for d, n in enumerate(game_map.neighbors(square)) if n.strength <= square.strength], key=lambda t: t[0].production)[1]) # We have reached our objective if game_map.get_square(objective.x, objective.y).owner == myID: logger.log("Objective reached !") global get_move get_move = get_move_after_settling return get_move(square) direction = game_map.get_direction(square, objective) target = game_map.get_target(square, direction) if square.strength > 0 and (target.owner == myID or target.strength < square.strength): return Move(square, direction) return Move(square, STILL)
def get_move(x, y, gmap): # If on the border, hit the neighbour with the highest heuristic if gmap.border[x, y]: heur_vals = [gmap.heuristic[nx, ny] for (nx, ny) in gmap.nbrs[x, y]] ni = np.argmax(heur_vals) nx, ny = gmap.nbrs[x, y][ni] # ...if strong enough to capture it if gmap.strn[nx, ny] > gmap.strn[x, y]: return Move(x, y, 0) else: return Move(x, y, ni + 1) # Stay if not at least 5x stronger than the production value if gmap.strn[x, y] < (gmap.prod[x, y] * 5): return Move(x, y, 0) # Else find the closest border square dist_to_brdr = np.zeros_like(gmap.prod) dist_to_brdr.fill(BIGINT) dist_to_brdr[np.nonzero(gmap.border)] = \ gmap.dists[x, y][np.nonzero(gmap.border)] # ..and move towards it tx, ty = np.unravel_index(dist_to_brdr.argmin(), dist_to_brdr.shape) direction = gmap.path_towards(x, y, tx, ty) return Move(x, y, direction)
def assign_move(square): wait = False i, s = get_weakest(square) logging.info("i: " + str(i)) logging.info("s: " + str(s)) if (i != -1 and s < square.strength): return Move(square, i) elif (i != -1): wait = True ## for idx, n in enumerate(game_map.neighbors(square)): ## if(n.owner != myID and n.strength < square.strength): ## return Move(square, idx) ## elif(n.owner != myID): ## wait = True if (wait or square.strength < 35): return Move(square, STILL) else: return Move( square, get_direction( square, kill_smallest_enemy(square, enemies, enemy_size, enemy_squares)))
def assign_move(square): total = 0 #Full strength squares should head to nearest border if square.strength == 255: return Move(square, fnb(square)) #If low on territory and has medium strength, just go to nearest enemy (seek out and destroy) if territory < 40 and square.strength > square.production * 5: return Move(square, fne(square)) #Go through all neighbours for direction, neighbor in enumerate(game_map.neighbors(square)): c = True total += neighbor.strength if neighbor.owner != myID: #The square is not surrounded by its own team c = False ## if neighbor.owner != myID and neighbor.strength < square.strength: ## #If it is next to a square of an enemy, and it is stronger, it will take it ## ## return Move(square, direction) #If it is next to a neighbour and they are both relatively weak, try merge if neighbor.owner == myID and (square.strength < 40 and square.strength > 20) and (neighbor.strength < 40 and neighbor.strength > square.production): #remain still if the production is higher #make sure they do not waste too much: if neighbor.strength + square.strength >= 280: pass else: if square.production < neighbor.production: return Move(square, direction) else: return Move(square, STILL) #If it is next to an enemy, take the weakest enemy if c == False: return Move(square, fwe(square)) #If it is surrounded by weak neighbors of its own type, then stay still if c == True and total < square.production * 12 and square.strength < 200: return Move(square, STILL) #If production is low but strength is high (implies there are many expensive squares around) for direction, neighbor in enumerate(game_map.neighbors(square)): if square.strength > 80 and neighbor.production > 2 * square.production: return Move(square, direction) #Otherwise if the square is in its territory and quite strong, move towards nearest enemy preferably, or near border if c == True and square.strength > 40: if fne(square) == 12: return Move(square, fnb(square)) else: return Move(square, fne(square)) #If the square is weak, stay still return Move(square, STILL)
def attack_move(square, immediate_enemy_neighbors): strengths = [sq_dir[0].strength for sq_dir in immediate_enemy_neighbors] min_index = strengths.index(min(strengths)) if immediate_enemy_neighbors[min_index][0].strength + 1 < square.strength: return Move(square, immediate_enemy_neighbors[min_index] [1]) # Should be same as direction # TODO Think of overkill logic return Move(square, STILL)
def get_move(square): _, direction = next(((neighbor.strength, direction) for direction, neighbor in enumerate(game_map.neighbors(square)) if neighbor.owner != myID and neighbor.strength < square.strength), (None, None)) if direction is not None: return Move(square, direction) elif square.strength < square.production * 5: return Move(square, STILL) else: return Move(square, NORTH if random.random() > 0.5 else WEST)
def assign_move(square): for direction, neighbor in enumerate(game_map.neighbors(square)): if neighbor.owner != myID and neighbor.strength < square.strength: return Move(square, direction) if square.strength < 5 * square.production: return Move(square, STILL) else: return Move(square, random.choice((WEST, NORTH)))
def make_move(square): x, y, owner, strength, production = square if strength == 0: return Move(square, STILL) not_my_neighbors = [ neighbor for neighbor in game_map.neighbors(square, n=7) if not is_enemy(neighbor) and not is_neutral(neighbor) ] # Go Radially from origin location if enough if len(not_my_neighbors) == 0 and is_mature_to_start_moving_radially_out( strength): return Move(square, direction_from_to_square(game_map, origin_square, square)) close_range_enemy_neighbors = [ neighbor for neighbor in game_map.neighbors(square, n=7) if is_enemy(neighbor) ] if len(close_range_enemy_neighbors ) > 0 and is_mature_for_close_range_battle(strength): return Move( square, direction_from_to_square(game_map, square, close_range_enemy_neighbors[0])) immediate_enemy_neighbors = [ (neighbor, dir) for dir, neighbor in enumerate(game_map.neighbors(square)) if is_enemy(neighbor) and neighbor.production > 0 ] if len(immediate_enemy_neighbors) > 0: return attack_move(square, immediate_enemy_neighbors) immediate_neutral_neighbors = [ (neighbor, dir) for dir, neighbor in enumerate(game_map.neighbors(square)) if is_neutral(neighbor) and neighbor.production > 0 ] if len(immediate_neutral_neighbors) > 0: return expand_move(square, immediate_neutral_neighbors) close_range_neutral_neighbors = [ neighbor for neighbor in game_map.neighbors(square, n=7) if is_neutral(neighbor) ] if len(close_range_neutral_neighbors ) > 0 and is_mature_for_close_range_conquer(strength): best_neighbor = choose_best_neutral(close_range_neutral_neighbors, square) return Move(square, direction_from_to_square(game_map, square, best_neighbor)) return Move(square, STILL)
def expand_move(square, immediate_neutral_neighbors): immediate_neutral_neighbors = sorted( immediate_neutral_neighbors, key=lambda a: neutral_cell_score(a[0], square), reverse=True) # productions = [sq_dir[0].production for sq_dir in immediate_neutral_neighbors] # max_index = productions.index(max(productions)) # for neighbor in immediate_neutral_neighbors[:2]: if immediate_neutral_neighbors[0][0].strength < square.strength: return Move(square, immediate_neutral_neighbors[0][1]) return Move(square, STILL)
def assign_move(square): n_str = "" wait = False dir_, str_ = get_prod_ratio(square) if (dir_ != -1 and square.strength > str_): return Move(square, dir_) elif (dir_ != -1 and square.strength < str_): wait = True if (wait or square.strength < 20): return Move(square, STILL) else: return Move(square, random.choice((NORTH, WEST, SOUTH, EAST)))
def assign_move(square): border = False for direction, neighbor in enumerate(game_map.neighbors(square)): if neighbor.owner != myID: border = True if neighbor.strength < square.strength: return Move(square, direction) if square.strength < 5 * square.production or border == True: return Move(square, STILL) else: return Move(square, random.choice((NORTH, WEST)))
def assign_movec(square): direction = assign_move(square) target = game_map.get_target(square, direction) #Check that merging won't cause a large loss. If it does, wait. if target.owner == myID and target.strength + square.strength > 290: return Move(square, STILL) #Check that it's not trying to take a stronger square if target.owner != myID and target.strength > square.strength: return Move(square, STILL) return Move(square, direction)
def assign_move(square): n_str = "" wait = False for idx, n in enumerate(game_map.neighbors(square)): if (n.owner != myID and n.strength < square.strength): return Move(square, idx) elif (n.owner != myID): wait = True if (wait or square.strength < 10): return Move(square, STILL) else: return Move(square, get_direction(square, find_closest_non_friend(square)))
def get_move(square): _, direction = next(((neighbor.strength, direction) for direction, neighbor in enumerate(game_map.neighbors(square)) if neighbor.owner != myID and neighbor.strength < square.strength), (None, None)) if direction is not None: return Move(square, direction) elif square.strength < square.production * 5: return Move(square, STILL) border = any(neighbor.owner != myID for neighbor in game_map.neighbors(square)) if not border: return Move(square, find_nearest_enemy_direction(square)) else: #wait until we are strong enough to attack return Move(square, STILL)
def assign_move(square): border = False for direction, neighbor in enumerate(game_map.neighbors(square)): if neighbor.owner != myID: border = True if neighbor.strength < square.strength: return Move(square, direction) if square.strength < 5 * square.production or border == True: return Move(square, STILL) else: return Move(square, findNearestEnemyDirection(square))
def assign_move(square): if square.strength == 0: return Move(square, STILL) for direction, neighbor in enumerate(game_map.neighbors(square)): if neighbor.owner != myID and neighbor.strength < square.strength and neighbor.production > square.production: return Move(square, direction) if neighbor.owner != myID and neighbor.strength < square.strength and neighbor.production != 0: return Move(square, direction) if neighbor.owner == myID and neighbor.strength != 0 and square.strength <= 100 and neighbor.strength <= square.strength: return Move(square, random.choice((STILL, direction))) if square.strength >= 100: direction = NORTH max_distance = min(game_map.width, game_map.height) / 2 for d in (NORTH, EAST, SOUTH, WEST): distance = 0 current = square while current.owner == myID and distance < max_distance: distance += 1 current = game_map.get_target(current, d) if distance < max_distance: direction = d max_distance = distance return Move(square, direction) if square.strength < 3 * square.production: return Move(square, STILL) for direction, neighbor in enumerate(game_map.neighbors(square)): if neighbor.owner == myID and square.strength + square.production < neighbor.strength: return Move(square, direction) else: return Move(square, random.choice((STILL, NORTH)))
def assignMove(square): squareIsBorder = False for direction, neighbor in enumerate(game_map.neighbors(square)): if neighbor.owner != myID: squareIsBorder = True if neighbor.strength < square.strength: return Move(square, direction) if square.strength < 5 * square.production: return Move(square, STILL) elif not squareIsBorder: return Move(square, findNearestOther(square)) else: return Move(square, STILL)
def assign_move(square): target, direction = max(((neighbor, direction) for direction, neighbor in enumerate(game_map.neighbors(square)) if neighbor.owner != myID), default = (None, None), key = lambda x: heuristic(x[0])) if target is not None and target.strength < square.strength: return Move(square, direction) elif square.strength < square.production * 5: return Move(square, STILL) border = any(neighbor.owner != myID for neighbor in game_map.neighbors(square)) if not border: return Move(square, find_nearest_enemy_direction(square)) else: return Move(square, STILL)
def assign_move(self, i, j): my_strength = self.game.strength[i, j] for direction, address in enumerate(self.game.neighbours_address(i, j)): n_owner = self.game.owner[address[0], address[1]] n_strength = self.game.strength[address[0], address[1]] if n_owner != self.my_id and n_strength < my_strength: return Move(j, i, direction) if all(self.game.owners[address[0], address[1]] == self.my_id for address in self.game.neighbours_address(i, j)): return Move(j, i, random.choice((NORTH, WEST, SOUTH, EAST))) return Move(j, i, STILL)
def find_combo_move(gamemap, square, target, my_id, max_distance=10, exclude=set()): strength_so_far = 0 visited = set() prior = target goal_strength = target.strength combo_square = None combo_direction = None for num_distance in range(max_distance): neighbors = [ square for square in gamemap.neighbors(prior) if square.owner == my_id and square not in visited and square not in exclude ] if len(neighbors) == 0: break best = max(neighbors, key=lambda square: square.strength) visited.add(best) strength_so_far += best.strength if strength_so_far > goal_strength: combo_square = best combo_direction = get_relative_position(gamemap, best, prior) if gamemap.get_distance(square, combo_square) <= 1: return Move(combo_square, combo_direction) break prior = best strength_so_far += best.production
def get_move(square): target, direction = max(((neighbor, direction) for direction, neighbor in enumerate(game_map.neighbors(square)) if neighbor.owner != myID), default = (None, None), key = lambda t: t[0].production) if target is not None and target.strength < square.strength: return Move(square, direction) elif square.strength < square.production * 5: return Move(square, STILL) border = any(neighbor.owner != myID for neighbor in game_map.neighbors(square)) if not border: return Move(square, find_nearest_enemy_direction(square)) else: #wait until we are strong enough to attack return Move(square, STILL)
def assign_move(square): potential, _, best_d, target = min( (pf_map[neighbor] + (float('inf') if destinations[neighbor] + square.strength > 255 else 0), random.random(), direction, neighbor) for direction, neighbor in enumerate(game_map.neighbors( square))) # the random number breaks ties randomly staying_is_bad = (square.strength + square.production + destinations.get(square, 0)) > 255 if potential == float('inf'): if staying_is_bad: # all 5 destinations are bad, choose least bad _, direction, target = min( (square.strength + destinations.get(neighbor, 0) + (square.production if direction == 0 else 0), direction, neighbor) for direction, neighbor in enumerate( game_map.neighbors(square, include_self=True))) return Move(square, direction) else: # OK to just stay return Move(square, STILL) if not staying_is_bad and any( Move(neighbor, best_d) in moves for neighbor in game_map.neighbors( square)): #do not follow or mimic neighbors return Move(square, STILL) if not staying_is_bad and destinations[square] > 0: return Move(square, STILL) if staying_is_bad and any(destinations[neighbor] + square.strength < 256 for _, neighbor in originations[square]): return Move( square, min(originations[square], key=lambda tup: destinations[tup[1]])[0]) if staying_is_bad: return Move(square, best_d) if target.owner != myID: #an opponent -- actually can never be adjacent to opponent, it's always me or a "zero" owner square if (square.strength == 255) or (square.strength > target.strength): return Move(square, best_d) elif square.strength >= square.production * args.hold_until: #target square is friendly, and we are strong enough to move return Move(square, best_d) return Move(square, STILL)
def assign_move(square): border = False neighbors = list(enumerate(game_map.neighbors(square))) notMySquares = list(filter(notMe, neighbors)) if (notMySquares): notMySquaresSorted = sorted(notMySquares, key=lambda tup: tup[1].production, reverse=True) target = notMySquares[0] if (target != None and target[1].strength < square.strength): return Move(square, target[0]) if square.strength < 5 * square.production: return Move(square, STILL) else: return Move(square, findNearestEnemyDirection(square))
def assign_move(square): target, direction = max(((neighbor, direction) for direction, neighbor in enumerate(game_map.neighbors(square)) if neighbor.owner != myID), default = (None, None), key = lambda t: heuristic(t[0])) if (target != None) and (target.strength < square.strength): return Move(square, direction) elif square.strength < 5 * square.production: return Move(square, STILL) border = any(neighbor.owner != myID for neighbor in game_map.neighbors(square)) if (not border): return Move(square, nearest_enemy_direction(square)) # return Move(square, random.choice((NORTH, WEST))) else: return Move(square, STILL)
def createMove(gameMap, location, site, myX, myY): # logFile.write("\nmove (" + str(location.x) + ", " + str(location.y) + ").\t") # logFile.write(xYToString(*distanceToCenter(location, myX, myY))) # logFile.write("moveAwayFromCenterUsingDistance:" + MOVES_STRINGS[moveAwayFromCenterUsingDistance(location, myX, myY, *distanceToCenter(location, myX, myY))]) # for d in CARDINALS: # neighbour_site = gameMap.getSite(location, d) # if neighbour_site.owner != myID and neighbour_site.strength < site.strength: # return Move(location, d) if site.strength < site.production * 5: return Move(location, STILL) # moveAwayFromCenter = getMoveAwayFromCenter(location, myX, myY) moveAwayFromCenter = moveAwayFromCenterUsingDistance( location, myX, myY, *distanceToCenter(location, myX, myY)) targetSite = gameMap.getSite(location, moveAwayFromCenter) if targetSite.strength < site.strength: return Move(location, moveAwayFromCenter) return Move(location, STILL)
def assign_move(square): border = False neighbors = list(enumerate(game_map.neighbors(square))) notMySquares = list(filter(notMe, neighbors)) if (notMySquares): border = True notMySquaresSorted = sorted(notMySquares, key=heuristic, reverse=True) target = notMySquares[0] if (target[1].strength < square.strength): return Move(square, target[0]) if square.strength < square.production * 5: return Move(square, STILL) if border == False: return Move(square, findNearestEnemyDirection(square)) return Move(square, STILL)
def setDirections(PARAMS, moves): for squareID, mySquaresDict in PARAMS.allMySquares.items(): sq = mySquaresDict['currentsquare'] direction = mySquaresDict['direction'] moves.append(Move(sq, direction)) #####For 1 line # return [Move(mySquaresDict['currentsquare'], mySquaresDict['direction']) for squareID, mySquaresDict in PARAMS.allMySquares.items()] return moves
def assign_move(square): border = False ###On Border, Can I Win? for direction, neighbor in enumerate(game_map.neighbors(square)): if neighbor.owner != myID: border = True if neighbor.strength < square.strength: return Move(square, direction) ###Not enough power, build it. if square.strength < 5 * square.production: return Move(square, STILL) ###Not on border, advance territory. if border == False: return Move(square, random.choice((NORTH, WEST))) #On Border, but can't win. Hold position. return Move(square, STILL)
def assign_move(square): sides = (WEST, EAST) tb = (NORTH, SOUTH) c = True svind = 5 #Check if it is on the edge of mass for direction, neighbor in enumerate(game_map.neighbors(square)): if neighbor.owner != myID: c = False for direction, neighbor in enumerate(game_map.neighbors(square)): #If too big if square.strength == 255: return Move(square, fnb(square)) #If I can take it w some left over if neighbor.owner != myID and neighbor.strength + 10 < square.strength: return Move(square, direction) #If I am a better factory if square.strength > square.production * svind: return Move(square, fnb(square)) return Move(square, STILL)