|
@@ -18,39 +18,189 @@ class Base():
|
|
|
def __repr__(self):
|
|
def __repr__(self):
|
|
|
return f"<{self.__class__.__name__}: {self.__dict__}>"
|
|
return f"<{self.__class__.__name__}: {self.__dict__}>"
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-class Building(Base):
|
|
|
|
|
- def __init__(self, owner, type_, x, y):
|
|
|
|
|
|
|
+class BaseLoc(Base):
|
|
|
|
|
+ def __init__(self, x, y):
|
|
|
self.x = x
|
|
self.x = x
|
|
|
self.y = y
|
|
self.y = y
|
|
|
|
|
+
|
|
|
|
|
+ @property
|
|
|
|
|
+ def pos(self):
|
|
|
|
|
+ return self.x, self.y
|
|
|
|
|
+
|
|
|
|
|
+class Mine(BaseLoc):
|
|
|
|
|
+ def __init__(self, x, y):
|
|
|
|
|
+ super().__init__(x, y)
|
|
|
|
|
+
|
|
|
|
|
+class BaseOwnedLoc(BaseLoc):
|
|
|
|
|
+ def __init__(self, x, y, owner):
|
|
|
|
|
+ super().__init__(x, y)
|
|
|
self.owner = owner
|
|
self.owner = owner
|
|
|
|
|
+
|
|
|
|
|
+ @property
|
|
|
|
|
+ def owned(self):
|
|
|
|
|
+ return self.owner == 0
|
|
|
|
|
+
|
|
|
|
|
+class Building(BaseOwnedLoc):
|
|
|
|
|
+ def __init__(self, owner, type_, x, y):
|
|
|
|
|
+ super().__init__(x, y, owner)
|
|
|
self.type_ = type_
|
|
self.type_ = type_
|
|
|
|
|
|
|
|
-class Unit(Base):
|
|
|
|
|
|
|
+class Unit(BaseOwnedLoc):
|
|
|
def __init__(self, owner, id_, level, x, y):
|
|
def __init__(self, owner, id_, level, x, y):
|
|
|
- self.x = x
|
|
|
|
|
- self.y = y
|
|
|
|
|
- self.owner = owner
|
|
|
|
|
|
|
+ super().__init__(x, y, owner)
|
|
|
self.id_ = id_
|
|
self.id_ = id_
|
|
|
self.level = level
|
|
self.level = level
|
|
|
|
|
|
|
|
-mines = [[int(j) for j in input().split()] for _ in range(int(input()))]
|
|
|
|
|
|
|
+
|
|
|
|
|
+class Player(Base):
|
|
|
|
|
+ def __init__(self, id_):
|
|
|
|
|
+ self.id_ = id_
|
|
|
|
|
+ self.gold = 0
|
|
|
|
|
+ self.income = 0
|
|
|
|
|
+ self.units = []
|
|
|
|
|
+ self.buildings = []
|
|
|
|
|
+ self.hq = None
|
|
|
|
|
+
|
|
|
|
|
+ def update(self, gold, income, units, buildings):
|
|
|
|
|
+ self.gold = gold
|
|
|
|
|
+ self.income = income
|
|
|
|
|
+ self.units = [u for u in units if u.owner == self.id_]
|
|
|
|
|
+ self.buildings = [b for b in buildings if b.owner == self.id_]
|
|
|
|
|
+
|
|
|
|
|
+class Cell(Base):
|
|
|
|
|
+ def __init__(self, x, y):
|
|
|
|
|
+ self.x = x
|
|
|
|
|
+ self.y = y
|
|
|
|
|
+ self._content = "#"
|
|
|
|
|
+ self.unit = None
|
|
|
|
|
+ self.building = None
|
|
|
|
|
+
|
|
|
|
|
+ @property
|
|
|
|
|
+ def pos(self):
|
|
|
|
|
+ return self.x, self.y
|
|
|
|
|
+
|
|
|
|
|
+ @property
|
|
|
|
|
+ def raw_val(self):
|
|
|
|
|
+ return self._content
|
|
|
|
|
+
|
|
|
|
|
+ def update(self, content, unit = None, building = None):
|
|
|
|
|
+ self._content = content
|
|
|
|
|
+ self.unit = unit
|
|
|
|
|
+ self.building = building
|
|
|
|
|
+
|
|
|
|
|
+ @property
|
|
|
|
|
+ def movable(self):
|
|
|
|
|
+ return self._content != "#"
|
|
|
|
|
+
|
|
|
|
|
+ @property
|
|
|
|
|
+ def owned(self):
|
|
|
|
|
+ return self._content.lower() == "o"
|
|
|
|
|
+
|
|
|
|
|
+ @property
|
|
|
|
|
+ def opponents(self):
|
|
|
|
|
+ return self._content.lower() == "x"
|
|
|
|
|
+
|
|
|
|
|
+ @property
|
|
|
|
|
+ def headquarter(self):
|
|
|
|
|
+ return self.pos in Grid.hqs
|
|
|
|
|
+
|
|
|
|
|
+ @property
|
|
|
|
|
+ def occupied(self):
|
|
|
|
|
+ return self.unit or self.building
|
|
|
|
|
+
|
|
|
|
|
+ @property
|
|
|
|
|
+ def is_active(self):
|
|
|
|
|
+ return self._content.isupper()
|
|
|
|
|
+
|
|
|
|
|
+class Grid(Base):
|
|
|
|
|
+ dim = 12
|
|
|
|
|
+ hqs = [(0,0), (11,11)]
|
|
|
|
|
+
|
|
|
|
|
+ def __init__(self, mines = []):
|
|
|
|
|
+ self.cells = {(x, y): Cell(x, y) for x in range(Grid.dim) for y in range(Grid.dim)}
|
|
|
|
|
+ self.units = {}
|
|
|
|
|
+ self.buildings = {}
|
|
|
|
|
+ self.mines = {(m.x, m.y): m for m in mines}
|
|
|
|
|
+
|
|
|
|
|
+ def print_grid(self):
|
|
|
|
|
+ return "\n".join(["".join([c for c in row]) for row in self.grid])
|
|
|
|
|
+
|
|
|
|
|
+ @property
|
|
|
|
|
+ def pos(self):
|
|
|
|
|
+ return self.x, self.y
|
|
|
|
|
+
|
|
|
|
|
+ @property
|
|
|
|
|
+ def grid(self):
|
|
|
|
|
+ return [[self.cells[(x, y)].raw_val for x in range(Grid.dim)] for y in range(Grid.dim)]
|
|
|
|
|
+
|
|
|
|
|
+ def __getitem__(self, key):
|
|
|
|
|
+ return self.cells[key]
|
|
|
|
|
+
|
|
|
|
|
+ def update(self, grid, buildings, units):
|
|
|
|
|
+ self.buildings = {(b.x, b.y): b for b in buildings}
|
|
|
|
|
+ self.units = {(u.x, u.y): u for u in units}
|
|
|
|
|
+
|
|
|
|
|
+ for y, row in enumerate(grid):
|
|
|
|
|
+ for x, c in enumerate(row):
|
|
|
|
|
+ self.cells[(x, y)].update(c,
|
|
|
|
|
+ self.units.get((x, y), None),
|
|
|
|
|
+ self.buildings.get((x, y), None))
|
|
|
|
|
+
|
|
|
|
|
+ def neighbors(self, x, y, diags=True):
|
|
|
|
|
+ neighs = [(x, y - 1), (x - 1, y), (x + 1, y), (x, y + 1)]
|
|
|
|
|
+ if diags:
|
|
|
|
|
+ neighs += [(x - 1, y - 1), (x + 1, y - 1), (x - 1, y + 1), (x + 1, y + 1)]
|
|
|
|
|
+ return [(x, y) for x, y in neighs if 0 <= x < Grid.dim and 0 <= y < Grid.dim]
|
|
|
|
|
+
|
|
|
|
|
+ def where_to_train(self):
|
|
|
|
|
+ available = set()
|
|
|
|
|
+ for p, c in self.cells.items():
|
|
|
|
|
+ if c.owned:
|
|
|
|
|
+ available.add(p)
|
|
|
|
|
+ available |= set(self.neighbors(*p))
|
|
|
|
|
+ return (self.cells[p] for p in available if not self.cells[p].occupied)
|
|
|
|
|
+
|
|
|
|
|
+mines = [Mine(*[int(j) for j in input().split()]) for _ in range(int(input()))]
|
|
|
log(f"* mines: {mines}")
|
|
log(f"* mines: {mines}")
|
|
|
|
|
|
|
|
|
|
+grid = Grid()
|
|
|
|
|
+player = Player(0)
|
|
|
|
|
+opponent = Player(1)
|
|
|
|
|
+
|
|
|
while True:
|
|
while True:
|
|
|
- gold, income = int(input()), int(input())
|
|
|
|
|
- log(f"* gold: {gold} / +{income}")
|
|
|
|
|
|
|
|
|
|
|
|
+ # <--- get input
|
|
|
|
|
+ gold, income = int(input()), int(input())
|
|
|
opponent_gold, opponent_income = int(input()), int(input())
|
|
opponent_gold, opponent_income = int(input()), int(input())
|
|
|
- log(f"* opponent's gold: {opponent_gold} / +{opponent_income}")
|
|
|
|
|
-
|
|
|
|
|
- grid = [input().split() for _ in range(12)]
|
|
|
|
|
- log("* grid: {}".format("\n".join([" ".join(row) for row in grid])))
|
|
|
|
|
|
|
+ new_grid = [list(input()) for _ in range(12)]
|
|
|
|
|
|
|
|
buildings = [Building(*[int(j) for j in input().split()]) for _ in range(int(input()))]
|
|
buildings = [Building(*[int(j) for j in input().split()]) for _ in range(int(input()))]
|
|
|
log(f"* buildings: {buildings}")
|
|
log(f"* buildings: {buildings}")
|
|
|
|
|
|
|
|
units = [Unit(*[int(j) for j in input().split()]) for _ in range(int(input()))]
|
|
units = [Unit(*[int(j) for j in input().split()]) for _ in range(int(input()))]
|
|
|
log(f"* units: {units}")
|
|
log(f"* units: {units}")
|
|
|
|
|
+ # --->
|
|
|
|
|
+
|
|
|
|
|
+ # <--- update data
|
|
|
|
|
+ grid.update(new_grid, buildings, units)
|
|
|
|
|
+ log(f"grid:\n{grid.print_grid()}")
|
|
|
|
|
+
|
|
|
|
|
+ player.update(gold, income, units, buildings)
|
|
|
|
|
+ if player.hq is None:
|
|
|
|
|
+ player.hq = next((c for c in [grid[(x, y)] for x, y in Grid.hqs] if c.owned))
|
|
|
|
|
+ log(f"player:\n{player}")
|
|
|
|
|
+
|
|
|
|
|
+ opponent.update(opponent_gold, opponent_income, units, buildings)
|
|
|
|
|
+ if opponent.hq is None:
|
|
|
|
|
+ opponent.hq = next((c for c in [grid[(x, y)] for x, y in Grid.hqs] if c.opponents))
|
|
|
|
|
+ log(f"opponent:\n{opponent}")
|
|
|
|
|
+ # --->
|
|
|
|
|
+
|
|
|
|
|
+ # start
|
|
|
|
|
+
|
|
|
|
|
+ if not player.units:
|
|
|
|
|
+ c = next(grid.where_to_train())
|
|
|
|
|
+ print(f"TRAIN 1 {c.x} {c.y}")
|
|
|
|
|
+
|
|
|
|
|
|
|
|
print("WAIT")
|
|
print("WAIT")
|