Exemplo n.º 1
0
 def __init__(self):
     """
     Initializing the Simulator
     """
     self.world = World()
     self.mdp = []
     self.replay = Replay(self.world.maze, self.world.agents, self.world.get_agents_position())
     self.launch_replay = False
     self.stats = Statistics(len(self.world.agents), len(self.world.adversaries))
     self.distances = []
     self.end = False
     self.coordination = True
Exemplo n.º 2
0
 def __init__(self, world: World):
     self.me = world.get_my_player().id
     self.opponent = world.get_opponent_player().id
     self.by_player = defaultdict(lambda: set())
     self.by_type = defaultdict(lambda: set())
     self.by_group = defaultdict(lambda: set())
     self.updated = set()
     self.damaged = set()
     TaggedDict.__init__(self, world.new_vehicles)
     for i in world.new_vehicles:
         self.by_player.setdefault(i.player_id, set()).add(i.id)
         self.by_type.setdefault(i.type, set()).add(i.id)
         self.updated.add(i.id)
Exemplo n.º 3
0
 def __init__(self, world: World):
     self.allies = set()
     self.hostiles = set()
     self.neutral = set()
     self.by_type = dict()
     self.by_type[FacilityType.CONTROL_CENTER] = set()
     self.by_type[FacilityType.VEHICLE_FACTORY] = set()
     TaggedDict.__init__(self, world.facilities)
     self.me = world.get_my_player().id
     self.opponent = world.get_opponent_player().id
     for i in world.facilities:
         (i.owner_player_id == self.me and self.allies
          or i.owner_player_id == self.opponent and self.hostiles
          or self.neutral).add(i.id)
         self.by_type[i.type].add(i.id)
Exemplo n.º 4
0
    def __init__(self):
        self.world = World(10)
        self.gridWidth = 15
        self.gridHeight = 20
        self.playerSize = 0.5

        self.speed = 0.03
        self.killLine = -0.1

        self.platforms = [Platform(PhysicsVector(0, 0, 0), PhysicsVector(gridWidth, 0, 0))]

        self.minPlatformWidth = 1.0
        self.maxPlatformWidth = 6.0
        self.maxPlatformGaps = 8.0
        self.probabilityOfNoPlatforms = 0.2
        self.gapProbability = 0.8

        self.lastLevelGenerated = 0

        self.skipped = 0
        self.maxConsecutiveSkips = 2

        self.player = Player(
            PhysicsVector(self.gridWidth / 3.0, 0, self.gridHeight / 2.0),
            PhysicsVector(0, 0, 0)
        )
        self.world.objects = [self.player]

        self.generateUntilLevel(int(self.gridHeight) - 5)
Exemplo n.º 5
0
    def read_world(self):
        if not self.read_boolean():
            return None

        return World(self.read_int(), self.read_int(), self.read_double(),
                     self.read_double(), self.read_players(),
                     self.read_hockeyists(), self.read_puck())
Exemplo n.º 6
0
    def init_game(self, me: Car, world: World, game: Game):
        if not getattr(self, '_init_game', False):
            self.__class__._init_game = True

            Meta.game = game
            Meta.world = world
            world.waypoints_track = deque(map(Point, world.waypoints))
            LoggerData.print_map()

            # Step(Point(me), world.starting_direction)
            self.track = deque([(Point(me), world.starting_direction)])
            cost = t_map(self.track)

            LoggerData.print_map(self.track)
            LoggerData.print_track(self.track)

            assert len(self.track) > 0, 'Wrong initialize track'
            assert len(self.track) == cost, 'cost must be equal to len(track)'

            if not (set(map(tuple, world.waypoints)) <=
                    set(map(lambda s: (s[0].xi, s[0].yi), self.track))):
                print(f'Track: {self.track}')
                raise Exception('Not all waypoints contains in track')

            self.log_to_file1 = LoggerData(r'./results1.csv')
            self.log_to_file2 = LoggerData(r'./results2_keyboard.csv')
    def read_world(self):
        if not self.read_boolean():
            return None

        return World(self.read_int(), self.read_double(), self.read_double(),
                     self.read_players(), self.read_obstacles(),
                     self.read_tanks(), self.read_shells(),
                     self.read_bonuses())
Exemplo n.º 8
0
 def check_nuke(s: MyStrategy, w: World):
     enemy = w.get_opponent_player()
     if (enemy.next_nuclear_strike_vehicle_id > 0
             and not s.flags["nuke detected"]):
         s.current_action = actions + s.current_action
         s.flags["nuke detected"] = True
     elif s.flags[
             "nuke detected"] and enemy.next_nuclear_strike_vehicle_id <= 0:
         s.flags["nuke detected"] = False
Exemplo n.º 9
0
    def read_world(self):
        if not self.read_boolean():
            return None

        return World(
            self.read_int(), self.read_int(), self.read_double(), self.read_double(), self.read_players(),
            self.read_vehicles(), self.read_vehicle_updates(), self.read_terrain_by_cell_x_y(),
            self.read_weather_by_cell_x_y(), self.read_facilities()
        )
Exemplo n.º 10
0
    def read_world(self):
        if not self.read_boolean():
            return None

        return World(self.read_int(), self.read_int(), self.read_double(),
                     self.read_double(), self.read_players(),
                     self.read_wizards(), self.read_minions(),
                     self.read_projectiles(), self.read_bonuses(),
                     self.read_buildings(), self.read_trees())
Exemplo n.º 11
0
    def read_world(self):
        if not self.read_boolean():
            return None

        return World(self.read_int(), self.read_int(), self.read_int(),
                     self.read_int(), self.read_int(), self.read_players(),
                     self.read_cars(), self.read_projectiles(),
                     self.read_bonuses(), self.read_oil_slicks(),
                     self.read_map_name(), self.read_tiles_x_y(),
                     self.read_waypoints(), self.read_starting_direction())
Exemplo n.º 12
0
 def __comeback_after_strike(self, world: World):
     opponent = world.get_opponent_player()
     next_nuclear_strike_tick = opponent.next_nuclear_strike_tick_index
     if next_nuclear_strike_tick != -1:
         return False
     if not self.actionQueue.is_action_in_queue(ActionType.MOVE):
         self.actionQueue.push(Action.move(0, 0))
     else:
         self.actionQueue.clear()
     self._sos_mode = False
     return True
Exemplo n.º 13
0
    def read_world(self):
        if not self.read_boolean():
            return None

        world = RemoteProcessClient.WORLD_STRUCT.unpack(self.read_bytes(24))

        return World(world[0], world[1], world[2], world[3],
                     self.read_players(), self.read_vehicles(),
                     self.read_vehicle_updates(),
                     self.read_terrain_by_cell_x_y(),
                     self.read_weather_by_cell_x_y(), self.read_facilities())
Exemplo n.º 14
0
    def read_world(self):
        if not self.read_boolean():
            return None

        byte_array = self.read_bytes(24)
        world = struct.unpack(
            RemoteProcessClient.BYTE_ORDER_FORMAT_STRING + "2i2d", byte_array)

        return World(world[0], world[1], world[2], world[3],
                     self.read_players(), self.read_vehicles(),
                     self.read_vehicle_updates(),
                     self.read_terrain_by_cell_x_y(),
                     self.read_weather_by_cell_x_y(), self.read_facilities())
Exemplo n.º 15
0
    def move(self, me: Player, world: World, game: Game, move: Move):
        en = world.get_opponent_player()
        self.update(me, en, world, game)

        if world.tick_index == 0:
            self.init()

        if me.remaining_action_cooldown_ticks > 0:
            return

        if self.execute_move_queue(move):
            return

        # formation
        if not self.aerial_form_done:
            self.do_aerial_formation()
        if not self.ground_form_done:
            self.do_ground_formation_2()
        if self.execute_move_queue(move):
            return

        # shrink
        if self.ground_form_done and self.aerial_form_done and not self.shrinking_done:
            self.do_shrinking()
        if self.execute_move_queue(move):
            return

        # evade nukes
        if self.aerial_form_done and self.ground_form_done:
            self.evade_nukes()
        if self.execute_move_queue(move):
            return

        #self.fix_formation()
        #if self.execute_move_queue(move):
        #    return

        # attack signature
        if (self.units_have_stopped(self.me, group=Group.AERIAL)
                and self.units_have_stopped(self.me, group=Group.GROUND)):
            if self.world_has_facilities:
                self.occupy_nearest_facility()
            else:
                self.attack_nearest_cluster_of_enemy()
        if self.execute_move_queue(move):
            return

        if self.can_nuke() and self.world.tick_index % 10 == 0:
            self.fire_nukes()
        self.execute_move_queue(move)
Exemplo n.º 16
0
    def test_updateWorld(self):
        physics = Physics()
        location = PhysicsVector(5, 0, 50)
        velocity = PhysicsVector(0, 0, 0)
        player = Player(location, velocity)
        world = World(5)
        dt = 3

        world.objects.append(player)

        physics.updateWorld(player, world, dt)

        self.assertTrue(player.velocity.x == 0)
        self.assertTrue(player.velocity.y == 0)
        self.assertTrue(player.velocity.z == -15)
Exemplo n.º 17
0
    def test_updateVelocity(self):
        physics = Physics()

        location = PhysicsVector(0, 0, 0)
        velocity = PhysicsVector(0, 0, 20)
        obj = PhysicalObject(location, velocity)
        world = World(5)
        dt = 3

        physics.updateVelocity(obj, world, dt)

        expected = PhysicsVector(0, 0, 5)

        self.assertEqual(obj.velocity.x, expected.x)
        self.assertEqual(obj.velocity.y, expected.y)
        self.assertEqual(obj.velocity.z, expected.z)
Exemplo n.º 18
0
    def move(self, me: Hockeyist, world: World, game: Game, move: Move):

        # self.me = me
        # self.world = world
        # self.game = game
        # self.me_move = move

        if me.state == HockeyistState.SWINGING:
            move.action = ActionType.STRIKE
            return

        if world.puck.owner_player_id == me.player_id:

            if world.puck.owner_hockeyist_id == me.id:

                opponent = world.get_opponent_player()

                net_x = 0.5 * (opponent.net_back + opponent.net_front)
                net_y = 0.5 * (opponent.net_bottom + opponent.net_top)

                angle_to_net = me.get_angle_to(net_x, net_y)
                move.turn = angle_to_net

                if abs(angle_to_net) < self.STRIKE_ANGLE:
                    move.action = ActionType.STRIKE

            else:

                nearest_opponent = self.get_nearest_opponent(me, world)

                if nearest_opponent is not None:

                    if me.get_distance_to_unit(nearest_opponent) > game.stick_length:
                        move.speed_up = 1
                    else:
                        move.action = ActionType.STRIKE

                    move.turn = me.get_angle_to_unit(nearest_opponent)

        else:
            move.speed_up = 1
            move.turn = me.get_angle_to_unit(world.puck)
            move.action = ActionType.TAKE_PUCK
Exemplo n.º 19
0
    def __save_our_souls(self, world: World):
        opponent = world.get_opponent_player()
        next_nuclear_strike_tick = opponent.next_nuclear_strike_tick_index
        if next_nuclear_strike_tick == -1:
            return False
        f = Formation(self.allVehicles, self.me, ownership=Ownership.ALLY)
        x = opponent.next_nuclear_strike_x
        y = opponent.next_nuclear_strike_y

        next_nuclear_strike_vehicle_id = opponent.next_nuclear_strike_vehicle_id
        if next_nuclear_strike_vehicle_id == -1:
            return False
        if next_nuclear_strike_vehicle_id not in self.vehicleById:
            return False
        is_aerial = self.vehicleById[next_nuclear_strike_vehicle_id].aerial

        kill_factor = f.calc_nuclear_kill_factor(x, y)
        if kill_factor['total_damage'] < 700 and kill_factor[
                'survived'] > kill_factor['killed'] * 5 and not is_aerial:
            return False

        from_x, from_y = self.vehicleById[
            next_nuclear_strike_vehicle_id].x, self.vehicleById[
                next_nuclear_strike_vehicle_id].y
        sos_vector = (y - from_y, x - from_x)
        sos_vector_norm = 120 / math.hypot(sos_vector[0], sos_vector[1])
        sos_vector = (sos_vector[0] * sos_vector_norm,
                      sos_vector[1] * sos_vector_norm)
        topleft = f.find_topleft()
        bottomright = f.find_bottomright()
        if topleft[0] + sos_vector[0] < 0 or topleft[1] + sos_vector[1] < 0:
            sos_vector = (-sos_vector[0], -sos_vector[1])
        elif bottomright[0] + sos_vector[0] >= self.world.height or bottomright[
                1] + sos_vector[1] >= self.world.width:
            sos_vector = (-sos_vector[0], -sos_vector[1])
        self.actionQueue.clear()
        self.actionQueue.push(Action.move(sos_vector[1], sos_vector[0], 0.3))
        self._sos_mode = True
        return True
Exemplo n.º 20
0
 def do_kill(s: MyStrategy, w: World, g: Game, m: Move):
     enemy = w.get_opponent_player()
     vs = s.worldstate.vehicles
     epicenter = Unit(None, enemy.next_nuclear_strike_x,
                      enemy.next_nuclear_strike_y)
     radius = g.tactical_nuclear_strike_radius + 10
     enemies = vs.resolve(vs.by_player[vs.opponent])
     clusters = clusterize(enemies)
     navigator = enemy.next_nuclear_strike_vehicle_id
     in_cluster_of_len = 0
     for c in clusters:
         cluset = set()
         for i in c:
             cluset.add(enemies[i].id)
         if navigator in cluset:
             in_cluster_of_len = len(c)
             break
     expl_area = Area(epicenter.x - radius, epicenter.x + radius,
                      epicenter.y - radius, epicenter.y + radius)
     my_avias = vs.by_player[vs.me] & (vs.by_type[VehicleType.HELICOPTER]
                                       | vs.by_type[VehicleType.FIGHTER])
     my_avias_len = len(my_avias)
     if my_avias_len >= in_cluster_of_len:
         target = vs[navigator]
         shift = Unit(None, target.x - epicenter.x, target.y - epicenter.y)
         result = [
             select_vehicles(expl_area, vtype=VehicleType.HELICOPTER),
             move(shift),
             select_vehicles(expl_area, vtype=VehicleType.FIGHTER),
             move(shift),
         ]
     else:
         result = [select_vehicles(expl_area), scale(epicenter, 10)]
     result.append(wait(enemy.next_nuclear_strike_tick_index -
                        w.tick_index))
     s.current_action = deque(result) + s.current_action
Exemplo n.º 21
0
    def baseLogic(self, me, world: World, game, move):
        if world.get_opponent_player(
        ).next_nuclear_strike_tick_index > 0 and not self.nuca_detect:
            self.nuca_detect = True
            self.is_quene_free = False
            strike_x = str(world.get_opponent_player().next_nuclear_strike_x)
            strike_y = str(world.get_opponent_player().next_nuclear_strike_y)
            self.delayedMoves = Queue()
            self.delayedMoves.put(
                'move.action = model.ActionType.ActionType.SCALE; move.x = ' +
                strike_x + '; move.y =' + strike_y + '; move.factor = 3.')
            for i in range(29):
                self.delayedMoves.put(
                    'move.action = model.ActionType.ActionType.NONE')
            self.delayedMoves.put(
                'move.action = model.ActionType.ActionType.SCALE; move.x = ' +
                strike_x + '; move.y =' + strike_y + '; move.factor = 0.5')
            for i in range(30):
                self.delayedMoves.put(
                    'move.action = model.ActionType.ActionType.NONE')

            x_enemy_c, y_enemy_c = self.getCenterOfGroup(
                self.getEnemyVehicles(me))
            x_c, y_c = self.getCenterOfSelected()
            self.delayedMoves.put(
                'move.action = model.ActionType.ActionType.MOVE; move.max_speed=0.3; move.x='
                + str(x_enemy_c - x_c) + '; move.y=' + str(y_enemy_c - y_c))
            self.delayedMoves.put(
                'self.is_quene_free = True; self.nuca_detect = False')
            return

        if me.remaining_nuclear_strike_cooldown_ticks == 0 and self.is_quene_free:
            x_enemy_c, y_enemy_c = self.getCenterOfGroup(
                self.getEnemyVehicles(me))
            x_c, y_c = self.getCenterOfSelected()
            viz_obj.message(
                'ROCKET Potential! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ')
            nuc_veh_id = self.getNucaVehId(me)
            #viz_obj.message('ROCKET Potential! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ')
            viz_obj.message(str(nuc_veh_id))  ########
            if nuc_veh_id > 0 and ((x_c - x_enemy_c)**2 +
                                   (y_c - y_enemy_c)**2)**0.5 > 44:
                self.is_quene_free = False
                self.delayedMoves = Queue()
                #viz_obj.message('ROCKET GO! 11111111111111111111111111111111111111111111')
                #viz_obj.message(str(nuc_veh_id))
                self.delayedMoves.put(
                    'move.action = model.ActionType.ActionType.TACTICAL_NUCLEAR_STRIKE; move.x='
                    + str(x_enemy_c) + '; move.y=' + str(y_enemy_c) +
                    '; move.vehicle_id=' + str(nuc_veh_id))
                viz_obj.circle(x_enemy_c, y_enemy_c, 50, 0xFF0000)

                self.delayedMoves.put(
                    'self.is_quene_free = True; move.action = model.ActionType.ActionType.MOVE; move.max_speed=0.3; move.x='
                    + str(x_enemy_c - x_c) + '; move.y=' +
                    str(y_enemy_c - y_c))

        if self.buildEnd:
            if world.tick_index % 150 == 0 and self.is_quene_free:
                viz_obj.message(
                    str(world.tick_index) + ' ' + str(self.buildEnd))
                x_enemy_c, y_enemy_c = self.getCenterOfGroup(
                    self.getEnemyVehicles(me))
                x_c, y_c = self.getCenterOfSelected()
                viz_obj.message(' ' + str(x_enemy_c - x_c) + ' ' +
                                str(y_enemy_c - y_c) + '\n')
                self.delayedMoves = Queue()
                self.delayedMoves.put(
                    'move.action = model.ActionType.ActionType.SCALE; x_c, y_c = self.getCenterOfSelected(); move.x = x_c; move.y = y_c; move.factor = 0.6'
                )
                for i in range(20):
                    self.delayedMoves.put(
                        'move.action = model.ActionType.ActionType.NONE')
                self.delayedMoves.put(
                    'move.action = model.ActionType.ActionType.ROTATE; x_c, y_c = self.getCenterOfSelected(); move.x = x_c; move.y = y_c; move.angle = 1.5'
                )
                for i in range(55):
                    self.delayedMoves.put(
                        'move.action = model.ActionType.ActionType.NONE')
                self.delayedMoves.put(
                    'move.action = model.ActionType.ActionType.MOVE; move.max_speed=0.3; move.x='
                    + str(x_enemy_c - x_c) + '; move.y=' +
                    str(y_enemy_c - y_c))
Exemplo n.º 22
0
    def move(self, me: Player, world: World, game: Game, move: Move):
        global vtDict, vehicleById, updateTickByVehicleId, facilityById
        global myVehicleIds, myVehicleIdsByType, enemyVehicleIds, enemyVehicleIdsByType
        global mu, muNuke, K, KK, lastNukaTick
        global minDist, maxDist, bestdist
        global myV, enV
        global clustersX, clustersY, frame
        global movements
        global round2, minefield, fieldChecker
        global scaleFactor, maxGroup, centerGroups, deadGroups
        global attacks, muNA
        myId=world.get_my_player().id
        enemy=world.get_opponent_player()
        enemyId=enemy.id
        wti=world.tick_index
        nsr=game.tactical_nuclear_strike_radius
        nsd=game.tactical_nuclear_strike_delay
        for v in world.new_vehicles:
            vehicleById[v.id] = v
            updateTickByVehicleId[v.id] = wti
            if v.player_id == myId:
                myVehicleIds.append(v.id)
                myVehicleIdsByType[v.type].append(v.id)
            else:
                enemyVehicleIds.append(v.id)
                enemyVehicleIdsByType[v.type].append(v.id)

        for v in world.vehicle_updates:
            if v.durability == 0:
                if v.id in myVehicleIds:
                    myVehicleIds.pop(myVehicleIds.index(v.id))
                    myVehicleIdsByType[vehicleById[v.id].type].pop(myVehicleIdsByType[vehicleById[v.id].type].index(v.id))
                else:
                    enemyVehicleIds.pop(enemyVehicleIds.index(v.id))
                    enemyVehicleIdsByType[vehicleById[v.id].type].pop(enemyVehicleIdsByType[vehicleById[v.id].type].index(v.id))
                vehicleById.pop(v.id)
                updateTickByVehicleId.pop(v.id)
            else:
                vehicleById[v.id].update(v)
                updateTickByVehicleId[v.id] = wti
        for f in world.facilities:
                facilityById[f.id] = f

        if wti == 0:
            if world.facilities:
                round2 = True
            if round2 == False:
                for i in range (0,5):
                    movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.vehicle_type = '+str(i)+'; move.right = world.width; move.bottom = world.height',0,'building'])
                    arr = []
                    for v in vehicleById.values():
                        if v.type == i:
                            arr.append(v)
                    movements.append(['move.action = ActionType.SCALE; move.x, move.y = ' + str(min([v.x for v in arr]) - 10) + ', ' + str(min([v.y for v in arr]) - 10) +'; move.factor = 10.0',1,'building'])
            else:
                for i in [VehicleType.FIGHTER, VehicleType.HELICOPTER]:
                    movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.vehicle_type = '+str(i)+'; move.right = world.width; move.bottom = world.height',0,'building'])
                    arr = []
                    for v in vehicleById.values():
                        if (v.type == i) &(v.player_id == me.id):
                            arr.append(v)
                    movements.append(['move.action = ActionType.SCALE; move.x, move.y = ' + str(min([v.x for v in arr]) - 10) + ', ' + str(min([v.y for v in arr]) - 10) +'; move.factor = 10.0',1,'building'])
                muNA = []
                notAerial = []
                for i in [VehicleType.ARRV, VehicleType.IFV, VehicleType.TANK]:
                    arr = []
                    for v in vehicleById.values():
                        if (v.type == i) &(v.player_id == me.id):
                            arr.append(v)
                            notAerial.append(v)
                    w = max([v.x for v in arr])- min([v.x for v in arr])
                    h = max([v.y for v in arr])- min([v.y for v in arr])
                    
                    if len(facilityById) > 2:
                        muNA.append([min([v.x for v in arr])+w/4, min([v.y for v in arr])+h/4])
                        muNA.append([min([v.x for v in arr])+3*w/4, min([v.y for v in arr])+h/4])
                        muNA.append([min([v.x for v in arr])+w/4, min([v.y for v in arr])+3*h/4])
                        muNA.append([min([v.x for v in arr])+3*w/4, min([v.y for v in arr])+3*h/4])
                    
                sortedMu = []
                sortedFacilities = []
                ZeroPoint = [np.mean([ v.x for v in notAerial]), np.mean([ v.y for v in notAerial])]
                distFromZero = []
                for i in range(1,len(world.facilities)+1):
                    f = facilityById[i]
                    distFromZero.append((f.left + 32 - ZeroPoint[0])**2 + (f.top + 32 - ZeroPoint[1])**2)

                while sum(distFromZero) != 0:
                    ind = distFromZero.index(max(distFromZero))
                    sortedFacilities.append(ind+1)
                    distFromZero[ind] = 0

                if len(sortedFacilities) > len(muNA):
                    sortedFacilities = sortedFacilities[len(sortedFacilities) - len(muNA):]
                
                for i in range(0,len(sortedFacilities)):
                    f=facilityById[sortedFacilities[i]]
                    minDistToFacilities = 10000000
                    for j in range(0,len(muNA)):
                        dst = (muNA[j][0] - f.left - 32)**2 + (muNA[j][1] - f.top - 32)**2
                        if dst < minDistToFacilities:
                            minDistToFacilities = dst
                            nearest = j
                    sortedMu.append(muNA.pop(nearest))
                while muNA:
                    minDistToZero = 10000000
                    for i in range(0,len(muNA)):
                        c=muNA[i]
                        dst = c[0]**2 + c[1]**2
                        if dst < minDistToZero:
                            minDistToZero = dst
                            ind = i
                    sortedMu.append(muNA.pop(ind))

                clustersNotAerial = []
                for i in range(0,len(sortedMu)):
                    clustersNotAerial.append([])
                for i in range(0, len(notAerial)):
                    distFromCenters = []
                    for center in sortedMu:
                        distFromCenters.append((notAerial[i].x - center[0])**2 + (notAerial[i].y - center[1])**2)
                    ind = distFromCenters.index(min(distFromCenters))
                    clustersNotAerial[ind].append(notAerial[i])

                last = 0
                for i in range(0,len(sortedMu)):
                    counts = np.bincount([v.type for v in clustersNotAerial[i]])
                    t = np.argmax(counts)
                    movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left, move.right, move.top, move.bottom = ' +str(getCoords(clustersNotAerial[i])) + '; move.type = ' + str(t) ,0,'start'])
                    movements.append(['move.action = ActionType.SCALE; move.factor = 0.1; move.x, move.y = '+ str(sortedMu[i][0]) + ', ' + str(sortedMu[i][1]), 2, 'start']) 
                    maxGroup += 1
                    movements.append(['move.action = ActionType.ASSIGN; move.group = ' + str(maxGroup),1,'start'])
                    
                    if (last < len(sortedFacilities)) & (i in [2,6,10]):
                        movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.group = ' + str(1+last), 0, 'start'])
                        movements.append(['move.action = ActionType.MOVE; move.x, move.y = '+ str(facilityById[sortedFacilities[last]].left + 32 - sortedMu[last][0]) + ', ' + str(facilityById[sortedFacilities[last]].top + 32 - sortedMu[last][1]), 1, 'start']) 
                        last +=1
                while last<len(sortedFacilities):
                        movements.append(['pause',0,'start',58])
                        movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.group = ' + str(1+last), 0, 'start'])
                        movements.append(['move.action = ActionType.MOVE; move.x, move.y = '+ str(facilityById[sortedFacilities[last]].left + 32 - sortedMu[last][0]) + ', ' + str(facilityById[sortedFacilities[last]].top + 32 - sortedMu[last][1]), 1, 'start']) 
                        last +=1
                        
        if enemyVehicleIds:
            if round2 == False:
                if (wti % 100 == 1) & (wti < 302):
                    for i in range(0,5):
                        fieldChecker[i].append(min([vehicleById[j].get_distance_to(1023,1023) for j in enemyVehicleIdsByType[i]]))
                if wti==302:
                    minefield = True
                    for i in range(0,5):
                        if fieldChecker[i] != sorted(fieldChecker[i]):
                            minefield = False
                    if (abs(fieldChecker[VehicleType.FIGHTER][3] - fieldChecker[VehicleType.FIGHTER][2])>3) | (abs(fieldChecker[VehicleType.HELICOPTER][3] - fieldChecker[VehicleType.HELICOPTER][2])>3):
                        minefield = False
                    if minefield:
                        movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.right = world.width; move.bottom = world.height', 0, 'antifield'])
                        movements.append(['move.action = ActionType.MOVE; move.x, move.y = -500, 0', 1, 'antifield']) 
        
        #Если враг - ковер, делаем сосиску и сидим в углу
        if minefield:
            i = 0
            if movements:
                i = movements[0][1]

            if wti==800:
                movements.insert(i, ['move.action = ActionType.CLEAR_AND_SELECT; move.right = world.width; move.bottom = world.height', 0, 'antifield'])
                movements.insert(i+1, ['move.action = ActionType.MOVE; move.x, move.y = -300, -300', 1, 'antifield']) 
            elif wti==1000:
                movements.insert(i, ['move.action = ActionType.CLEAR_AND_SELECT; move.right = world.width; move.bottom = world.height; move.vehicle_type = VehicleType.FIGHTER', 0, 'antifield'])
                movements.insert(i+1, ['move.action = ActionType.MOVE; move.x, move.y = 0, -200', 1, 'antifield'])
                movements.insert(i+2, ['move.action = ActionType.CLEAR_AND_SELECT; move.right = world.width; move.bottom = world.height; move.vehicle_type = VehicleType.HELICOPTER', 0, 'antifield'])
                movements.insert(i+3, ['move.action = ActionType.MOVE; move.x, move.y = 0, -200', 1, 'antifield'])
            elif (wti < 19000)&(wti > 1000)&(wti % 1500==0):
                movements.insert(i, ['move.action = ActionType.CLEAR_AND_SELECT; move.right = world.width; move.bottom = world.height', 0, 'antifield'])
                movements.insert(i+1, ['move.action = ActionType.MOVE; move.x, move.y = 500, 100', 1, 'antifield'])
            elif (wti < 19000)&(wti > 3999)&(wti > 3999)&(wti % 1500==500):
                movements.insert(i, ['move.action = ActionType.CLEAR_AND_SELECT; move.right = world.width; move.bottom = world.height', 0, 'antifield'])
                movements.insert(i+1, ['move.action = ActionType.MOVE; move.x, move.y = -500, -100', 1, 'antifield'])
            elif wti==19000:
                movements.insert(i, ['move.action = ActionType.CLEAR_AND_SELECT; move.right = world.width; move.bottom = world.height; move.vehicle_type = VehicleType.HELICOPTER', 0, 'antifield'])
                movements.insert(i+1, ['move.action = ActionType.MOVE; move.x, move.y = 700, 700; move.max_speed = 0.6', 1, 'antifield'])
                movements.insert(i+2, ['move.action = ActionType.CLEAR_AND_SELECT; move.right = world.width; move.bottom = world.height; move.vehicle_type = VehicleType.FIGHTER', 0, 'antifield'])
                movements.insert(i+3, ['move.action = ActionType.MOVE; move.x, move.y = 700, 700; move.max_speed = 0.6', 1, 'antifield'])

        #Если на нас сбросили
        if (enemy.next_nuclear_strike_tick_index - wti == nsd - 1) & ((minefield==False) | (minefield & (wti < 19000))):
            i = 0
            if movements:
                i = movements[0][1]
            movements.insert(i, ['move.action = ActionType.CLEAR_AND_SELECT; move.left = ' + str(enemy.next_nuclear_strike_x - nsr) + '; move.right = ' + str(enemy.next_nuclear_strike_x + nsr) + '; move.top = ' + str(enemy.next_nuclear_strike_y - nsr) + '; move.bottom = ' + str(enemy.next_nuclear_strike_y + nsr),0,'escape'])
            movements.insert(i+1, ['move.action = ActionType.SCALE; move.x, move.y = ' + str(enemy.next_nuclear_strike_x) + ', ' + str(enemy.next_nuclear_strike_y) + '; move.factor = 2.0',1,'escape'])

        #Если можно сбросить
        if (me.remaining_nuclear_strike_cooldown_ticks == 0) & (wti % 30 == 0): 
            xNuke = [[vehicleById[i].x, vehicleById[i].y] for i in enemyVehicleIds]
            muNuke = []
            kNuke = KK
            if len(xNuke) < kNuke:
                kNuke = len(xNuke)
            if kNuke != 0:
                muNuke = kmeans(xNuke, kNuke)[0]
                distances = []
                for c in range(0,len(muNuke)):
                    maxD = 0
                    maxDI = -1
                    for i in myVehicleIds:
                        v = vehicleById[i]
                        vDist = v.get_distance_to(muNuke[c][0],muNuke[c][1])
                        if (vDist > minDist[v.type])&(vDist < maxDist[v.type])&(vDist > maxD):
                            maxD = vDist
                            maxDI = i
                    distances.append([muNuke[c][0], muNuke[c][1], maxD, maxDI])
                maxDamage = 0
                for d in distances:
                    if d[3] != -1:
                        damage = 0
                        for i in enemyVehicleIds:
                            v = vehicleById[i]
                            disNuc = v.get_distance_to(d[0],d[1])
                            if disNuc < 50.0:
                                damageForUnit = 100 - (disNuc + 0.5) * 2 
                                if (v.durability - damageForUnit) <= 0:
                                    damage += 1
                                else:
                                    damage += (100 - (disNuc * 2 + 1)) / 100.0
                                    if v.type == VehicleType.ARRV:
                                        damage -= 1.23 #1230 * 0.1 / 100 old formula: damage -= (100 - (disNuc * 2 + 1)) / 1000.0
                        if damage > maxDamage:
                            maxDamage = damage
                            bestdist = d
                if maxDamage > 0.5: #maxDamage > len(enemyVehicleIds) / (kNuke * 15)
                    i = 0
                    if movements:
                        i = movements[0][1]
                    lastNukaTick = wti
                    movements.insert(i, ['move.action = ActionType.TACTICAL_NUCLEAR_STRIKE; move.x = ' + str(bestdist[0]) + '; move.y = ' + str(bestdist[1]) + '; move.vehicle_id = ' + str(bestdist[3]), 0, 'nuka'])
                    v = vehicleById[bestdist[3]]
                    movements.insert(i+1, ['move.action = ActionType.CLEAR_AND_SELECT; move.left = ' + str(v.x - 5) + '; move.right = ' + str(v.x + 5) + '; move.top = ' + str(v.y - 5) + '; move.bottom = ' + str(v.y + 5), 2, 'nuka'])
                    k = (maxDist[v.type] - bestdist[2]) / maxDist[v.type]
                    movements.insert(i+2, ['move.action = ActionType.MOVE; move.x, move.y = '+ str((v.x - bestdist[0]) * k)+', ' + str((v.y - bestdist[1]) * k ), 1, 'nuka'])

        #Если очков мало
        if ((me.score-enemy.score) < (20001-wti)/50) & (me.remaining_nuclear_strike_cooldown_ticks == 0) & (wti % 300 == 0) & (wti > 300):
            myFly = []
            for i in myVehicleIds:
                v=vehicleById[i]
                if (v.type == VehicleType.FIGHTER) | (v.type == VehicleType.HELICOPTER):
                    myFly.append(vehicleById[i])
            enemyArmy = []
            for i in enemyVehicleIds:
                v=vehicleById[i]
                if v.type != VehicleType.ARRV:
                    enemyArmy.append(vehicleById[i])
            distMin = 10000
            distEnemy = 10000
            for v in myFly:
                dist=v.get_distance_to(1023, 1023)
                if dist < distMin:
                    distMin = dist
                    distMinI = v.id
            if distMin !=10000:
                myV = vehicleById[distMinI]
                for v in enemyArmy:
                    dist=v.get_distance_to(myV.x, myV.y)
                    if dist < distEnemy:
                        distEnemy = dist
                        distEnemyI = v.id
                if enemyArmy:
                    enV = vehicleById[distEnemyI]
                    movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left = ' + str(myV.x - 5) + '; move.right = ' + str(myV.x + 5) + '; move.top = ' + str(myV.y - 5) + '; move.bottom = ' + str(myV.y + 5), 0, 'scout'])
                    b = myV.get_distance_to(enV.x, enV.y)
                    k = (b - minDist[myV.type]) / b
                    movements.append(['move.action = ActionType.MOVE; move.x, move.y = '+ str((enV.x - myV.x) * k) + ', ' + str((enV.y - myV.y) * k), 1, 'scout']) 
                else:
                    movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left = ' + str(myV.x - 5) + '; move.right = ' + str(myV.x + 5) + '; move.top = ' + str(myV.y - 5) + '; move.bottom = ' + str(myV.y + 5), 0, 'scout'])
                    b = myV.get_distance_to(900, 900)
                    k = (b - minDist[myV.type]) / b
                    movements.append(['move.action = ActionType.MOVE; move.x, move.y = '+ str((900 - myV.x) * k) + ', ' + str((900 - myV.y) * k), 1, 'scout']) 

        #Фабрики
        if (wti % 30 == 0):
            if world.facilities:
                for f in world.facilities:
                    if (f.type == FacilityType.VEHICLE_FACTORY) & (f.owner_player_id == me.id):
                        if (f.vehicle_type is None):
                            movements.append(['move.action = ActionType.SETUP_VEHICLE_PRODUCTION; move.facility_id = '+ str(f.id) + '; move.vehicle_type = ' + str(VehicleType.IFV), 0, 'factory_set'])
                        elif (f.vehicle_type in [ VehicleType.IFV, VehicleType.ARRV, VehicleType.TANK ]):
                            ground = myVehicleIdsByType[VehicleType.IFV] + myVehicleIdsByType[VehicleType.TANK] + myVehicleIdsByType[VehicleType.ARRV]
                            sumG = {}
                            for i in [ VehicleType.IFV, VehicleType.ARRV, VehicleType.TANK ]:
                                sumG[i] = 0
                                for j in myVehicleIdsByType[i]:
                                    v = vehicleById[j]
                                    if (v.x >= f.left) & (v.y >= f.top) & (v.x <= f.left + 64) & (v.y <= f.top + 64):
                                        sumG[i]+=1
                            if (sumG[VehicleType.IFV] + sumG[VehicleType.ARRV] + sumG[VehicleType.TANK]) > 65:
                                movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left = ' + str(f.left - 20) + '; move.right = ' + str(f.left + 84) + '; move.top = ' + str(f.top - 20) + '; move.bottom = ' + str(f.top + 84), 0, 'factory_ground'])
                                movements.append(['move.action = ActionType.SCALE; move.factor = 0.5; move.x, move.y = '+ str(f.left + 32) + ', ' + str(f.top + 32), 2, 'factory_ground']) 
                                maxGroup += 1
                                movements.append(['move.action = ActionType.ASSIGN; move.group = ' + str(maxGroup),1,'factory_ground'])
                                if len(myVehicleIdsByType[VehicleType.FIGHTER]) < len(enemyVehicleIdsByType[VehicleType.FIGHTER]):
                                    movements.append(['move.action = ActionType.SETUP_VEHICLE_PRODUCTION; move.facility_id = '+ str(f.id) + '; move.vehicle_type = ' + str(VehicleType.FIGHTER), 0, 'factory_set'])
                                else:
                                    movements.append(['move.action = ActionType.SETUP_VEHICLE_PRODUCTION; move.facility_id = '+ str(f.id) + '; move.vehicle_type = ' + str(VehicleType.HELICOPTER), 0, 'factory_set'])
                            else:
                                if (sumG[VehicleType.IFV] + sumG[VehicleType.ARRV] + sumG[VehicleType.TANK]) > 9:
                                    if (sumG[VehicleType.IFV] % 10 == 0) & (sumG[VehicleType.IFV] > sumG[VehicleType.ARRV]) & (sumG[VehicleType.IFV] > sumG[VehicleType.TANK]) & (f.vehicle_type == VehicleType.IFV):
                                        movements.append(['move.action = ActionType.SETUP_VEHICLE_PRODUCTION; move.facility_id = '+ str(f.id) + '; move.vehicle_type = ' + str(VehicleType.ARRV), 0, 'factory_set'])
                                    elif (sumG[VehicleType.ARRV] % 3 == 0) & (sumG[VehicleType.ARRV] >= sumG[VehicleType.IFV]//3) & (sumG[VehicleType.ARRV] > sumG[VehicleType.TANK]//3) & (f.vehicle_type == VehicleType.ARRV):
                                        movements.append(['move.action = ActionType.SETUP_VEHICLE_PRODUCTION; move.facility_id = '+ str(f.id) + '; move.vehicle_type = ' + str(VehicleType.TANK), 0, 'factory_set'])
                                    elif (sumG[VehicleType.TANK] % 10 == 0) & (sumG[VehicleType.TANK] >= sumG[VehicleType.IFV]) & (sumG[VehicleType.TANK] >= sumG[VehicleType.ARRV]) & (f.vehicle_type == VehicleType.TANK):
                                        movements.append(['move.action = ActionType.SETUP_VEHICLE_PRODUCTION; move.facility_id = '+ str(f.id) + '; move.vehicle_type = ' + str(VehicleType.IFV), 0, 'factory_set'])

                        elif (f.vehicle_type in [VehicleType.HELICOPTER, VehicleType.FIGHTER] ):
                            air = myVehicleIdsByType[VehicleType.FIGHTER] + myVehicleIdsByType[VehicleType.HELICOPTER] + myVehicleIdsByType[VehicleType.ARRV]
                            sumA = 0
                            for i in air:
                                v = vehicleById[i]
                                if (v.x >= f.left) & (v.y >= f.top) & (v.x <= f.left + 64) & (v.y <= f.top + 64):
                                    sumA+=1
                            if sumA >= 5:
                                movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.vehicle_type = '+ str(f.vehicle_type) + '; move.left = ' + str(f.left - 20) + '; move.right = ' + str(f.left + 84) + '; move.top = ' + str(f.top - 20) + '; move.bottom = ' + str(f.top + 84), 0, 'factory_air'])
                                movements.append(['move.action = ActionType.SCALE; move.factor = 2; move.x, move.y = '+ str(f.left + 32) + ', ' + str(f.top + 32), 2, 'factory_air']) 
                                maxGroup += 1
                                movements.append(['move.action = ActionType.ASSIGN; move.group = ' + str(maxGroup),1,'factory_air'])
                                movements.append(['move.action = ActionType.SETUP_VEHICLE_PRODUCTION; move.facility_id = '+ str(f.id) + '; move.vehicle_type = ' + str(VehicleType.IFV), 0, 'factory_set'])
        if round2:
            if (wti >= (min(len(facilityById),len(muNA))+1)*60):
                if (wti % ((maxGroup - len(deadGroups)+1)*20) == 0):
                    for i in range(1,maxGroup+1):
                        if i not in deadGroups:
                            cGX = []
                            cGY = []
                            for j in myVehicleIds:
                                v = vehicleById[j]
                                if i in v.groups:
                                    cGX.append(v.x)
                                    cGY.append(v.y)
                            if len(cGX) > 5:
                                centerGroups[i] = [np.median(cGX),np.median(cGY)]
                elif (wti % ((maxGroup - len(deadGroups)+1)*20) == 2):
                    newCenterGroups = {}
                    i = 0
                    while len(movements)>i:    
                        if (movements[i][2] == 'stuck') & (movements[i][1] == 0):
                            movements.pop(i)
                            movements.pop(i)
                        else:
                            i+=1
                    for i in range(1,maxGroup+1):
                        if (i not in deadGroups)&(i in centerGroups):
                            cGX = []
                            cGY = []
                            for j in myVehicleIds:
                                v = vehicleById[j]
                                if i in v.groups:
                                    cGX.append(v.x)
                                    cGY.append(v.y)
                            if len(cGX) > 3:
                                if len(cGX) < 6:
                                    movements.append(['move.action = ActionType.DISBAND; move.group = ' + str(i), 0, 'disband'])
                                    deadGroups.append(i)
                                else:
                                    newCenterGroups[i] = [np.median(cGX),np.median(cGY)]
                                    if ((newCenterGroups[i][0] - centerGroups[i][0])**2 + (newCenterGroups[i][1] - centerGroups[i][1])**2 < 0.02) | ((wti>3000)&(wti%1000 > 0)&(wti%1000 <= ((maxGroup - len(deadGroups) + 1 )*20) + 1 )):
                                        stopFlag = True
                                        for f in world.facilities:
                                            if ((f.owner_player_id!=me.id)|(f.capture_points < game.max_facility_capture_points)) & ((newCenterGroups[i][0] >= f.left - 10) & (newCenterGroups[i][1] >= f.top - 10) & (newCenterGroups[i][0] <= f.left + 74) & (newCenterGroups[i][1] <= f.top + 74)):
                                                stopFlag = False
                                        if stopFlag:
                                            #Новая цель
                                            minDistOccup = 10000000
                                            ind = -1
                                            for f in world.facilities:
                                                if (f.owner_player_id!=me.id)|(f.capture_points < game.max_facility_capture_points): #if (f.owner_player_id!=me.id)|(f.capture_points < game.max_facility_capture_points):
                                                    dist=(f.left + 32 - newCenterGroups[i][0])**2 + (f.top + 32 - newCenterGroups[i][1])**2 
                                                    if f.type == FacilityType.VEHICLE_FACTORY:
                                                        dist-=10000
                                                    if dist < minDistOccup:
                                                        minDistOccup = dist
                                                        ind = f.id
                                            if ind !=-1:
                                                f=facilityById[ind]
                                                movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left, move.right, move.top, move.bottom = ' + str(min(cGX) - 3) + ', ' + str(max(cGX) + 3) + ', ' + str(min(cGY) - 3) + ', ' + str(max(cGY) + 3), 0, 'stuck'])
                                                movements.append(['move.action = ActionType.MOVE; move.x, move.y = '+ str(f.left + 32 - newCenterGroups[i][0]) + ', ' + str(f.top + 32 - newCenterGroups[i][1]), 1, 'stuck']) 
                                            elif (wti>13000):
                                                movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left, move.right, move.top, move.bottom = ' + str(min(cGX) - 3) + ', ' + str(max(cGX) + 3) + ', ' + str(min(cGY) - 3) + ', ' + str(max(cGY) + 3), 0, 'stuck'])
                                                movements.append(['move.action = ActionType.MOVE; move.x, move.y = '+ str(mu[0][0] - newCenterGroups[i][0]) + ', ' + str(mu[1][0] - newCenterGroups[i][1]), 1, 'stuck'])
                            else:
                                deadGroups.append(i)

        #Убегаем
        if (wti > lastNukaTick + 30) & (wti % 60 == 30) & (minefield==False):
            kScale = K
            mu = []
            X = [[vehicleById[i].x, vehicleById[i].y] for i in enemyVehicleIds]
            if len(X) < kScale:
                kScale = len(X)
            if kScale != 0:
                mu = kmeans(X, kScale)[0]
                clustersX = [[],[],[],[],[]]
                clustersY = [[],[],[],[],[]]
                for i in range(0, len(X)):
                    distFromCenters = []
                    for center in mu:
                        distFromCenters.append((X[i][0] - center[0])**2 + (X[i][1] - center[1])**2)
                    ind = distFromCenters.index(min(distFromCenters))
                    clustersX[ind].append(X[i][0])
                    clustersY[ind].append(X[i][1])
                i = 0
                while len(movements)>i:    
                        if (movements[i][2] == 'scale')&(movements[i][1] == 0):
                            movements.pop(i)
                            movements.pop(i)
                        else:
                            i+=1
                aggrFlag = False
                for i in range(0, len(mu)):
                    minEnX=min(clustersX[i])
                    maxEnX=max(clustersX[i])
                    minEnY=min(clustersY[i])
                    maxEnY=max(clustersY[i])
                    sumMy=0
                    sumFac=0
                    nearestGroups= {}
                    notInGroups = 0
                    for gr in range(1,maxGroup+2):
                        nearestGroups[gr]=0
                    myAttack = 0
                    enAttack = 0
                    mySide = dict([(VehicleType.TANK, 0), (VehicleType.IFV, 0), (VehicleType.HELICOPTER, 0), (VehicleType.FIGHTER, 0), (VehicleType.ARRV, 0)])
                    enSide = dict([(VehicleType.TANK, 0), (VehicleType.IFV, 0), (VehicleType.HELICOPTER, 0), (VehicleType.FIGHTER, 0), (VehicleType.ARRV, 0)])
                    for j in myVehicleIds:
                        v=vehicleById[j]
                        if (v.x > minEnX - frame) & (v.x < minEnX + frame) & (v.y > minEnY - frame) & (v.y < minEnY + frame):
                            sumMy+=1
                            if v.groups:
                                for g in v.groups:
                                    nearestGroups[g]+=1
                            else:
                                notInGroups+=1
                    '''
                    if notInGroups > 0:
                        maxNearestGroup = 0
                        for g in nearestGroups:
                            mGV=max(nearestGroups.values())
                            if (nearestGroups[g] == mGV) & (mGV !=0):
                                maxNearestGroup = g
                        if maxNearestGroup == 0:
                            maxGroup+=1
                            maxNearestGroup=maxGroup
                        movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left = ' + str(minEnX - frame) + '; move.right = ' + str(maxEnX + frame) + '; move.top = ' + str(minEnY - frame) + '; move.bottom = ' + str(maxEnY + frame), 0, 'scale'])
                        movements.append(['move.action = ActionType.ASSIGN; move.group = ' + str(maxNearestGroup),1,'scale'])
                        nearestGroups[maxNearestGroup] += notInGroups
                    '''
                    for j in myVehicleIds:
                        v=vehicleById[j]
                        if v.groups:
                            if (v.groups[0] in nearestGroups.keys()) & ((v.x > minEnX - frame) & (v.x < minEnX + frame) & (v.y > minEnY - frame) & (v.y < minEnY + frame)):
                                mySide[v.type]+=v.durability
                    for j in enemyVehicleIds:
                        v=vehicleById[j]
                        if (v.x > minEnX - frame) & (v.x < minEnX + frame) & (v.y > minEnY - frame) & (v.y < minEnY + frame):
                            enSide[v.type]+=v.durability
                    for j in range(0,5):
                        for k in range(0,5):
                            myAttack+=attacks[j][k] * (mySide[j]/100) - enSide[k]
                            enAttack+=attacks[j][k] * (enSide[j]/100) - mySide[k]

                    #for f in world.facilities:
                    #    if ( (f.top < minEnY - frame) | (f.top +64 > maxEnY + frame) | (f.left +64 < minEnX - frame) | (f.left > maxEnX + frame) ):
                    #        sumFac+=1
                    #        break

                    if ((wti>=15000)|((len(myVehicleIds)//2>len(enemyVehicleIds))&(game.fog_of_war_enabled == False))) & (round2) & (wti % 1000 <= 100):
                        aggrFlag = True
                    else:
                        if ((maxEnX - minEnX)!= 0) & ((maxEnY - minEnY) !=0):
                            if (sumMy>0) &(sumFac==0)& (((len(clustersX)/((maxEnX - minEnX) * (maxEnY - minEnY)))*10000) >2):
                                if (myAttack < enAttack):
                                    movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left = ' + str(minEnX - frame) + '; move.right = ' + str(maxEnX + frame) + '; move.top = ' + str(minEnY - frame) + '; move.bottom = ' + str(maxEnY + frame), 0, 'scale'])
                                    movements.append(['move.action = ActionType.SCALE; move.x, move.y = '+ str(mu[i][0]) + ', ' + str(mu[i][1]) + '; move.factor = ' + str(scaleFactor), 1, 'scale']) 
                                else:
                                    for g in nearestGroups.keys():
                                        movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.group = ' + str(g), 0, 'scale'])
                                        movements.append(['move.action = ActionType.SCALE; move.x, move.y = '+ str(mu[i][0]) + ', ' + str(mu[i][1]) + '; move.factor = 0.1', 1, 'scale']) 
                #Аггр мод - собираем 4 кучи и идем на 4 кластера врага
                if aggrFlag:
                    j = 0 
                    while len(movements)>j:    
                        if (movements[j][2] == 'stuck')&(movements[j][1] == 0):
                            movements.pop(j)
                            movements.pop(j)
                        else:
                            j+=1
                    j = 0
                    while len(movements)>j:    
                        if (movements[j][2] == 'scale')&(movements[j][1] == 0):
                            movements.pop(j)
                            movements.pop(j)
                        else:
                            j+=1
                    j = 0
                    while len(movements)>j:    
                        if (movements[j][2] == 'aggrMode')&(movements[j][1] == 0):
                            for k in range(0,18):
                                movements.pop(j)
                        else:
                            j+=1
                    movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left, move.right, move.top, move.bottom = 0,511,0,511', 0, 'aggrMode'])
                    movements.append(['move.action = ActionType.SCALE; move.x, move.y = 256,511; move.factor = 0.1', 17, 'aggrMode']) 
                    movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left, move.right, move.top, move.bottom = 512,1023,0,511', 16, 'aggrMode'])
                    movements.append(['move.action = ActionType.SCALE; move.x, move.y = 768,511; move.factor = 0.1', 15, 'aggrMode']) 
                    movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left, move.right, move.top, move.bottom = 0,511,512,1023', 14, 'aggrMode'])
                    movements.append(['move.action = ActionType.SCALE; move.x, move.y = 256,512; move.factor = 0.1', 13, 'aggrMode']) 
                    movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left, move.right, move.top, move.bottom = 512,1023,512,1023', 12, 'aggrMode'])
                    movements.append(['move.action = ActionType.SCALE; move.x, move.y = 768,512; move.factor = 0.1', 11, 'aggrMode']) 
                    movements.append(['pause',10,'aggrMode',100])
                    movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left, move.right, move.top, move.bottom = 0,511,0,511', 9, 'aggrMode'])
                    movements.append(['move.action = ActionType.SCALE; move.factor = 0.1; move.x, move.y = '+ str(mu[0][0]) + ', ' + str(mu[0][1]), 8, 'aggrMode']) 
                    if len(mu)>=2:
                        movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left, move.right, move.top, move.bottom = 512,1023,0,511', 7, 'aggrMode'])
                        movements.append(['move.action = ActionType.SCALE; move.factor = 0.1; move.x, move.y = '+ str(mu[1][0]) + ', ' + str(mu[1][1]), 6, 'aggrMode'])
                    else:
                        movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left, move.right, move.top, move.bottom = 512,1023,0,511', 7, 'aggrMode'])
                        movements.append(['move.action = ActionType.SCALE; move.factor = 0.1; move.x, move.y = '+ str(mu[0][0]) + ', ' + str(mu[0][1]), 6, 'aggrMode'])
                    if len(mu)>=3:
                        movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left, move.right, move.top, move.bottom = 0,511,512,1023', 5, 'aggrMode'])
                        movements.append(['move.action = ActionType.SCALE; move.factor = 0.1; move.x, move.y = '+ str(mu[2][0]) + ', ' + str(mu[2][1]), 4, 'aggrMode']) 
                    else:
                        movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left, move.right, move.top, move.bottom = 0,511,512,1023', 5, 'aggrMode'])
                        movements.append(['move.action = ActionType.SCALE; move.factor = 0.1; move.x, move.y = '+ str(mu[0][0]) + ', ' + str(mu[0][1]), 4, 'aggrMode']) 
                    if len(mu)>=4:
                        movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left, move.right, move.top, move.bottom = 512,1023,512,1023', 3, 'aggrMode'])
                        movements.append(['move.action = ActionType.SCALE; move.factor = 0.1; move.x, move.y = '+ str(mu[3][0]) + ', ' + str(mu[3][1]), 2, 'aggrMode']) 
                    else:
                        movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.left, move.right, move.top, move.bottom = 512,1023,512,1023', 3, 'aggrMode'])
                        movements.append(['move.action = ActionType.SCALE; move.factor = 0.1; move.x, move.y = '+ str(mu[0][0]) + ', ' + str(mu[0][1]), 2, 'aggrMode']) 
                    movements.append(['pause',1,'aggrMode',600])       
        if (wti == 800) & (len(enemyVehicleIds)==0):
            movements.append(['move.action = ActionType.CLEAR_AND_SELECT; move.vehicle_type = VehicleType.FIGHTER; move.right = world.width; move.bottom = world.height',0,'total_scouts'])
            movements.append(['move.action = ActionType.SCALE; move.x, move.y = 512, 512; move.factor = 1.5',1,'total_scouts'])

        #Двигаемся
        if me.remaining_action_cooldown_ticks == 0:
            if movements:
                if movements[0][0] == 'pause':
                    movements[0][3] -= 1
                    if movements[0][3]<=1:
                        movements.pop(0)
                else:
                    exec(movements.pop(0)[0])
Exemplo n.º 23
0
def main():
    world = World(__width, __height)

    #zeroes on the map feels so loonely... let's populate the map ;)
    world.placeRandomObject(__wallSymbol, __wallNumber)
    world.placeRandomObject(__foodSymbol, __foodNumber)
    world.placeRandomObject(__robotSymbol, __robotNumber)

    #now i want to print the initial populated map
    world.printMap()

    print('\n\n')

    #starting game loop :)
    foodEaten = __foodNumber - world.getNumberOfFoodToFind()
    turno = 1
    while foodEaten < __foodNumber and turno < __foodNumber * 100:  #after all these turns i stop the simulation to avoid loops
        #input('Press enter to continue: ')
        print('____________________Round ', turno,
              ' begin__________________________')
        world.tick()
        print()
        print('map at the end of the round ', turno, ':')
        world.printMap()
        print()
        world.printScoreboard('SCORE')
        print('____________________Round ', turno,
              ' end____________________________')

        turno += 1
        foodEaten = __foodNumber - world.getNumberOfFoodToFind()

    print('END OF THE GAME: ', foodEaten, ' F has been eaten and ',
          world.getNumberOfFoodToFind(), ' F are still on the map')
    #world.printScoreboard('SCORE')
    print()
Exemplo n.º 24
0
    def move(self, me: Player, world: World, game: Game, move: Move):
        en = world.get_opponent_player()
        self.update(me, en, world, game)

        if world.tick_index == 0:
            self.init()

        if debug:
            with debug.pre() as dbg:
                for facility in self.world.facilities:
                    if facility.type == 0 or facility.owner_player_id != self.me.id:
                        continue
                    dbg.fill_circle(facility.left + 32, facility.top + 11, 32,
                                    (0, 0, 1))
                for centroid in self.get_centroids(self.en):
                    dbg.fill_circle(centroid[0], centroid[1], 32, (1, 0, 0))
                if self.aerial_form_done and self.ground_form_done:
                    for squad in Group.squadrons:
                        x, y = self.get_median(player=self.me, group=squad.id)
                        dbg.fill_circle(x, y, 32, (0, 0.5, 0.5))

        if me.remaining_action_cooldown_ticks > 0:
            return

        if self.execute_move_queue(move):
            return

        # formation
        if not self.aerial_form_done:
            self.do_aerial_formation()
        if not self.ground_form_done:
            self.do_ground_formation_2()
        if self.execute_move_queue(move):
            return

        if self.can_nuke() and self.world.tick_index % 10 == 0:
            self.fire_nukes()
        if self.execute_move_queue(move):
            return

        if not self.ground_form_done or not self.aerial_form_done:
            return
        '''for i in [1, 101, 201, 301, 401]:
            print(self.all_vehicles[i].groups)'''

        # shrink
        if not self.shrinking_done:
            print("shrink")
            self.do_shrinking()
        if self.execute_move_queue(move):
            return

        if not self.splitting_done:
            if self.splitting_stage == 1:
                print("split")
                self.m_queue.append(self.new_move(action=1, y_range=(0, 120)))
                self.m_queue.append(self.new_move(action=4, group=9))
                self.m_queue.append(
                    self.new_move(action=1, y_range=(120, self.WORLD_HEIGHT)))
                self.m_queue.append(self.new_move(action=4, group=10))
                self.splitting_stage += 1
            elif (self.splitting_stage == 2
                  and len(self.get_positions(player=self.me, group=10)) > 0):
                print("split finished")
                self.splitting_done = True
                self.splitting_stage += 1
            if self.execute_move_queue(move):
                return

        # evade nukes
        self.evade_nukes()
        if self.execute_move_queue(move):
            return

        #self.fix_formation()
        #if self.execute_move_queue(move):
        #    return

        # assign new groups
        if self.world_has_facilities:
            self.assign_new_groups()
            if self.execute_move_queue(move):
                return

        # clean up groups
        for squad in Group.squadrons:
            group = squad.id
            # print(Group.g_queue)
            if len(self.get_positions(player=self.me, group=group)) == 0:
                print("remove group", group)
                Group.remove(group)

        # attack signature
        if self.aerial_form_done and self.ground_form_done:
            for _ in range(len(Group.g_queue)):
                squad = Group.g_queue.popleft()
                if squad not in Group.squadrons:
                    continue
                Group.g_queue.append(squad)
                group = squad.id
                # print("now:", group)
                if not self.units_have_stopped(
                        self.me, group=group, duration=1):
                    continue
                if group == Group.ALL:
                    if self.count_free_facilities() > 0:
                        self.occupy_nearest_facility(Group.ALL)
                    else:
                        self.attack_nearest_cluster_of_enemy(Group.ALL)
                else:
                    self.potential_flow(squad)
                if self.execute_move_queue(move):
                    return
Exemplo n.º 25
0
            "type": 2
        }
    ],
    "train": [
        {
            "capacity": 15,
            "idx": 0,
            "line_idx": 1,
            "player_id": "dcdfdf83-cbcf-4cec-8ad8-c919c7f6781d",
            "position": 10,
            "product": 0,
            "speed": 0
        }
    ]
}''')

world = World(posts=world_responce['post'], trains=world_responce['train'])
game = Game(lines=game_responce['line'], points=game_responce['point'])


def test_defult():

    strategy = Strategy(start_data)
    next_move = strategy.move(world, game)

    print(next_move)
    test_move = Move(12, 1, 0)
    assert next_move.line_idx == test_move.line_idx
    assert next_move.speed == test_move.speed
    assert next_move.train_idx == test_move.train_idx
Exemplo n.º 26
0
 def do_move(s: MyStrategy,
             w: World,
             g: Game,
             m: Move,
             max_speed=max_speed):
     vs = s.worldstate.vehicles
     aviaspeedfactor = 1
     myg = vs.by_group[gr]
     my = list(vs.resolve(myg))
     marea = get_square(my)
     mycenter = get_center(my)
     aviasupport = vs.by_group[gr + 1]
     if len(aviasupport) > 0:
         aviacenter = get_center(list(vs.resolve(aviasupport)))
     enemies = list(vs.resolve(vs.by_player[vs.opponent]))
     if len(enemies) == 0:
         return  # some patroling action might be inserted later
     clusters = clusterize(enemies, thresh=20)
     aviaingroup = len(myg & aviasupport)
     #allmine = len(myg | aviasupport)
     groundmine = len(my)
     least = get_center(enemies)
     value = 500
     mindistance = 2000
     for c in clusters:
         #print("Cluster:" + str(len(c)))
         cluster = list(map(lambda x: enemies[x], c))
         clustercenter = get_center(cluster)
         distance = mycenter.get_distance_to_unit(clustercenter)
         #new_value = map(lambda i: 1-int(i.type==0)-int(i.type==1)/2, cluster)
         #new_value = reduce(lambda x, y: x+y, new_value)
         new_value = len(cluster)
         criticaldistance = (
             new_value + groundmine) / 2  # should be obtained empirically
         #print(str(value) + " == " + str(new_value))
         if distance < criticaldistance:
             # combat mode! fight or flee!
             cluset = set(map(lambda x: x.id, cluster))
             fulladvantage = calculate(s.effectiveness, vs,
                                       (myg | aviasupport) - vs.damaged,
                                       cluset)
             #if len((myg | aviasupport)-vs.damaged) / len(myg | aviasupport) > 0.7:
             print("Advantage: " + str(fulladvantage))
             print("Cluster length: " + str(len(cluster)))
             nuke_cd = w.get_my_player(
             ).remaining_nuclear_strike_cooldown_ticks
             if (nuke_cd == 0 and len(cluster) > 20):
                 print("NUKE IT!")
                 navigator = -1
                 dst = 2000
                 for i in aviasupport:
                     ndst = vs[i].get_distance_to_unit(clustercenter)
                     if ndst < dst:
                         dst = ndst
                         navigator = i
                 if navigator > 0:
                     narea = get_square([vs[navigator]])
                     aviaspeedfactor = 10
                     if dst <= 2 * g.fighter_vision_range / 3:
                         s.flags["nuking"] = w.tick_index + 60
                         s.current_action.append(
                             nuke_it(clustercenter, navigator))
                     else:
                         s.flags["nuking"] = 20000
                         target = Unit(None, clustercenter.x - aviacenter.x,
                                       clustercenter.y - aviacenter.y)
                         if target.x == 0:
                             target = Unit(
                                 None, target.x,
                                 target.y - g.fighter_vision_range)
                         elif target.y == 0:
                             target = Unit(
                                 None, target.x - g.fighter_vision_range,
                                 target.y)
                         else:
                             slope = target.y / target.x
                             dx = sqrt((g.fighter_vision_range**2) /
                                       (slope**2 + 1))
                             dy = dx * slope
                             target = Unit(None, target.x - dx,
                                           target.y - dy)
                         s.current_action.append(
                             select_vehicles(narea,
                                             vtype=VehicleType.FIGHTER))
                         s.current_action.append(move(target))
                     # slowly go to the enemy
                 else:
                     print("Navigator not found")
                 # NUKE IS COMMING!
             elif "nuking" in s.flags and s.flags["nuking"] < w.tick_index:
                 s.flags.pop("nuking")
             #fight!
             least = Unit(None,
                          mycenter.x + (clustercenter.x - mycenter.x) / 2,
                          mycenter.y + (clustercenter.y - mycenter.y) / 2)
             mindistance = distance
             value = new_value
             max_speed = max_speed * 0.8
             if aviaspeedfactor == 1:
                 aviaadvantage = calculate(s.effectiveness, vs,
                                           aviasupport - vs.damaged, cluset)
                 #print("Aviaadvantage: " + str(aviaadvantage))
                 if aviaadvantage > 0:
                     aviaspeedfactor = 10
                 elif aviaingroup > 0 and aviaadvantage < -10:
                     aviaspeedfactor = 0.5
         if value * valdst + mindistance > new_value * valdst + distance:
             #print(str(value) + " > " + str(new_value))
             least = clustercenter
             value = new_value
             mindistance = distance
     dx = (least.x - mycenter.x)
     dy = (least.y - mycenter.y)
     destination = Unit(None, dx, dy)
     if aviaspeedfactor != 1 or "nuking" in s.flags:
         aviadestination = Unit(None, least.x - aviacenter.x,
                                least.y - aviacenter.y)
         s.current_action.appendleft(
             move(aviadestination, max_speed=aviaspeedfactor * max_speed))
         s.current_action.appendleft(group(gr, action=ActionType.DISMISS))
         s.current_action.appendleft(select_vehicles(marea, group=gr + 1))
     elif aviaingroup == 0 and not "nuking" in s.flags:
         ddx = copysign(100 * max_speed, dx)
         ddy = copysign(100 * max_speed, dy)
         overmain = Unit(None, mycenter.x - aviacenter.x + ddx,
                         mycenter.y - aviacenter.y + ddy)
         s.current_action.appendleft(move(overmain,
                                          max_speed=2 * max_speed))
         s.current_action.appendleft(group(gr, action=ActionType.ASSIGN))
         s.current_action.appendleft(select_vehicles(marea, group=gr + 1))
     s.current_action.appendleft(move(destination, max_speed=max_speed))
Exemplo n.º 27
0
from app_init import *
from model.World import World
from model.OrganismFactory import OrganismFactory
from model.SpeciesEnum import SpeciesEnum
import wx
import wx.lib.ogl as ogl
from controller.Controller import Controller
from view.View import View

if __name__ == "__main__":
    model = World(world_size_x, world_size_y, compasRose)
    factory = OrganismFactory()

    # add one human
    org = factory.createOrganism(SpeciesEnum.HUMAN,
                                 model.getFreePositionInWorld())
    org.world = model
    model.addOrganism(org)
    # add the rest
    for sp in SpeciesEnum:
        propName = "number_of_{0}".format(sp.name.lower())
        if propName in globals():
            propValInt = globals()[propName]
            # print(propValInt)
            if propName and not propName == "number_of_human":
                for i in range(0, propValInt):
                    org = factory.createOrganism(
                        sp, model.getFreePositionInWorld())
                    if org:
                        org.world = model
                        model.addOrganism(org)
Exemplo n.º 28
0
class Simulator:

    """
    Class representing the Simulator.
    """

    def __init__(self):
        """
        Initializing the Simulator
        """
        self.world = World()
        self.mdp = []
        self.replay = Replay(self.world.maze, self.world.agents, self.world.get_agents_position())
        self.launch_replay = False
        self.stats = Statistics(len(self.world.agents), len(self.world.adversaries))
        self.distances = []
        self.end = False
        self.coordination = True

    def get_maze(self):
        """
        Return the class Maze contained in the class World
        :return: Return the maze
        """
        return self.world.maze

    def generate_maze(self, size):
        """
        Generate a maze.
        """
        self.world.maze.make_maze(size)
        self.world.create_random_goal()

    def init_simulator(self):
        """
        Initialize the simulator and create the mdp and the agents
        """
        self.generate_maze([15, 15])
        self.mdp = self.calculate_policies()
        self.world.create_agents(2, self.mdp)

    def calculate_policies(self):
        """
        Create the MDP and calculate all the policies
        :return:
        """
        print(" Computing policies... ")
        mdp = MDP(self.world.maze)
        mdp.compute_all_policies(0.99)
        print(" Done. ")
        return mdp

    def create_scenario(self, maze_size, nb_agents, position_agents, position_goal, nb_adveraries):
        """
        Create a new scenario
        :param maze_size: the size of the maze to generate
        :param nb_agents: the number of agents
        :param position_agents: the positions of the agents
        :param position_goal: the position of the goal
        """
        scenario = Scenario(maze_size, nb_agents, position_agents, position_goal)
        scenario.create_maze()
        self.world.maze = scenario.maze
        self.mdp = self.calculate_policies()
        scenario.create_agents(self.mdp)
        scenario.random_adversaries(nb_adveraries, self.mdp)
        self.world.agents = scenario.agents
        self.world.adversaries = scenario.adversaries
        self.replay = Replay(self.world.maze, self.world.agents, self.world.get_agents_position(), self.world.adversaries, self.world.get_adversary_position())
        self.stats = Statistics(len(self.world.agents), len(self.world.adversaries))
        self.distances = self.mdp.value_iteration(1, self.world.maze.end)[1]

    def new_scenario(self, nb_agents, position_agents, position_goal, nb_adveraries, coordination=True):
        """
        Create a new scenario without changing the map
        :param nb_agents: the number of agents
        :param position_agents: the positions of the agents
        :param position_goal: the position of the goal
        """
        scenario = Scenario([self.world.maze.nx, self.world.maze.ny], nb_agents, position_agents, position_goal)
        scenario.nb_agents = nb_agents
        scenario.maze = self.world.maze
        scenario.create_agents(self.mdp)
        scenario.random_adversaries(nb_adveraries, self.mdp)
        self.world.agents = scenario.agents
        self.world.adversaries = scenario.adversaries
        self.world.maze.end = position_goal
        self.replay = Replay(self.world.maze, self.world.agents, self.world.get_agents_position(), self.world.adversaries, self.world.get_adversary_position())
        self.stats = Statistics(len(self.world.agents), len(self.world.adversaries))
        self.distances = self.mdp.value_iteration(1, self.world.maze.end)[1]
        self.coordination = coordination

    def reset(self):
        """
        Reset the simulation
        :return the new world
        """
        self.world.reset()
        self.init_simulator()
        return self.world

    def run(self):
        """
        Run the problem
        """
        if self.launch_replay:
            self.run_replay()
        else:
            positions = []
            positions_adv = []
            for a in self.world.agents:
                if a.position != self.world.get_end():
                    self.run_agent(a)
                positions.append(a.position)
                self.stats.update_distances(a.id, self.distances[a.position[1]][a.position[0]]/2)
            for adv in self.world.adversaries:
                if adv.position != self.world.get_end():
                    self.run_adversary(adv)
                positions_adv.append(adv.position)
                self.stats.update_distances(adv.id, self.distances[adv.position[1]][adv.position[0]]/2)
            self.replay.update_positions(positions)
            self.replay.update_positions_adversary(positions_adv)
            messages = self.exchanging_message()
            self.replay.update_messages(messages)
            self.stats.update_messages(self.world, messages)
            goals_possible, no_goals = self.deduce_goal()
            for a in self.world.agents:
                if self.coordination:
                    a.pomdp.deduce_goal(goals_possible, no_goals)
                else:
                    a.pomdp.deduce_goal([], [])
        self.checkEnd()

    def run_replay(self):
        if self.replay.index < self.replay.index_max:
            positions = self.replay.get_positions()
            positions_adv = self.replay.get_positions_adversaries()
            messages = self.replay.get_messages()
            self.replay.index += 1
            for i in range(len(self.world.agents)):
                self.world.agents[i].position = positions[i]
                self.stats.update_distances(self.world.agents[i].id, self.distances[self.world.agents[i].position[1]][self.world.agents[i].position[0]] / 2)
            for i in range(len(self.world.adversaries)):
                self.world.adversaries[i].position = positions_adv[i]
                self.stats.update_distances(self.world.adversaries[i].id, self.distances[self.world.adversaries[i].position[1]][
                    self.world.adversaries[i].position[0]] / 2)
            self.stats.update_messages(self.world, messages)


    def run_agent(self, agent):
        """
        Run the process for each agent
        :param agent: agent
        """
        # Get the best action following the current policy
        action = agent.pomdp.get_best_action()
        # Execute the action
        new_position = agent.pomdp.execute_action(action)
        # Update the position of the agent
        agent.position = new_position
        # Search with an heuristic the best policy to execute
        agent.pomdp.heuristic_search()

    def run_adversary(self, adversary):
        """
        Run the process for each adversary
        :param adversary: adversary
        """
        # Get the best action following the current policy
        action = adversary.pomdp.get_best_action()
        # Execute the action
        new_position = adversary.pomdp.execute_action(action)
        # Update the position of the agent
        adversary.position = new_position
        # Search with an heuristic the best policy to execute
        adversary.pomdp.heuristic_search()

    def exchanging_message(self):
        """
        Exchange messages between agents.
        """
        messages = []
        for i in range(len(self.world.agents)):
            verifier = self.world.agents[i]
            messages_a = []
            for j in range(len(self.world.agents)):
                if j != i:
                    prover = self.world.agents[j]
                    question = verifier.zkmaze.verifier_send_question(prover.id)
                    answer = prover.zkmaze.prover_send_answer(question)
                    verifier.zkmaze.verifier_receive_answer(prover.id, answer)
                    verifier.zkmaze.estimate_position_agent(prover.id)
                    messages_a.append([question, prover.id, answer])
                else:
                    messages_a.append([])
            for adv in range(len(self.world.adversaries)):
                prover = self.world.adversaries[adv]
                question = verifier.zkmaze.verifier_send_question(prover.id)
                answer = prover.strategy.prover_send_answer(question)
                verifier.zkmaze.verifier_receive_answer(prover.id, answer)
                verifier.zkmaze.estimate_position_agent(prover.id)
                messages_a.append([question, prover.id, answer])
            messages.append(messages_a)
        for i in range(len(self.world.adversaries)):
            verifier = self.world.adversaries[i]
            messages_a = []
            for j in range(len(self.world.agents)):
                prover = self.world.agents[j]
                question = verifier.strategy.verifier_send_question(prover.id)
                answer = prover.zkmaze.prover_send_answer(question)
                verifier.strategy.verifier_receive_answer(prover.id, answer)
                messages_a.append([question, prover.id, answer])
            messages.append(messages_a)
        return messages

    def estimate_position_agent(self, id, positions):
        """
        Estimate the position of the agent
        :param id: Id of the agent
        """
        if id in self.estimated_positions:
            new_positions = self.reduce_position_uncertainty(id, positions)
            self.estimated_positions[id] = new_positions
        else:
            self.estimated_positions[id] = positions

    def reduce_position_uncertainty(self, id, new_estimation):
        """
        Reduce the uncertainty on the estimated positions
        :param id: id of the agent
        :param new_estimation: new positions estimated
        :return: List of positions
        """
        positions = []
        previous_estimation = self.estimated_positions[id]
        for pe in previous_estimation:
            for ne in new_estimation:
                previous_cell = self.world.maze.cell_at(pe[0], pe[1])
                new_cell = self.world.maze.cell_at(ne[0], ne[1])
                if previous_cell.wall_between(new_cell) is not None:
                    if not previous_cell.wall_between(new_cell) and ne not in positions:
                        positions.append(ne)
                if previous_cell == new_cell:
                    positions.append(ne)
        return positions

    def get_estimated_agent_positions(self):
        """
        Return all the expected positions for every agent
        :return: list of expected positions
        """
        expected_positions = {}
        for a in self.world.agents:
            if a.id in self.stats.estimated_position:
                expected_positions[a.id] = self.stats.estimated_position[a.id][self.stats.index-1]
        return expected_positions

    def deduce_goal(self):
        goals = []
        no_goals = []
        for a in self.world.agents:
            if self.stats.index > 1:
                if self.stats.estimated_position[a.id][self.stats.index-1] == self.stats.estimated_position[a.id][self.stats.index-2]:
                    goals += self.stats.estimated_position[a.id][self.stats.index-1]
                    break
                else:
                  if len(self.stats.estimated_position[a.id][self.stats.index-2]) == 1:
                    no_goals += self.stats.estimated_position[a.id][self.stats.index-2]
        return goals, no_goals

    def save_maze(self, file_name):
        """
        Save the maze in a Pickle file
        :param file_name: name of the file
        """
        save = Save(self.world.maze, self.mdp)
        with open(file_name, 'wb') as handle:
            pickle.dump(save, handle)

    def load_maze(self, file_name):
        """
        Load a maze from a Pickle file
        :param file_name: name of the file
        """
        with open(file_name, "rb") as handle:
            save = pickle.load(handle)
            maze = save.maze
            mdp = save.mdp
        self.world.maze = maze
        self.mdp = mdp

    def save_replay(self, file_name):
        """
        Save the replay in a Pickle file
        :param file_name: name of the file
        """
        with open(file_name, 'wb') as handle:
            pickle.dump(self.replay, handle)

    def load_replay(self, file_name):
        """
        Load a maze from a Pickle file
        :param file_name: name of the file
        """
        with open(file_name, "rb") as handle:
            self.replay = pickle.load(handle)
        self.world.maze = self.replay.maze
        self.world.agents = self.replay.agents
        self.world.adversaries = self.replay.adversaries
        self.stats = Statistics(len(self.world.agents), len(self.world.adversaries))
        self.mdp = self.calculate_policies()
        self.distances = self.mdp.value_iteration(1, self.world.maze.end)[1]

    def checkEnd(self):
        end = True
        for a in self.world.agents:
            if a.position != self.world.get_end():
                end = False
        self.end = end
Exemplo n.º 29
0
    def move(self, me: Player, world: World, game: Game, move: Move):
        self.me = me
        self.opponent = world.get_opponent_player()  # type: Player
        self.world = world
        self.game = game
        self.terrain = world.terrain_by_cell_x_y
        self.weather = world.weather_by_cell_x_y

        if world.tick_index == 0:
            self.put_attack_range(VehicleType.TANK, game.tank_ground_attack_range, game.tank_aerial_attack_range)
            self.put_attack_range(VehicleType.FIGHTER, None, game.fighter_aerial_attack_range)
            self.put_attack_range(VehicleType.HELICOPTER, game.helicopter_ground_attack_range, game.helicopter_aerial_attack_range)
            self.put_attack_range(VehicleType.IFV, game.ifv_ground_attack_range, game.ifv_aerial_attack_range)

        # Update units.
        for vehicle in world.new_vehicles:  # type: Vehicle
            self.vehicles[vehicle.id] = vehicle
            if vehicle.player_id == me.id:
                self.my_vehicles[vehicle.id] = vehicle
            else:
                self.enemy_vehicles[vehicle.id] = vehicle
        for update in world.vehicle_updates:  # type: VehicleUpdate
            if update.durability != 0:
                vehicle = self.vehicles[update.id]
                vehicle.x = update.x
                vehicle.y = update.y
                vehicle.durability = update.durability
                vehicle.groups = update.groups
                vehicle.selected = update.selected
                vehicle.remaining_attack_cooldown_ticks = update.remaining_attack_cooldown_ticks
            else:
                self.vehicles.pop(update.id, None)
                self.my_vehicles.pop(update.id, None)
                self.enemy_vehicles.pop(update.id, None)

        # Update freeze.
        if self.freeze_ticks != 0:
            self.freeze_ticks -= 1

        # Pre-compute some useful values.
        self.my_x, self.my_y = self.get_my_center()
        self.r2 = max(vehicle.get_squared_distance_to(self.my_x, self.my_y) for vehicle in self.my_vehicles.values())
        self.r = sqrt(self.r2)

        my_durability = self.get_attacker_durability(self.my_vehicles.values(), self.enemy_vehicles.values())
        opponent_durability = self.get_attacker_durability(self.enemy_vehicles.values(), self.my_vehicles.values())
        self.attack_ratio = my_durability / opponent_durability if opponent_durability != 0 else 1000000.0

        # Nuclear strike protection.
        if self.opponent.next_nuclear_strike_vehicle_id != -1:
            print('[{}] NUCLEAR STRIKE PROTECTION!'.format(self.world.tick_index))
            self.action_queue.clear()
            if not all(vehicle.selected for vehicle in self.my_vehicles.values()):
                self.schedule(self.select_all)
            self.schedule(lambda move_: self.expand(move_, self.opponent.next_nuclear_strike_x, self.opponent.next_nuclear_strike_y))
            self.freeze_ticks = 0

        # Check if something has to be done.
        if self.action_queue:
            if me.remaining_action_cooldown_ticks == 0 and self.freeze_ticks == 0:
                self.action_queue.popleft()(move)
                print('[{}] {}({:.2f}, {:.2f})'.format(self.world.tick_index, move.action, move.x, move.y))
            return

        print('[{}] Next action: {}'.format(world.tick_index, self.next_action))
        if self.next_action == 'ROTATE':
            self.schedule(lambda move_: self.select_all(move_, vehicle_type=VehicleType.TANK))
            self.schedule(lambda move_: self.select_all(move_, vehicle_type=VehicleType.IFV, add_to_selection=True))
            self.schedule(lambda move_: self.select_all(move_, vehicle_type=VehicleType.ARRV, add_to_selection=True))
            self.schedule(self.rotate_selected)
            self.schedule(lambda move_: self.select_all(move_, vehicle_type=VehicleType.FIGHTER))
            self.schedule(lambda move_: self.select_all(move_, vehicle_type=VehicleType.HELICOPTER, add_to_selection=True))
            self.schedule(self.rotate_selected)
            self.schedule(lambda _: self.reset_freeze(50))
            self.rotate_angle *= -1
            self.next_action = 'SHRINK'
        elif self.next_action == 'SHRINK':
            self.schedule(lambda move_: self.select_all(move_, vehicle_type=VehicleType.TANK))
            self.schedule(lambda move_: self.select_all(move_, vehicle_type=VehicleType.IFV, add_to_selection=True))
            self.schedule(lambda move_: self.select_all(move_, vehicle_type=VehicleType.ARRV, add_to_selection=True))
            self.schedule(self.shrink_selected)
            self.schedule(lambda move_: self.select_all(move_, vehicle_type=VehicleType.FIGHTER))
            self.schedule(lambda move_: self.select_all(move_, vehicle_type=VehicleType.HELICOPTER, add_to_selection=True))
            self.schedule(self.shrink_selected)
            self.schedule(lambda _: self.reset_freeze(50))
            self.shrink_count += 1
            self.next_action = 'MOVE' if self.shrink_count > 5 else 'ROTATE'
        elif self.next_action == 'MOVE':
            self.schedule(self.select_all)
            self.schedule(self.move_forward)
            self.schedule(lambda _: self.reset_freeze(50))
            density = self.get_density()
            print("[{}] Density: {:.3f}".format(world.tick_index, density))
            self.next_action = 'ROTATE' if density < 0.039 else 'MOVE'