|
|
@ -1,6 +1,7 @@ |
|
|
|
#!/usr/bin/env python3 |
|
|
|
import argparse |
|
|
|
import time |
|
|
|
from typing import Callable, List, Optional, Tuple |
|
|
|
from client import get_state, send_turn, logger, TIME_BEFORE_RETRY |
|
|
|
|
|
|
|
|
|
|
@ -12,6 +13,27 @@ parser.add_argument("--log_level", type=str, default="WARNING", choices=["ERROR" |
|
|
|
# you can add your own arguments, the strategy function will get them |
|
|
|
|
|
|
|
|
|
|
|
Coords = Tuple[int, int] |
|
|
|
|
|
|
|
|
|
|
|
class Member: |
|
|
|
def __init__(self, team: int, id: int, remaining_rounds: int): |
|
|
|
self.team = team |
|
|
|
self.id = id |
|
|
|
self.remaining_rounds = remaining_rounds |
|
|
|
self.action: Optional[str] = None |
|
|
|
|
|
|
|
|
|
|
|
class Field: |
|
|
|
def __init__(self, home_for_team: Optional[int], |
|
|
|
occupied_by_team: Optional[int], |
|
|
|
hill: bool, members: List[Member]): |
|
|
|
self.home_for_team = home_for_team |
|
|
|
self.occupied_by_team = occupied_by_team |
|
|
|
self.hill = hill |
|
|
|
self.members = members |
|
|
|
|
|
|
|
|
|
|
|
def strategy(team_id: int, state: dict, args: argparse.Namespace) -> dict: |
|
|
|
"""Finds the best move for the given state. |
|
|
|
|
|
|
@ -46,7 +68,75 @@ def strategy(team_id: int, state: dict, args: argparse.Namespace) -> dict: |
|
|
|
} |
|
|
|
``` |
|
|
|
""" |
|
|
|
return {} |
|
|
|
|
|
|
|
world = parse_world(state["map"]) |
|
|
|
home = find_fields(world, lambda f: f.home_for_team == team_id)[0][1] |
|
|
|
members = find_members(world, lambda m: m.team == team_id) |
|
|
|
|
|
|
|
# TODO: implement your strategy here |
|
|
|
for member, coords in members: |
|
|
|
member.action = "up" |
|
|
|
return build_turn(members) |
|
|
|
|
|
|
|
|
|
|
|
def find_fields( |
|
|
|
world: List[List[Field]], |
|
|
|
predicate: Callable[[Field], bool] |
|
|
|
) -> List[Tuple[Field, Coords]]: |
|
|
|
"""Finds all fields that satisfy the given predicate.""" |
|
|
|
|
|
|
|
result = [] |
|
|
|
for y, row in enumerate(world): |
|
|
|
for x, field in enumerate(row): |
|
|
|
if predicate(field): |
|
|
|
result.append((field, (x, y))) |
|
|
|
return result |
|
|
|
|
|
|
|
|
|
|
|
def find_members( |
|
|
|
world: List[List[Field]], |
|
|
|
predicate: Callable[[Member], bool] |
|
|
|
) -> List[Tuple[Member, Coords]]: |
|
|
|
"""Finds all members that satisfy the given predicate.""" |
|
|
|
|
|
|
|
result = [] |
|
|
|
for y, row in enumerate(world): |
|
|
|
for x, field in enumerate(row): |
|
|
|
for member in field.members: |
|
|
|
if predicate(member): |
|
|
|
result.append((member, (x, y))) |
|
|
|
return result |
|
|
|
|
|
|
|
|
|
|
|
def build_turn(members: List[Member]) -> dict: |
|
|
|
return { |
|
|
|
"members": [ |
|
|
|
{"id": member.id, "action": member.action} |
|
|
|
for member in members |
|
|
|
] |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
def parse_world(world: dict) -> List[List[Field]]: |
|
|
|
fields = [] |
|
|
|
for row in world: |
|
|
|
fields_row = [] |
|
|
|
for field in row: |
|
|
|
members = [] |
|
|
|
for member in field["members"]: |
|
|
|
members.append(Member( |
|
|
|
member["team"], |
|
|
|
member["id"], |
|
|
|
member["remaining_rounds"] |
|
|
|
)) |
|
|
|
fields_row.append(Field( |
|
|
|
field["home_for_team"], |
|
|
|
field["occupied_by_team"], |
|
|
|
field["hill"], |
|
|
|
members |
|
|
|
)) |
|
|
|
fields.append(fields_row) |
|
|
|
return fields |
|
|
|
|
|
|
|
|
|
|
|
def main(args: argparse.Namespace): |
|
|
|