Strategická: úpravy logiky
Ochrana domečků, nová úmrtnost při bitvách, spawnování závislé na aktuálním počtu vojáků
This commit is contained in:
		
							parent
							
								
									226d897eca
								
							
						
					
					
						commit
						748a640b83
					
				
					 2 changed files with 46 additions and 9 deletions
				
			
		|  | @ -106,7 +106,11 @@ Metadata | ||||||
| 
 | 
 | ||||||
| 	# S možnou změnou | 	# S možnou změnou | ||||||
| 	initial_remaining_rounds: <int> | 	initial_remaining_rounds: <int> | ||||||
| 	born_per_round: <List[int]> # pro každý tah počet, pokud je kratší, uvažujeme cyklicky | 	# Parametry k počtu nových vojáků | ||||||
|  | 	# Pomyslná cena *nového* vojáka | ||||||
|  | 	spawn_price: <int> | ||||||
|  | 	# Na kolik nových spawnů bude stačit obnos "peněz" v posledním kole | ||||||
|  | 	last_spawn: <int> | ||||||
| } | } | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -33,6 +33,12 @@ class Occupy(Logic): | ||||||
|         "up": (-1, 0), |         "up": (-1, 0), | ||||||
|         "down": (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): |     def __init__(self, teams_count: int, configuration: Any): | ||||||
|         super().__init__(teams_count, configuration) |         super().__init__(teams_count, configuration) | ||||||
|  | @ -41,8 +47,10 @@ class Occupy(Logic): | ||||||
|         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.map_width = self.teams_width * configuration["width_per_team"] | ||||||
|         self.map_height = self.teams_height * configuration["height_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 |         # Parametry k počtu nových vojáků | ||||||
|         self.bpr = self.configuration["born_per_round"] |         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): |     def generate_soldier(self, team_id, soldier_id): | ||||||
|         return { |         return { | ||||||
|  | @ -52,6 +60,9 @@ class Occupy(Logic): | ||||||
|             "remaining_rounds": 1 |             "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 |     # Počáteční stav | ||||||
|     def zero_state(self) -> Any: |     def zero_state(self) -> Any: | ||||||
|         map = [ |         map = [ | ||||||
|  | @ -77,7 +88,7 @@ class Occupy(Logic): | ||||||
|                 map[home_y][home_x]["home_for_team"] = team_id |                 map[home_y][home_x]["home_for_team"] = team_id | ||||||
|                 map[home_y][home_x]["occupied_by_team"] = team_id |                 map[home_y][home_x]["occupied_by_team"] = team_id | ||||||
|                 # Initial stav vojáků: |                 # 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)) |                     map[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"] | ||||||
|  | @ -115,12 +126,19 @@ class Occupy(Logic): | ||||||
|         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.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 |         y = 0 | ||||||
|         for row in state["map"]: |         for row in state["map"]: | ||||||
|             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"] | ||||||
|  |                 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: |                 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"]: | ||||||
|  | @ -151,8 +169,9 @@ class Occupy(Logic): | ||||||
|                 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.map_height | ||||||
|                 new_x = (orig_x + move_vect[1]) % self.map_width |                 new_x = (orig_x + move_vect[1]) % self.map_width | ||||||
|                 if hills[new_y][new_x]: |                 # Chráněné území nebo skála | ||||||
|                     # Voják se snažil lézt na skálu, zůstane na původním místě |                 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) |                     soldier_lists[orig_y][orig_x][team_id].append(soldier_id) | ||||||
|                 else: |                 else: | ||||||
|                     soldier_lists[new_y][new_x][team_id].append(soldier_id) |                     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: |         # Přidáme vojáky v homes: | ||||||
|         for team_id in range(self.teams_count): |         for team_id in range(self.teams_count): | ||||||
|             home_pos = home_positions[team_id] |             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) |                 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í: | ||||||
|  | @ -169,7 +190,12 @@ class Occupy(Logic): | ||||||
|                 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): | ||||||
|                     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: |         # Vygenerujeme výsledek: | ||||||
|         score = [0] * self.teams_count |         score = [0] * self.teams_count | ||||||
|  | @ -212,6 +238,8 @@ class Occupy(Logic): | ||||||
|         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.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 |         # ID soldierů, se kterými tým už hnul | ||||||
|         ids_moved = {} |         ids_moved = {} | ||||||
| 
 | 
 | ||||||
|  | @ -220,6 +248,9 @@ class Occupy(Logic): | ||||||
|             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: | ||||||
|  |                     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"]: |                 for member in field["members"]: | ||||||
|                     if member["team"] != team_id: |                     if member["team"] != team_id: | ||||||
|                         continue |                         continue | ||||||
|  | @ -240,7 +271,9 @@ class Occupy(Logic): | ||||||
|             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.map_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.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.")) |                 warns.append(self.generate_warn(member["id"], "Voják se snaží vylézt na skálu, což nejde.")) | ||||||
|          |          | ||||||
|         if len(warns) == 0: |         if len(warns) == 0: | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Martin Koreček
						Martin Koreček