blob_manager.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import random
  2. import json
  3. # from ant import Ant
  4. # from gatherer import Gatherer
  5. from simulation.logic.fsm_ant import FSMAnt
  6. from simulation.board import Board
  7. class BlobManager:
  8. def __init__(self, board, default_knowledge):
  9. """
  10. :type board: Board
  11. """
  12. self.board = board
  13. self.knowledge = dict()
  14. self.scouters = []
  15. with open(default_knowledge, 'r') as file:
  16. self.knowledge.update(json.load(file))
  17. self.knowledge['food'] = []
  18. for x in range(self.board.width):
  19. for y in range(self.board.height):
  20. if self.board.has_food(x, y) and self.board.is_touched(x, y):
  21. self.knowledge['food'].append((x, y))
  22. self.knowledge['max_scouters'] = self.compute_max_scouters()
  23. while len(self.scouters) < self.knowledge['max_scouters']:
  24. self.add_scouter()
  25. print("Scouters: " + str(len(self.scouters)))
  26. def save(self):
  27. d = self.knowledge.copy()
  28. del d["food"]
  29. del d["max_scouters"]
  30. return json.dumps(d, indent=4, sort_keys=True)
  31. def move(self):
  32. deads = []
  33. for scouter in self.scouters:
  34. old = (scouter.x, scouter.y)
  35. scouter.move()
  36. if old == (scouter.x, scouter.y):
  37. deads.append(scouter)
  38. else:
  39. if self.board.has_food(scouter.x, scouter.y) and (scouter.x, scouter.y) not in self.knowledge['food']:
  40. self.food_discovered(scouter.x, scouter.y)
  41. scouter.update()
  42. new_max = self.compute_max_scouters()
  43. if new_max != self.knowledge['max_scouters']:
  44. print("Scouters: " + str(new_max))
  45. self.knowledge['max_scouters'] = new_max
  46. scouters_qt = len(self.scouters)
  47. diff = self.knowledge['max_scouters'] - scouters_qt
  48. if diff > 0:
  49. for _ in range(diff):
  50. self.add_scouter()
  51. elif diff < 0:
  52. for _ in range(-diff):
  53. self.remove_scouter()
  54. for dead in deads:
  55. self.scouters.remove(dead)
  56. self.add_scouter()
  57. self.board.manage_blob(self.knowledge["Global Decrease"], self.knowledge["Remaining Blob on Food"])
  58. def add_scouter(self):
  59. if len(self.scouters) < self.knowledge['max_scouters']:
  60. if len(self.knowledge['food']) != 0:
  61. index = random.randrange(len(self.knowledge['food']))
  62. (x, y) = self.knowledge['food'][index]
  63. else:
  64. x, y = self.find_blob_square()
  65. self.scouters.append(FSMAnt(self.board, self.knowledge, x, y))
  66. else:
  67. print("Max scouters already reached !")
  68. def remove_scouter(self):
  69. nbr = random.randrange(len(self.scouters))
  70. del self.scouters[nbr]
  71. def compute_max_scouters(self):
  72. total_scouters = self.knowledge["Computing"]["Blob Size Factor"] * self.board.get_blob_total() \
  73. + self.knowledge["Computing"]["Covering Factor"] * self.board.get_cover() \
  74. + self.knowledge["Computing"]["Known Foods Factor"] * len(self.knowledge['food'])
  75. total_scouters *= (self.knowledge["Computing"]["Global Factor"] * (self.board.height * self.board.width / 100000))
  76. return max(self.knowledge["Scouters"]["Min"], int(total_scouters))
  77. def find_blob_square(self):
  78. availables = []
  79. total_blob = 0
  80. for x in range(self.board.width):
  81. for y in range(self.board.height):
  82. if self.board.is_touched(x, y):
  83. qt = self.board.get_blob(x, y) + 1
  84. total_blob += qt
  85. availables.append(((x, y), qt))
  86. if len(availables) == 0:
  87. return 0, 0
  88. # Random need cast to integer
  89. # Floor cast will make sure a solution is found
  90. index_pond = random.randrange(int(total_blob))
  91. acc = 0
  92. for square, qt in availables:
  93. acc += qt
  94. if acc >= index_pond:
  95. return square
  96. def reset(self, x, y):
  97. for scouter in self.scouters.copy():
  98. if scouter.x == x and scouter.y == y:
  99. self.scouters.remove(scouter)
  100. for food in self.knowledge['food'].copy():
  101. if food == (x, y):
  102. self.knowledge['food'].remove(food)
  103. self.knowledge['max_scouters'] -= 1
  104. def food_discovered(self, x, y):
  105. self.knowledge['food'].append((x, y))
  106. # self.knowledge['max_scouters'] += 1
  107. # for _ in range(1):
  108. # self.scouters.append(FSMAnt(self.board, self.knowledge, x, y, Blob_Manager.DROP_VALUE))
  109. # print("Food discovered in (" + str(x) + ", " + str(y) + ")")
  110. def food_destroyed(self, x, y):
  111. self.knowledge['food'].remove((x, y))