temp.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. '''
  2. @author: olivier.massot, 2019
  3. '''
  4. from collections import Counter
  5. import itertools
  6. import time
  7. class Node():
  8. def __init__(self, pos, path=[]):
  9. self.pos = pos
  10. self.path = path
  11. class Grid():
  12. dim = 12
  13. owned = 3
  14. def __init__(self):
  15. self.cells = [(x, y) for x in range(Grid.dim) for y in range(Grid.dim)]
  16. def print_grid(self):
  17. grid = [["" for _ in range(Grid.dim)] for _ in range(Grid.dim)]
  18. for x, y in self.cells:
  19. grid[y][x] = f"({x}, {y})" if self._active_owned((x, y), 0) else "______"
  20. return "\n".join(["".join([c for c in row]) for row in grid])
  21. @staticmethod
  22. def manhattan(from_, to_):
  23. xa, ya = from_
  24. xb, yb = to_
  25. return abs(xa - xb) + abs(ya - yb)
  26. def neighbors(self, x, y, diags=False):
  27. neighs = [(x, y - 1), (x - 1, y), (x + 1, y), (x, y + 1)]
  28. if diags:
  29. neighs += [(x - 1, y - 1), (x + 1, y - 1), (x - 1, y + 1), (x + 1, y + 1)]
  30. return [(x, y) for x, y in neighs if 0 <= x < Grid.dim and 0 <= y < Grid.dim]
  31. def oriented_neighbors(self, x, y, orient):
  32. return [(x + 1, y), (x, y + 1)] if orient > 0 else [(x - 1, y), (x, y - 1)]
  33. def update_frontlines(self):
  34. self.frontline = []
  35. for p in self.cells:
  36. if self._active_owned(p, 0):
  37. if any(not self._active_owned(n, 0) for n in self.neighbors(*p)):
  38. # cell.update_threat()
  39. self.frontline.append(p)
  40. def _active_owned(self, pos, player_id):
  41. return pos in [(0,0), (1,0), (2,0), (3,0), (4, 0),
  42. (0,1), (1,1), (2,1),
  43. (0,2), (1,2), (2,2),
  44. (0,3), (1,3), (2,3),
  45. (2,4),
  46. (1,5), (2,5),
  47. (1,6), (2,6),
  48. (1,7), (2,7),
  49. (1,8), (2,8)]
  50. def __active_owned(self, pos, player_id):
  51. return pos[0] < 12 and pos[1] < 12
  52. def update_pivot_for(self, player_id):
  53. # start = self.get_hq(player_id).pos
  54. start = (0,0)
  55. orient = 1 if start == (0, 0) else -1
  56. start_node = Node(start)
  57. buffer = [start_node]
  58. nodes = {start_node}
  59. ignored = set()
  60. while buffer:
  61. new_buffer = []
  62. for node in buffer:
  63. neighbors = [p for p in self.neighbors(*node.pos) if self._active_owned(p, player_id)]
  64. if len(neighbors) == 4:
  65. ignored.add(node.pos)
  66. continue
  67. for n in neighbors:
  68. if not n in node.path:
  69. new_node = Node(n, node.path + [node.pos])
  70. nodes.add(new_node)
  71. new_buffer.append(new_node)
  72. buffer = new_buffer
  73. paths_to = {}
  74. for node in nodes:
  75. if not node.pos in paths_to:
  76. paths_to[node.pos] = []
  77. paths_to[node.pos].append(node.path)
  78. print(paths_to)
  79. pivots = {}
  80. for candidate in paths_to:
  81. if candidate == start:
  82. continue
  83. for p, paths in paths_to.items():
  84. if not paths or not paths[0] or p in ignored:
  85. continue
  86. if all(candidate in path for path in paths):
  87. if not candidate in pivots:
  88. pivots[candidate] = []
  89. pivots[candidate].append(p)
  90. occurrences = Counter(sum(sum(paths_to.values(), []), []))
  91. while ignored:
  92. new_ignored = set()
  93. for p in ignored:
  94. occured_neighbors = [occurrences[n] for n in self.neighbors(*p) if n in occurrences]
  95. if not occured_neighbors:
  96. new_ignored.add[p]
  97. continue
  98. occurrences[p] = 2 * sum(occured_neighbors) // len(occured_neighbors)
  99. ignored = new_ignored
  100. print(occurrences)
  101. return pivots
  102. def __update_pivot_for(self, player_id):
  103. # start = self.get_hq(player_id).pos
  104. start = (0,0)
  105. orient = 1
  106. buffer = [(None, start)]
  107. bounds = []
  108. while buffer:
  109. new_buffer = []
  110. for o, p in buffer:
  111. for n in self.oriented_neighbors(*p, orient):
  112. if self._active_owned(n, player_id) and not (p, n) in bounds and n != o:
  113. bounds.append((p, n))
  114. new_buffer.append((p, n))
  115. buffer = new_buffer
  116. print(bounds)
  117. parents_number = Counter()
  118. for parent, child in bounds:
  119. parents_number[child] += 1
  120. print(parents_number)
  121. pivots = set()
  122. for parent, child in bounds:
  123. if parent == start:
  124. continue
  125. if parents_number[child] == 1:
  126. pivots |= {parent}
  127. return pivots
  128. grid = Grid()
  129. Grid.owned = 5
  130. print(grid.print_grid())
  131. t0 = time.time()
  132. a = grid.update_pivot_for(0)
  133. print(a)
  134. print(time.time() - t0)