philRG

Vindinium starter

Aug 22nd, 2021 (edited)
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.65 KB | None | 0 0
  1. import random
  2. import sys
  3. import math
  4. import time
  5. from enum import Enum
  6. from typing import Tuple, List, Optional
  7.  
  8. MAXLIFE = 100
  9.  
  10.  
  11. def idebug(*args):
  12.     return
  13.     print(*args, file=sys.stderr, flush=True)
  14.  
  15.  
  16. def debug(*args):
  17.     # return
  18.     print(*args, file=sys.stderr, flush=True)
  19.  
  20.  
  21. # Four legendary heroes were fighting for the land of Vindinium
  22. # Making their way in the dangerous woods
  23. # Slashing goblins and stealing gold mines
  24. # And looking for a tavern where to drink their gold
  25.  
  26. class Type(Enum):
  27.     AIR = '.'
  28.     WALL = '#'
  29.     TAVERN = 'T'
  30.     MINE = 'M'
  31.  
  32.  
  33. class Tile:
  34.     __slots__ = ['type', 'x', 'y', 'mine']
  35.  
  36.     def __init__(self, type: Type, x: int, y: int):
  37.         self.type = type
  38.         self.x = x
  39.         self.y = y
  40.         self.mine: Mine = None
  41.  
  42.     def distance(self, t):
  43.         dx = self.x - t.x
  44.         dy = self.y - t.y
  45.         return math.sqrt(dx * dx + dy * dy)
  46.  
  47.     def __repr__(self):
  48.         # return f'({self.x},{self.y})'
  49.         return f'{self.type} ({self.x},{self.y})'
  50.  
  51.  
  52. class Mine:
  53.     __slots__ = ['tile', 'owner']
  54.  
  55.     def __init__(self, tile: Tile):
  56.         self.tile = tile
  57.         self.owner: Hero = None
  58.  
  59.     def conquer(self, hero):
  60.         self.owner = hero
  61.  
  62.     def __repr__(self):
  63.         return f'MINE on ({self.tile.x}, {self.tile.y}) belongs to {self.owner}'
  64.  
  65.  
  66. class Hero:
  67.     __slots__ = ['player_id', 'spawn_pos', 'tile', 'life', 'gold']
  68.  
  69.     def __init__(self, player_id: int, spawn_pos: Tile = None):
  70.         self.player_id = player_id
  71.         self.spawn_pos = spawn_pos
  72.         self.tile = spawn_pos
  73.         self.life = MAXLIFE
  74.         self.gold = 0
  75.  
  76.     def update(self, x: int, y: int, life: int, gold: int):
  77.         self.tile = [t for t in board if (t.x, t.y) == (x, y)][0]
  78.         self.life, self.gold = life, gold
  79.  
  80.     def __repr__(self):
  81.         return f'HERO {self.player_id} {self.tile} {self.life} {self.gold}'
  82.  
  83.  
  84. board = []
  85. players = []
  86. mines = []
  87.  
  88. for i in range(4):
  89.     players.append(Hero(player_id=i))
  90.  
  91. size = int(input())
  92. idebug(size)
  93. for i in range(size):
  94.     line = input()
  95.     idebug(line)
  96.     for j, c in enumerate(line):
  97.         try:
  98.             c = int(c)
  99.             tile = Tile(type=Type.AIR, x=j, y=i)
  100.             hero = players[c]
  101.             hero.spawn_pos = tile
  102.             hero.tile = tile
  103.         except ValueError:
  104.             if Type(c) == Type.MINE:
  105.                 tile = Tile(type=Type.MINE, x=j, y=i)
  106.                 mines.append(Mine(tile))
  107.             else:
  108.                 tile = Tile(type=Type(c), x=j, y=i)
  109.         finally:
  110.             board.append(tile)
  111.  
  112. taverns = [t for t in board if t.type == Type.TAVERN]
  113. walls = [t for t in board if t.type == Type.WALL]
  114.  
  115. my_id = int(input())  # ID of your hero
  116. idebug(my_id)
  117.  
  118. me = [h for h in players if h.player_id == my_id][0]
  119.  
  120. # game loop
  121. while True:
  122.     entity_count = int(input())  # the number of entities
  123.     idebug(entity_count)
  124.     for i in range(entity_count):
  125.         line = input()
  126.         idebug(line)
  127.         inputs = line.split()
  128.         entity_type = inputs[0]  # HERO or MINE
  129.         _id = int(inputs[1])  # the ID of a hero or the owner of a mine
  130.         x = int(inputs[2])  # the x position of the entity
  131.         y = int(inputs[3])  # the y position of the entity
  132.         life = int(inputs[4])  # the life of a hero (-1 for mines)
  133.         gold = int(inputs[5])  # the gold of a hero (-1 for mines)
  134.         if entity_type == 'HERO':
  135.             hero = players[_id]
  136.             hero.update(x, y, life, gold)
  137.         else:
  138.             mine = [m for m in mines if (m.tile.x, m.tile.y) == (x, y)][0]
  139.             mine.conquer(_id)
  140.  
  141.     # Write an action using print
  142.     # To debug: print("Debug messages...", file=sys.stderr, flush=True)
  143.     for hero in players:
  144.         debug(hero)
  145.  
  146.     for mine in mines:
  147.         debug(mine)
  148.  
  149.     # WAIT | NORTH | EAST | SOUTH | WEST
  150.     if me.life <= 20:
  151.         taverns_candidates = [(t, me.tile.distance(t)) for t in taverns]
  152.         closest_tavern = min(taverns_candidates, key=lambda x: x[1])[0]
  153.         action = f'MOVE {closest_tavern.x} {closest_tavern.y}'
  154.     else:
  155.         mines_to_conquer_candidates = [(m, me.tile.distance(m.tile) - m.owner / abs(m.owner) * 2) for m in mines if m.owner != my_id]
  156.         if mines_to_conquer_candidates:
  157.             closest_mine_to_conquer = min(mines_to_conquer_candidates, key=lambda x: x[1])[0]
  158.             action = f'MOVE {closest_mine_to_conquer.tile.x} {closest_mine_to_conquer.tile.y}'
  159.         else:
  160.             heroes_to_fight_candidates = [(h, (me.life - h.life) / (1 + me.tile.distance(h.tile))) for h in players and h.player_id != my_id]
  161.  
  162.     print(action)
  163.  
Add Comment
Please, Sign In to add comment