Advertisement
Guest User

Untitled

a guest
Nov 22nd, 2017
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.52 KB | None | 0 0
  1. import sys
  2. import math
  3.  
  4. import itertools
  5.  
  6.  
  7. def log(to_log, newline=True):
  8. print(to_log, file=sys.stderr, flush=True, end='\n' if newline else '')
  9.  
  10. class UnitType:
  11. REAPER = 0
  12. DESTROYER = 1
  13. DOOF = 2
  14. TANKER = 3
  15. WRECK = 4
  16.  
  17. class Point():
  18. def __init__(self, x, y):
  19. self.x = x
  20. self.y = y
  21.  
  22. class Entity(Point):
  23. def __init__(self, id, x, y, player):
  24. super().__init__(x, y)
  25. self.id = id
  26. self.player = player
  27.  
  28. def update(self, vx, vy, mass, r, extra, extra2):
  29. self.vx = vx
  30. self.vy = vy
  31. self.mass = mass
  32. self.r = r
  33. self.next_pos = (self.x + self.vx, self.y + self.vy)
  34. self.extra = extra
  35. self.extra2 = extra2
  36.  
  37. class Reaper(Entity):
  38. def __init__(self, id, x, y, player):
  39. super().__init__(id, x, y, player)
  40. self.mass = 0.5
  41. self.friction = 0.2
  42.  
  43. class Destroyer(Entity):
  44. def __init__(self, id, x, y, player):
  45. super().__init__(id, x, y, player)
  46. self.mass = 1.5
  47. self.friction = 0.3
  48.  
  49. class Tanker(Entity):
  50. def __init__(self, id, x, y, player):
  51. super().__init__(id, x, y, player)
  52. self.mass = 2.5
  53. self.friction = 0.4
  54.  
  55. class Doof(Entity):
  56. def __init__(self, id, x, y, player):
  57. super().__init__(id, x, y, player)
  58. self.mass = 1
  59. self.friction = 0.25
  60.  
  61.  
  62. class Wreck(Entity):
  63. def __init__(self, id, x, y, player):
  64. super().__init__(id, x, y, player)
  65.  
  66. def magic_formula(x, y, vx, vy):
  67. return int(x - 1.5 * vx), int(y - 1.5 * vy)
  68.  
  69. def get_closest(entity, entities):
  70. closest = None
  71. best = sys.maxsize
  72. for e in entities:
  73. dist = distance2(e, entity)
  74. if dist < best:
  75. closest = e
  76. best = dist
  77. return closest
  78.  
  79. def distance(e1, e2):
  80. return distance_coord(e1.x, e2.x, e1.y, e2.y)
  81.  
  82. def distance2(e1, e2):
  83. return distance_coord2(e1.x, e2.x, e1.y, e2.y)
  84.  
  85. def distance_coord(x1, x2, y1, y2):
  86. return math.sqrt(distance_coord2(x1, x2, y1, y2))
  87.  
  88. def distance_coord2(x1, x2, y1, y2):
  89. return (x2 - x1) ** 2 + (y2 - y1) ** 2
  90.  
  91.  
  92. def is_in_range(coord, entities):
  93. return any(distance_coord(e.x, coord[0], e.y, coord[1]) <= e.r for e in entities)
  94.  
  95. def find_overlaps(entities):
  96. overlaps = []
  97. for i, j in itertools.combinations(entities, 2):
  98. log(distance_coord(i.x, j.x, i.y, j.y))
  99. log(i.r+j.r)
  100. if distance_coord(i.x, j.x, i.y, j.y) < i.r+j.r:
  101. overlaps.append((i, j))
  102. log(overlaps)
  103. return overlaps
  104.  
  105. class Player():
  106. def __init__(self):
  107. pass
  108. def play(self):
  109. # game loop
  110. while True:
  111. self.my_units = []
  112. self.their_units = []
  113. self.wrecks = []
  114. self.tankers = []
  115.  
  116. my_score = int(input())
  117. enemy_score_1 = int(input())
  118. enemy_score_2 = int(input())
  119. my_rage = int(input())
  120. enemy_rage_1 = int(input())
  121. enemy_rage_2 = int(input())
  122. unit_count = int(input())
  123. for i in range(unit_count):
  124. unit_id, unit_type, player, mass, r, x, y, vx, vy, extra, extra_2 = input().split()
  125. unit_id = int(unit_id)
  126. unit_type = int(unit_type)
  127. player = int(player)
  128. mass = float(mass)
  129. r = int(r)
  130. x = int(x)
  131. y = int(y)
  132. vx = int(vx)
  133. vy = int(vy)
  134. extra = int(extra)
  135. extra_2 = int(extra_2)
  136.  
  137. if unit_type == UnitType.REAPER:
  138. e = Reaper(unit_id, x, y, player)
  139. elif unit_type == UnitType.TANKER:
  140. e = Tanker(unit_id, x, y, player)
  141. elif unit_type == UnitType.DOOF:
  142. e = Doof(unit_id, x, y, player)
  143. elif unit_type == UnitType.DESTROYER:
  144. e = Destroyer(unit_id, x, y, player)
  145. else:
  146. e = Wreck(unit_id, x, y, player)
  147.  
  148. e.update(vx, vy, mass, r, extra, extra_2)
  149.  
  150. if player == 0:
  151. self.my_units.append(e)
  152. if isinstance(e, Reaper):
  153. my_reaper = e
  154. elif isinstance(e, Destroyer):
  155. my_destroyer = e
  156. elif isinstance(e, Doof):
  157. my_doof = e
  158. elif player == -1:
  159. if isinstance(e, Tanker):
  160. self.tankers.append(e)
  161. else:
  162. self.wrecks.append(e)
  163. else:
  164. self.their_units.append(e)
  165.  
  166.  
  167. stronger_opponent = 1 if enemy_score_1 > enemy_score_2 else 2
  168.  
  169. # TODO - sort the reaper move by the gain in X number of moves - so you would not leave one wreck for another etc
  170. reaper_target = self.find_best_wreck_overlap()
  171. if reaper_target is None and len(self.wrecks) > 0:
  172. reaper_target = self.find_best_wreck(my_reaper)
  173.  
  174. tankers_inside = list(filter(lambda t: distance_coord(0, t.next_pos[0], 0, t.next_pos[1]) < 6000, self.tankers))
  175. is_reaper_target_tanker = False
  176.  
  177. if reaper_target is None and len(tankers_inside) > 0:
  178. max_values = [x for x in tankers_inside if x.extra == max(map(lambda t:t.extra, tankers_inside))]
  179. reaper_target = get_closest(my_destroyer, max_values)
  180. is_reaper_target_tanker = True
  181.  
  182. # Reaper move
  183. if reaper_target is not None:
  184. print("{0} {1} {2}".format(*magic_formula(reaper_target.x, reaper_target.y, my_reaper.vx, my_reaper.vy), 300))
  185. else:
  186. print("{0} {1} {2}".format(my_destroyer.x, my_destroyer.y, 300))
  187.  
  188. stronger_opp_reaper = next(filter(lambda e: isinstance(e, Reaper) and e.player == stronger_opponent, self.their_units))
  189. # Destroyer move
  190. if reaper_target is not None and is_reaper_target_tanker:
  191. print("{0} {1} {2}".format(*magic_formula(*reaper_target.next_pos, my_destroyer.vx, my_destroyer.vy), 300))
  192. # TODO don't spam spell in the same place
  193. elif stronger_opp_reaper is not None:
  194. if distance_coord(my_destroyer.x, my_destroyer.y, stronger_opp_reaper.next_pos[0], stronger_opp_reaper.next_pos[1]) < 3400 and my_rage > 60:
  195. print("{0} {1} {2}".format("SKILL", *stronger_opp_reaper.next_pos))
  196. else:
  197. print("{0} {1} {2}".format(*magic_formula(*stronger_opp_reaper.next_pos, my_destroyer.vx, my_destroyer.vy), 300))
  198. else:
  199. print("WAIT")
  200.  
  201. # Doof move
  202. # closest_opp_reaper = get_closest(my_destroyer, filter(lambda e: isinstance(e, Reaper), self.their_units))
  203. if stronger_opp_reaper is not None:
  204. if distance(my_doof, stronger_opp_reaper) < 3400 and my_rage > 30 and is_in_range(stronger_opp_reaper.next_pos, self.wrecks):
  205. print("{0} {1} {2}".format("SKILL", *stronger_opp_reaper.next_pos))
  206. else:
  207. print("{0} {1} {2}".format(*magic_formula(*stronger_opp_reaper.next_pos, my_doof.vx, my_doof.vy), 300))
  208. else:
  209. print("WAIT")
  210.  
  211. def find_best_wreck(self, my_reaper):
  212. closest_wreck = get_closest(my_reaper, self.wrecks)
  213. # TODO - remove once we have better move sorting
  214. # don't leave a wreck we are already close to
  215. if distance(my_reaper, closest_wreck) < closest_wreck.r + 600:
  216. return closest_wreck
  217.  
  218. max_values = [x for x in self.wrecks if x.extra == max(map(lambda t: t.extra, self.wrecks))]
  219. return get_closest(my_reaper, max_values)
  220.  
  221. def find_best_wreck_overlap(self):
  222. overlaps = find_overlaps(self.wrecks)
  223. # wreck overlap with most water
  224. reaper_target = None
  225. if len(overlaps) > 0:
  226. max_overlap = max(overlaps, key=lambda o : o[0].extra + o[1].extra)
  227. log(max_overlap)
  228. w1 = max_overlap[0]
  229. w2 = max_overlap[1]
  230. # NB! this is midpoint between the wrecks, this does not work if the circles are of very different size
  231. reaper_target = Point((w1.x + w2.x) / 2, (w1.y + w2.y) / 2)
  232. return reaper_target
  233.  
  234.  
  235. if __name__ == '__main__':
  236. p = Player()
  237. p.play()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement