|
|
@ -33,6 +33,12 @@ class Occupy(Logic): |
|
|
|
"up": (-1, 0), |
|
|
|
"down": (1, 0) |
|
|
|
} |
|
|
|
# Jaké území okolo domečku je chráněné |
|
|
|
PROTECTED_AREA = [ |
|
|
|
[-1, -1], [-1, 0], [-1, 1], |
|
|
|
[0, -1], [0, 0], [0, 1], |
|
|
|
[1, -1], [1, 0], [1, 1] |
|
|
|
] |
|
|
|
|
|
|
|
def __init__(self, teams_count: int, configuration: Any): |
|
|
|
super().__init__(teams_count, configuration) |
|
|
@ -41,8 +47,10 @@ class Occupy(Logic): |
|
|
|
assert(teams_count == self.teams_width * self.teams_height) |
|
|
|
self.map_width = self.teams_width * configuration["width_per_team"] |
|
|
|
self.map_height = self.teams_height * configuration["height_per_team"] |
|
|
|
# born per round - nultý index je počet vojáků každého týmu v zero-stavu |
|
|
|
self.bpr = self.configuration["born_per_round"] |
|
|
|
# Parametry k počtu nových vojáků |
|
|
|
self.rounds_total = configuration["initial_remaining_rounds"] |
|
|
|
self.spawn_price = configuration["spawn_price"] |
|
|
|
self.last_spawn = configuration["last_spawn"] |
|
|
|
|
|
|
|
def generate_soldier(self, team_id, soldier_id): |
|
|
|
return { |
|
|
@ -52,6 +60,9 @@ class Occupy(Logic): |
|
|
|
"remaining_rounds": 1 |
|
|
|
} |
|
|
|
|
|
|
|
def budget_for_round(self, round_id): |
|
|
|
return (self.last_spawn * self.spawn_price * (round_id + 1)**2) // (self.rounds_total**2) |
|
|
|
|
|
|
|
# Počáteční stav |
|
|
|
def zero_state(self) -> Any: |
|
|
|
map = [ |
|
|
@ -77,7 +88,7 @@ class Occupy(Logic): |
|
|
|
map[home_y][home_x]["home_for_team"] = team_id |
|
|
|
map[home_y][home_x]["occupied_by_team"] = team_id |
|
|
|
# Initial stav vojáků: |
|
|
|
for soldier_id in range(self.bpr[0]): |
|
|
|
for soldier_id in range(max(1, self.budget_for_round(0) // self.spawn_price)): |
|
|
|
map[home_y][home_x]["members"].append(self.generate_soldier(team_id, soldier_id)) |
|
|
|
team_id += 1 |
|
|
|
home_x += self.configuration["width_per_team"] |
|
|
@ -115,12 +126,19 @@ class Occupy(Logic): |
|
|
|
home_positions = [None] * self.teams_count |
|
|
|
# 2D array s `True`s tam, kde je hill |
|
|
|
hills = [[False] * self.map_width for _ in range(self.map_height)] |
|
|
|
# 2D array s ID týmu, který zde má chráněné území (okolo domečku) |
|
|
|
# (-1 tam, kde nikdo nemá domeček) |
|
|
|
protected_for = [[-1] * self.map_width for _ in range(self.map_height)] |
|
|
|
|
|
|
|
y = 0 |
|
|
|
for row in state["map"]: |
|
|
|
x = 0 |
|
|
|
for field in row: |
|
|
|
hills[y][x] = field["hill"] |
|
|
|
hft = field["home_for_team"] |
|
|
|
if hft is not None: |
|
|
|
for p in self.PROTECTED_AREA: |
|
|
|
protected_for[(y + p[0]) % self.map_height][(x + p[1]) % self.map_width] = hft |
|
|
|
if field["home_for_team"] is not None: |
|
|
|
home_positions[field["home_for_team"]] = [y, x] |
|
|
|
for member in field["members"]: |
|
|
@ -151,8 +169,9 @@ class Occupy(Logic): |
|
|
|
orig_x = id_positions[team_id][soldier_id][1] |
|
|
|
new_y = (orig_y + move_vect[0]) % self.map_height |
|
|
|
new_x = (orig_x + move_vect[1]) % self.map_width |
|
|
|
if hills[new_y][new_x]: |
|
|
|
# Voják se snažil lézt na skálu, zůstane na původním místě |
|
|
|
# Chráněné území nebo skála |
|
|
|
if (protected_for[new_y][new_x] > -1 and protected_for[new_y][new_x] != team_id) \ |
|
|
|
or hills[new_y][new_x]: |
|
|
|
soldier_lists[orig_y][orig_x][team_id].append(soldier_id) |
|
|
|
else: |
|
|
|
soldier_lists[new_y][new_x][team_id].append(soldier_id) |
|
|
@ -160,7 +179,9 @@ class Occupy(Logic): |
|
|
|
# Přidáme vojáky v homes: |
|
|
|
for team_id in range(self.teams_count): |
|
|
|
home_pos = home_positions[team_id] |
|
|
|
for i in range(self.bpr[(round_id + 1) % len(self.bpr)]): |
|
|
|
soldier_count = len(all_ids[team_id]) |
|
|
|
spawn_count = max(1, (self.budget_for_round(round_id) - soldier_count) // self.spawn_price) |
|
|
|
for i in range(spawn_count): |
|
|
|
soldier_lists[home_pos[0]][home_pos[1]][team_id].append(highest_ids[team_id] + i + 1) |
|
|
|
|
|
|
|
# Vojáci se pomlátí: |
|
|
@ -169,7 +190,12 @@ class Occupy(Logic): |
|
|
|
team_strengths = [len(soldier_lists[y][x][tid]) for tid in range(self.teams_count)] |
|
|
|
team_strengths.sort() |
|
|
|
for tid in range(self.teams_count): |
|
|
|
soldier_lists[y][x][tid] = soldier_lists[y][x][tid][team_strengths[-2]:] |
|
|
|
soldier_count = len(soldier_lists[y][x][tid]) |
|
|
|
if soldier_count <= team_strengths[-2]: |
|
|
|
soldier_lists[y][x][tid] = [] |
|
|
|
else: |
|
|
|
remaining_count = soldier_count - (team_strengths[-2]**2 // soldier_count) |
|
|
|
soldier_lists[y][x][tid] = soldier_lists[y][x][tid][0:remaining_count] |
|
|
|
|
|
|
|
# Vygenerujeme výsledek: |
|
|
|
score = [0] * self.teams_count |
|
|
@ -212,6 +238,8 @@ class Occupy(Logic): |
|
|
|
id_positions = {} |
|
|
|
# 2D array s `True`s tam, kde je hill |
|
|
|
hills = [[False] * self.map_width for _ in range(self.map_height)] |
|
|
|
# 2D array `True` na chráněných územích ostatních týmů |
|
|
|
protected = [[False] * self.map_width for _ in range(self.map_height)] |
|
|
|
# ID soldierů, se kterými tým už hnul |
|
|
|
ids_moved = {} |
|
|
|
|
|
|
@ -220,6 +248,9 @@ class Occupy(Logic): |
|
|
|
x = 0 |
|
|
|
for field in row: |
|
|
|
hills[y][x] = field["hill"] |
|
|
|
if field["home_for_team"] is not None and field["home_for_team"] != team_id: |
|
|
|
for p in self.PROTECTED_AREA: |
|
|
|
protected[(y + p[0]) % self.map_height][(x + p[1]) % self.map_width] = True |
|
|
|
for member in field["members"]: |
|
|
|
if member["team"] != team_id: |
|
|
|
continue |
|
|
@ -240,7 +271,9 @@ class Occupy(Logic): |
|
|
|
move_vect = self.MOVE_VECTORS[member["action"]] |
|
|
|
new_position_y = (id_positions[member["id"]][0] + move_vect[0]) % self.map_height |
|
|
|
new_position_x = (id_positions[member["id"]][1] + move_vect[1]) % self.map_width |
|
|
|
if hills[new_position_y][new_position_x]: |
|
|
|
if protected[new_position_y][new_position_x]: |
|
|
|
warns.append(self.generate_warn(member["id"], "Voják se snaží dostat do domečku cizího týmu. To není povoleno.")) |
|
|
|
elif hills[new_position_y][new_position_x]: |
|
|
|
warns.append(self.generate_warn(member["id"], "Voják se snaží vylézt na skálu, což nejde.")) |
|
|
|
|
|
|
|
if len(warns) == 0: |
|
|
|