123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- import random
- import json
- # from ant import Ant
- # from gatherer import Gatherer
- from simulation.logic.fsm_ant import FSMAnt
- from simulation.board import Board
- class Blob_Manager:
- def __init__(self, board, default_knowledge):
- """
- :type board: Board
- """
- self.board = board
- self.knowledge = dict()
- self.scouters = []
- with open(default_knowledge, 'r') as file:
- self.knowledge.update(json.load(file))
- self.knowledge['food'] = []
- for x in range(self.board.width):
- for y in range(self.board.height):
- if self.board.has_food(x, y) and self.board.is_touched(x, y):
- self.knowledge['food'].append((x, y))
- self.knowledge['max_scouters'] = self.compute_max_scouters()
- while len(self.scouters) < self.knowledge['max_scouters']:
- self.add_scouter()
- print("Scouters: " + str(len(self.scouters)))
- def save(self):
- d = self.knowledge.copy()
- del d["food"]
- del d["max_scouters"]
- return json.dumps(d, indent=4, sort_keys=True)
- def move(self):
- deads = []
- for scouter in self.scouters:
- old = (scouter.x, scouter.y)
- scouter.move()
- if old == (scouter.x, scouter.y):
- deads.append(scouter)
- else:
- if self.board.has_food(scouter.x, scouter.y) and (scouter.x, scouter.y) not in self.knowledge['food']:
- self.food_discovered(scouter.x, scouter.y)
- scouter.update()
- new_max = self.compute_max_scouters()
- if new_max != self.knowledge['max_scouters']:
- print("Scouters: " + str(new_max))
- self.knowledge['max_scouters'] = new_max
- scouters_qt = len(self.scouters)
- diff = self.knowledge['max_scouters'] - scouters_qt
- if diff > 0:
- for _ in range(diff):
- self.add_scouter()
- elif diff < 0:
- for _ in range(-diff):
- self.remove_scouter()
- for dead in deads:
- self.scouters.remove(dead)
- self.add_scouter()
- def add_scouter(self):
- if len(self.scouters) < self.knowledge['max_scouters']:
- if len(self.knowledge['food']) != 0:
- index = random.randrange(len(self.knowledge['food']))
- (x, y) = self.knowledge['food'][index]
- else:
- x, y = self.find_blob_square()
- self.scouters.append(FSMAnt(self.board, self.knowledge, x, y))
- else:
- print("Max scouters already reached !")
- def remove_scouter(self):
- nbr = random.randrange(len(self.scouters))
- del self.scouters[nbr]
- def compute_max_scouters(self):
- real_size_factor = 1 / 360
- blob_size_factor = 3 / 4
- cover_factor = 1 / 4
- blob_qt = self.board.get_blob_total()
- scouters_by_cover = int(self.board.get_cover())
- scouters_by_size = int(blob_qt)
- total_scouters = int((blob_size_factor * scouters_by_size + cover_factor * scouters_by_cover)
- * (real_size_factor * self.board.height * self.board.width / 100))
- return max(self.knowledge['min_scouters'], total_scouters)
- def find_blob_square(self):
- availables = []
- total_blob = 0
- for x in range(self.board.width):
- for y in range(self.board.height):
- if self.board.is_touched(x, y):
- qt = self.board.get_blob(x, y) + 1
- total_blob += qt
- availables.append(((x, y), qt))
- if len(availables) == 0:
- return 0, 0
- # Random need cast to integer
- # Floor cast will make sure a solution is found
- index_pond = random.randrange(int(total_blob))
- acc = 0
- for square, qt in availables:
- acc += qt
- if acc >= index_pond:
- return square
- def reset(self, x, y):
- for scouter in self.scouters.copy():
- if scouter.x == x and scouter.y == y:
- self.scouters.remove(scouter)
- for food in self.knowledge['food'].copy():
- if food == (x, y):
- self.knowledge['food'].remove(food)
- self.knowledge['max_scouters'] -= 1
- def food_discovered(self, x, y):
- self.knowledge['food'].append((x, y))
- # self.knowledge['max_scouters'] += 1
- # for _ in range(1):
- # self.scouters.append(FSMAnt(self.board, self.knowledge, x, y, Blob_Manager.DROP_VALUE))
- # print("Food discovered in (" + str(x) + ", " + str(y) + ")")
- def food_destroyed(self, x, y):
- self.knowledge['food'].remove((x, y))
|