|
@ -45,8 +45,8 @@ class Occupy(Logic): |
|
|
self.teams_width = configuration["teams_width"] |
|
|
self.teams_width = configuration["teams_width"] |
|
|
self.teams_height = configuration["teams_height"] |
|
|
self.teams_height = configuration["teams_height"] |
|
|
assert(teams_count == self.teams_width * self.teams_height) |
|
|
assert(teams_count == self.teams_width * self.teams_height) |
|
|
self.map_width = self.teams_width * configuration["width_per_team"] |
|
|
self.world_width = self.teams_width * configuration["width_per_team"] |
|
|
self.map_height = self.teams_height * configuration["height_per_team"] |
|
|
self.world_height = self.teams_height * configuration["height_per_team"] |
|
|
# Parametry k počtu nových vojáků |
|
|
# Parametry k počtu nových vojáků |
|
|
self.rounds_total = configuration["initial_remaining_rounds"] |
|
|
self.rounds_total = configuration["initial_remaining_rounds"] |
|
|
self.spawn_price = configuration["spawn_price"] |
|
|
self.spawn_price = configuration["spawn_price"] |
|
@ -65,7 +65,7 @@ class Occupy(Logic): |
|
|
|
|
|
|
|
|
# Počáteční stav |
|
|
# Počáteční stav |
|
|
def zero_state(self) -> Any: |
|
|
def zero_state(self) -> Any: |
|
|
map = [ |
|
|
world = [ |
|
|
[ |
|
|
[ |
|
|
{ |
|
|
{ |
|
|
"home_for_team": None, |
|
|
"home_for_team": None, |
|
@ -77,27 +77,27 @@ class Occupy(Logic): |
|
|
== "x"), |
|
|
== "x"), |
|
|
"members": [] |
|
|
"members": [] |
|
|
} |
|
|
} |
|
|
for i in range(self.map_width) |
|
|
for i in range(self.world_width) |
|
|
] |
|
|
] |
|
|
for j in range(self.map_height) |
|
|
for j in range(self.world_height) |
|
|
] |
|
|
] |
|
|
team_id = 0 |
|
|
team_id = 0 |
|
|
home_y = self.configuration["height_per_team"] // 2 |
|
|
home_y = self.configuration["height_per_team"] // 2 |
|
|
for _ in range(self.teams_height): |
|
|
for _ in range(self.teams_height): |
|
|
home_x = self.configuration["width_per_team"] // 2 |
|
|
home_x = self.configuration["width_per_team"] // 2 |
|
|
for _ in range(self.teams_width): |
|
|
for _ in range(self.teams_width): |
|
|
map[home_y][home_x]["home_for_team"] = team_id |
|
|
world[home_y][home_x]["home_for_team"] = team_id |
|
|
map[home_y][home_x]["occupied_by_team"] = team_id |
|
|
world[home_y][home_x]["occupied_by_team"] = team_id |
|
|
for x, y in self.PROTECTED_AREA: |
|
|
for x, y in self.PROTECTED_AREA: |
|
|
map[(home_y+y) % self.map_height][(home_x+x) % self.map_width]["protected_for_team"] = team_id |
|
|
world[(home_y+y) % self.world_height][(home_x+x) % self.world_width]["protected_for_team"] = team_id |
|
|
# Initial stav vojáků: |
|
|
# Initial stav vojáků: |
|
|
for soldier_id in range(max(1, self.budget_for_round(0) // self.spawn_price)): |
|
|
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)) |
|
|
world[home_y][home_x]["members"].append(self.generate_soldier(team_id, soldier_id)) |
|
|
team_id += 1 |
|
|
team_id += 1 |
|
|
home_x += self.configuration["width_per_team"] |
|
|
home_x += self.configuration["width_per_team"] |
|
|
home_y += self.configuration["height_per_team"] |
|
|
home_y += self.configuration["height_per_team"] |
|
|
|
|
|
|
|
|
return {"map": map} |
|
|
return {"world": world} |
|
|
|
|
|
|
|
|
# Zatím očekávám, že moves má takovéto prvky: |
|
|
# Zatím očekávám, že moves má takovéto prvky: |
|
|
# { |
|
|
# { |
|
@ -128,20 +128,20 @@ class Occupy(Logic): |
|
|
# homes jednotlivých týmů |
|
|
# homes jednotlivých týmů |
|
|
home_positions = [None] * self.teams_count |
|
|
home_positions = [None] * self.teams_count |
|
|
# 2D array s `True`s tam, kde je hill |
|
|
# 2D array s `True`s tam, kde je hill |
|
|
hills = [[False] * self.map_width for _ in range(self.map_height)] |
|
|
hills = [[False] * self.world_width for _ in range(self.world_height)] |
|
|
# 2D array s ID týmu, který zde má chráněné území (okolo domečku) |
|
|
# 2D array s ID týmu, který zde má chráněné území (okolo domečku) |
|
|
# (-1 tam, kde nikdo nemá domeček) |
|
|
# (-1 tam, kde nikdo nemá domeček) |
|
|
protected_for = [[-1] * self.map_width for _ in range(self.map_height)] |
|
|
protected_for = [[-1] * self.world_width for _ in range(self.world_height)] |
|
|
|
|
|
|
|
|
y = 0 |
|
|
y = 0 |
|
|
for row in state["map"]: |
|
|
for row in state["world"]: |
|
|
x = 0 |
|
|
x = 0 |
|
|
for field in row: |
|
|
for field in row: |
|
|
hills[y][x] = field["hill"] |
|
|
hills[y][x] = field["hill"] |
|
|
hft = field["home_for_team"] |
|
|
hft = field["home_for_team"] |
|
|
if hft is not None: |
|
|
if hft is not None: |
|
|
for p in self.PROTECTED_AREA: |
|
|
for p in self.PROTECTED_AREA: |
|
|
protected_for[(y + p[0]) % self.map_height][(x + p[1]) % self.map_width] = hft |
|
|
protected_for[(y + p[0]) % self.world_height][(x + p[1]) % self.world_width] = hft |
|
|
if field["home_for_team"] is not None: |
|
|
if field["home_for_team"] is not None: |
|
|
home_positions[field["home_for_team"]] = [y, x] |
|
|
home_positions[field["home_for_team"]] = [y, x] |
|
|
for member in field["members"]: |
|
|
for member in field["members"]: |
|
@ -162,16 +162,16 @@ class Occupy(Logic): |
|
|
|
|
|
|
|
|
# Místo mapy tabulka seznamů vojáků pro každý tým |
|
|
# Místo mapy tabulka seznamů vojáků pro každý tým |
|
|
soldier_lists = [ |
|
|
soldier_lists = [ |
|
|
[[[] for _ in range(self.teams_count)] for _ in range(self.map_width)] |
|
|
[[[] for _ in range(self.teams_count)] for _ in range(self.world_width)] |
|
|
for _ in range(self.map_height) |
|
|
for _ in range(self.world_height) |
|
|
] |
|
|
] |
|
|
for team_id in range(self.teams_count): |
|
|
for team_id in range(self.teams_count): |
|
|
for soldier_id in all_ids[team_id]: |
|
|
for soldier_id in all_ids[team_id]: |
|
|
move_vect = self.MOVE_VECTORS[id_moves[team_id][soldier_id]] |
|
|
move_vect = self.MOVE_VECTORS[id_moves[team_id][soldier_id]] |
|
|
orig_y = id_positions[team_id][soldier_id][0] |
|
|
orig_y = id_positions[team_id][soldier_id][0] |
|
|
orig_x = id_positions[team_id][soldier_id][1] |
|
|
orig_x = id_positions[team_id][soldier_id][1] |
|
|
new_y = (orig_y + move_vect[0]) % self.map_height |
|
|
new_y = (orig_y + move_vect[0]) % self.world_height |
|
|
new_x = (orig_x + move_vect[1]) % self.map_width |
|
|
new_x = (orig_x + move_vect[1]) % self.world_width |
|
|
# Chráněné území nebo skála |
|
|
# Chráněné území nebo skála |
|
|
if (protected_for[new_y][new_x] > -1 and protected_for[new_y][new_x] != team_id) \ |
|
|
if (protected_for[new_y][new_x] > -1 and protected_for[new_y][new_x] != team_id) \ |
|
|
or hills[new_y][new_x]: |
|
|
or hills[new_y][new_x]: |
|
@ -188,8 +188,8 @@ class Occupy(Logic): |
|
|
soldier_lists[home_pos[0]][home_pos[1]][team_id].append(highest_ids[team_id] + i + 1) |
|
|
soldier_lists[home_pos[0]][home_pos[1]][team_id].append(highest_ids[team_id] + i + 1) |
|
|
|
|
|
|
|
|
# Vojáci se pomlátí: |
|
|
# Vojáci se pomlátí: |
|
|
for y in range(self.map_height): |
|
|
for y in range(self.world_height): |
|
|
for x in range(self.map_width): |
|
|
for x in range(self.world_width): |
|
|
team_strengths = [len(soldier_lists[y][x][tid]) for tid in range(self.teams_count)] |
|
|
team_strengths = [len(soldier_lists[y][x][tid]) for tid in range(self.teams_count)] |
|
|
team_strengths.sort() |
|
|
team_strengths.sort() |
|
|
for tid in range(self.teams_count): |
|
|
for tid in range(self.teams_count): |
|
@ -202,9 +202,9 @@ class Occupy(Logic): |
|
|
|
|
|
|
|
|
# Vygenerujeme výsledek: |
|
|
# Vygenerujeme výsledek: |
|
|
score = [0] * self.teams_count |
|
|
score = [0] * self.teams_count |
|
|
new_map = [[] for _ in range(self.map_height)] |
|
|
new_world = [[] for _ in range(self.world_height)] |
|
|
y = 0 |
|
|
y = 0 |
|
|
for row in state["map"]: |
|
|
for row in state["world"]: |
|
|
x = 0 |
|
|
x = 0 |
|
|
for field in row: |
|
|
for field in row: |
|
|
new_field = { |
|
|
new_field = { |
|
@ -220,10 +220,10 @@ class Occupy(Logic): |
|
|
new_field["occupied_by_team"] = team_id |
|
|
new_field["occupied_by_team"] = team_id |
|
|
if new_field["occupied_by_team"] is not None: |
|
|
if new_field["occupied_by_team"] is not None: |
|
|
score[new_field["occupied_by_team"]] += 1 |
|
|
score[new_field["occupied_by_team"]] += 1 |
|
|
new_map[y].append(new_field) |
|
|
new_world[y].append(new_field) |
|
|
x += 1 |
|
|
x += 1 |
|
|
y += 1 |
|
|
y += 1 |
|
|
return ({"map": new_map}, score) |
|
|
return ({"world": new_world}, score) |
|
|
|
|
|
|
|
|
def generate_warn(self, member_id, description): |
|
|
def generate_warn(self, member_id, description): |
|
|
return { |
|
|
return { |
|
@ -241,20 +241,20 @@ class Occupy(Logic): |
|
|
# souřadnice IDs daného týmu |
|
|
# souřadnice IDs daného týmu |
|
|
id_positions = {} |
|
|
id_positions = {} |
|
|
# 2D array s `True`s tam, kde je hill |
|
|
# 2D array s `True`s tam, kde je hill |
|
|
hills = [[False] * self.map_width for _ in range(self.map_height)] |
|
|
hills = [[False] * self.world_width for _ in range(self.world_height)] |
|
|
# 2D array `True` na chráněných územích ostatních týmů |
|
|
# 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)] |
|
|
protected = [[False] * self.world_width for _ in range(self.world_height)] |
|
|
# ID soldierů, se kterými tým už hnul |
|
|
# ID soldierů, se kterými tým už hnul |
|
|
ids_moved = {} |
|
|
ids_moved = {} |
|
|
|
|
|
|
|
|
y = 0 |
|
|
y = 0 |
|
|
for row in state["map"]: |
|
|
for row in state["world"]: |
|
|
x = 0 |
|
|
x = 0 |
|
|
for field in row: |
|
|
for field in row: |
|
|
hills[y][x] = field["hill"] |
|
|
hills[y][x] = field["hill"] |
|
|
if field["home_for_team"] is not None and field["home_for_team"] != team_id: |
|
|
if field["home_for_team"] is not None and field["home_for_team"] != team_id: |
|
|
for p in self.PROTECTED_AREA: |
|
|
for p in self.PROTECTED_AREA: |
|
|
protected[(y + p[0]) % self.map_height][(x + p[1]) % self.map_width] = True |
|
|
protected[(y + p[0]) % self.world_height][(x + p[1]) % self.world_width] = True |
|
|
for member in field["members"]: |
|
|
for member in field["members"]: |
|
|
if member["team"] != team_id: |
|
|
if member["team"] != team_id: |
|
|
continue |
|
|
continue |
|
@ -273,8 +273,8 @@ class Occupy(Logic): |
|
|
if member["action"] is None: |
|
|
if member["action"] is None: |
|
|
continue |
|
|
continue |
|
|
move_vect = self.MOVE_VECTORS[member["action"]] |
|
|
move_vect = self.MOVE_VECTORS[member["action"]] |
|
|
new_position_y = (id_positions[member["id"]][0] + move_vect[0]) % self.map_height |
|
|
new_position_y = (id_positions[member["id"]][0] + move_vect[0]) % self.world_height |
|
|
new_position_x = (id_positions[member["id"]][1] + move_vect[1]) % self.map_width |
|
|
new_position_x = (id_positions[member["id"]][1] + move_vect[1]) % self.world_width |
|
|
if protected[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.")) |
|
|
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]: |
|
|
elif hills[new_position_y][new_position_x]: |
|
@ -287,7 +287,7 @@ class Occupy(Logic): |
|
|
|
|
|
|
|
|
def home_position(self, state: Any, team_id): |
|
|
def home_position(self, state: Any, team_id): |
|
|
y = 0 |
|
|
y = 0 |
|
|
for row in state["map"]: |
|
|
for row in state["world"]: |
|
|
x = 0 |
|
|
x = 0 |
|
|
for field in row: |
|
|
for field in row: |
|
|
if field["home_for_team"] == team_id: |
|
|
if field["home_for_team"] == team_id: |
|
@ -300,17 +300,17 @@ class Occupy(Logic): |
|
|
def personalize_state(self, state: Any, team_id: int, round_id: int) -> Any: |
|
|
def personalize_state(self, state: Any, team_id: int, round_id: int) -> Any: |
|
|
# Zjisti pozici domečku tohoto týmu: |
|
|
# Zjisti pozici domečku tohoto týmu: |
|
|
home_yx = self.home_position(state, team_id) |
|
|
home_yx = self.home_position(state, team_id) |
|
|
y_diff = (self.map_height // 2) - home_yx[0] |
|
|
y_diff = (self.world_height // 2) - home_yx[0] |
|
|
x_diff = (self.map_width // 2) - home_yx[1] |
|
|
x_diff = (self.world_width // 2) - home_yx[1] |
|
|
|
|
|
|
|
|
# Vycentruj: |
|
|
# Vycentruj: |
|
|
map_personalized = [ |
|
|
world_personalized = [ |
|
|
[ |
|
|
[ |
|
|
state["map"][(y - y_diff) % self.map_height][(x - x_diff) % self.map_width] |
|
|
state["world"][(y - y_diff) % self.world_height][(x - x_diff) % self.world_width] |
|
|
for x in range(self.map_width) |
|
|
for x in range(self.world_width) |
|
|
] |
|
|
] |
|
|
for y in range(self.map_height) |
|
|
for y in range(self.world_height) |
|
|
] |
|
|
] |
|
|
|
|
|
|
|
|
return {"map": map_personalized} |
|
|
return {"world": world_personalized} |
|
|
|
|
|
|
|
|