main.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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 Blob_Manager:
  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. def add_scouter(self):
  58. if len(self.scouters) < self.knowledge['max_scouters']:
  59. if len(self.knowledge['food']) != 0:
  60. index = random.randrange(len(self.knowledge['food']))
  61. (x, y) = self.knowledge['food'][index]
  62. else:
  63. x, y = self.find_blob_square()
  64. self.scouters.append(FSMAnt(self.board, self.knowledge, x, y))
  65. else:
  66. print("Max scouters already reached !")
  67. def remove_scouter(self):
  68. nbr = random.randrange(len(self.scouters))
  69. del self.scouters[nbr]
  70. def compute_max_scouters(self):
  71. real_size_factor = 1 / 360
  72. blob_size_factor = 3 / 4
  73. cover_factor = 1 / 4
  74. blob_qt = self.board.get_blob_total()
  75. scouters_by_cover = int(self.board.get_cover())
  76. scouters_by_size = int(blob_qt)
  77. total_scouters = int((blob_size_factor * scouters_by_size + cover_factor * scouters_by_cover)
  78. * (real_size_factor * self.board.height * self.board.width / 100))
  79. return max(self.knowledge['min_scouters'], total_scouters)
  80. def find_blob_square(self):
  81. availables = []
  82. total_blob = 0
  83. for x in range(self.board.width):
  84. for y in range(self.board.height):
  85. if self.board.is_touched(x, y):
  86. qt = self.board.get_blob(x, y) + 1
  87. total_blob += qt
  88. availables.append(((x, y), qt))
  89. if len(availables) == 0:
  90. return 0, 0
  91. # Random need cast to integer
  92. # Floor cast will make sure a solution is found
  93. index_pond = random.randrange(int(total_blob))
  94. acc = 0
  95. for square, qt in availables:
  96. acc += qt
  97. if acc >= index_pond:
  98. return square
  99. def reset(self, x, y):
  100. for scouter in self.scouters.copy():
  101. if scouter.x == x and scouter.y == y:
  102. self.scouters.remove(scouter)
  103. for food in self.knowledge['food'].copy():
  104. if food == (x, y):
  105. self.knowledge['food'].remove(food)
  106. self.knowledge['max_scouters'] -= 1
  107. def food_discovered(self, x, y):
  108. self.knowledge['food'].append((x, y))
  109. # self.knowledge['max_scouters'] += 1
  110. # for _ in range(1):
  111. # self.scouters.append(FSMAnt(self.board, self.knowledge, x, y, Blob_Manager.DROP_VALUE))
  112. # print("Food discovered in (" + str(x) + ", " + str(y) + ")")
  113. def food_destroyed(self, x, y):
  114. self.knowledge['food'].remove((x, y))