def pre_game_calc(self, game_map: Map, your_units: Units) -> None: # workers = your_units.get_all_unit_of_type('worker') melees = your_units.get_all_unit_of_type('melee') resource_nodes = game_map.find_all_resources() column = len(game_map.grid[0]) row = len(game_map.grid) print("MAP SIZE: {0} x {1}".format(column, row)) enemy_distance = [] for m in melees: enemy_coord = (abs(column - m.x), abs(row - m.y)) enemy_distance.append( len(game_map.bfs(enemy_coord, resource_nodes[0])) - 1) self.set_safety(min(enemy_distance))
def tick(self) -> None: try: size = int(self.safe_recv(10).decode()) response = self.safe_recv(size).decode() js = json.loads(response) moves = self.player.tick(Map(js['map']), Units(js['my_units']), Units(js['their_units']), js['my_resources'], js['turns_left']) data = [] for move in moves: if isinstance(move, Move): data.append(move.to_tuple()) else: print('Expected type Move but got {}'.format(type(move))) body = json.dumps(data).encode() self.conn.sendall('{:10}'.format(len(body)).encode()) self.conn.sendall(body) return True except SocketClosed: return False
def left(map: Map, unit: Unit, myUnits: Units, enemyUnits: Units, resourceCount: int, turnsLeft: int, resources: List, paths: Dict, foodPaths: Dict, ongoingGoal: Dict, bfs) -> int: nearbyWorkers, nearbyWarriors, nearbyEnemyWorkers, nearbyEnemyWarriors = unitsInFOV( unit, myUnits, enemyUnits) newPos = (unit.position()[0] - 1, unit.position()[1]) if not (len(nearbyEnemyWarriors) + len(nearbyEnemyWorkers)): if unit.id in ongoingGoal: myDist = bfs(ongoingGoal[unit.id], newPos) if myDist < 4 or myDist > 100: del ongoingGoal[unit.id] return 100 else: return myDist else: allPlaces = map.find_all_resources() randomMine = allPlaces[random.randint(0, len(allPlaces) - 1)] ongoingGoal[unit.id] = randomMine return bfs(randomMine, newPos) else: if len(nearbyEnemyWarriors): # assume the closest baddie for now, should be smarter tho return -20 + bfs( nearbyEnemyWarriors[0], newPos) + 30 * (bfs(nearbyEnemyWarriors[0], newPos) % 2) else: return -20 + bfs(nearbyEnemyWorkers[0], newPos)
def tick(self, game_map: Map, your_units: Units, enemy_units: Units, resources: int, turns_left: int) -> [Move]: # init calls def hasBlock(pos): for id in your_units.get_all_unit_ids(): if your_units.get_unit(id).position() == pos: return True for id in enemy_units.get_all_unit_ids(): if enemy_units.get_unit(id).position() == pos: return True return False def bfsDistance(p1, p2): if (p1, p2) in self.pathWeights and not hasBlock(p1): return self.pathWeights[(p1, p2)] elif (p2, p1) in self.pathWeights and not hasBlock(p2): return self.pathWeights[(p2, p1)] else: path = game_map.bfs(p1, p2) if path == None: return 0 if distance(p1, p2) == 0 else 100000 for i in range(len(path)): self.pathWeights[(path[i], p2)] = len(path) - i return len(path) if not len(self.resources): self.resources = game_map.find_all_resources() workers = your_units.get_all_unit_of_type('worker') moves = [] for worker in workers: moveValues = [] for action in self.validMoves(worker, game_map, resources, enemy_units): moveValues.append((evalFnsWorker[action]( game_map, worker, your_units, enemy_units, resources, turns_left, self.resources, self.pathWeights, self.foodPaths, self.alreadySpawning, self.pathingMem, bfsDistance), actionToMove[action](worker))) moves.append( sorted(moveValues, key=lambda x: x[0], reverse=True).pop()[1]) warriors = your_units.get_all_unit_of_type('melee') for warrior in warriors: moveValues = [] for action in self.validMoves(warrior, game_map, resources, enemy_units): moveValues.append( (evalFnsWarrior[action](game_map, warrior, your_units, enemy_units, resources, turns_left, self.resources, self.pathWeights, self.foodPaths, self.pathingMem, bfsDistance), actionToMoveWarrior[action]( warrior, warrior.can_attack(enemy_units)))) moves.append( sorted(moveValues, key=lambda x: x[0], reverse=True).pop()[1]) return moves
def tick(self, game_map: Map, your_units: Units, enemy_units: Units, resources: int, turns_left: int) -> [Move]: print("\n--------RESOURCES: {0} | TURNS LEFT: {1}--------".format( resources, turns_left)) if turns_left == 100: # Pre-game calculations. self.pre_game_calc(game_map, your_units) workers = your_units.get_all_unit_of_type('worker') melees = your_units.get_all_unit_of_type('melee') moves = [] resource_nodes = game_map.find_all_resources() asymmetrical_node = resource_nodes[(len(resource_nodes) // 2)] print(self.safe_turns) print(resource_nodes, asymmetrical_node) for unit in workers: if unit.can_mine(game_map): moves.append(unit.mine()) else: closest_node = game_map.closest_resources(unit) s_path = game_map.bfs(unit.position(), closest_node) if s_path: moves.append(unit.move_towards(s_path[1])) for unit in melees: enemy_list = unit.nearby_enemies_by_distance(enemy_units) if enemy_list: attack_list = unit.can_attack(enemy_units) if attack_list: moves.append(unit.attack(attack_list[0][1])) else: closest = enemy_units.units[enemy_list[0][0]] moves.append(unit.move_towards((closest.x, closest.y))) elif unit.can_duplicate(resources): moves.append(unit.duplicate('LEFT')) else: moves.append(unit.move('DOWN')) return moves
def validMoves(self, unit: Unit, map: Map, resources: int, enemies: Units) -> List: validActions = [] for dir in DIRECTIONS: newCoord = (unit.position()[0] + DIRECTIONS[dir][0], unit.position()[1] + DIRECTIONS[dir][1]) if not map.is_wall(*newCoord): validActions.append(dir) if len(unit.can_attack(enemies)): validActions.append(Action.ATK) if unit.can_mine(map) and unit.type == 'worker': validActions.append(Action.MINE) if unit.can_duplicate(resources, 'worker'): validActions.append(Action.BREED_WORKER) if unit.can_duplicate(resources, 'melee'): validActions.append(Action.BREED_WARRIOR) if len(unit.can_stun(enemies)): validActions.append(Action.STUN) return validActions