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 __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)
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)
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)
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())
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())
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
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() )
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())
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())
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
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())
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())
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)
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)
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)
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
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
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
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))
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])
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()
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
"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
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))
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)
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
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'