예제 #1
0
    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))
예제 #2
0
    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
예제 #3
0
 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)
예제 #4
0
    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
예제 #5
0
    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
예제 #6
0
 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