def __init__(self, team): self.inventory = Inventory() self.voir = None self.state = None self.level = 1 self.team = team self.messages = MessageList()
def update_vision(self, cmd): cmd = cmd[cmd.index('{') + 1:] cmd = cmd[:cmd.index('}')] cases = cmd.split(', ') self.voir = [] for case in cases: new = Inventory.from_str(case) self.voir.append(new)
if level > 8: print('invalid incantation level ' + str(level)) exit(0) incant = Incantation.incant_list[level] for res in Resource: if incant.prerequisites.get_qt(res) > trantor.inventory.get_qt(res): return False return True def missing_resources(trantor): level = trantor.level incant = Incantation.incant_list[level] to_return = [] for res in Resource: if incant.prerequisites.get_qt(res) > trantor.inventory.get_qt(res): to_return.append(res) return to_return def incantation_to_level_up(level): return Incantation.incant_list[level] Incantation.incant_list = { 1 : Incantation(1, Inventory.from_nbrs(0, 1, 0, 0, 0, 0, 0)), 2 : Incantation(2, Inventory.from_nbrs(0, 1, 1, 1, 0, 0, 0)), 3 : Incantation(2, Inventory.from_nbrs(0, 2, 0, 1, 0, 2, 0)), 4 : Incantation(4, Inventory.from_nbrs(0, 1, 1, 2, 0, 1, 0)), 5 : Incantation(4, Inventory.from_nbrs(0, 1, 2, 1, 3, 0, 0)), 6 : Incantation(6, Inventory.from_nbrs(0, 1, 2, 3, 0, 1, 0)), 7 : Incantation(6, Inventory.from_nbrs(0, 2, 2, 2, 2, 2, 1)) }
incant = Incantation.incant_list[level] for res in Resource: if incant.prerequisites.get_qt(res) > trantor.inventory.get_qt( res): return False return True def missing_resources(trantor): level = trantor.level incant = Incantation.incant_list[level] to_return = [] for res in Resource: if incant.prerequisites.get_qt(res) > trantor.inventory.get_qt( res): to_return.append(res) return to_return def incantation_to_level_up(level): return Incantation.incant_list[level] Incantation.incant_list = { 1: Incantation(1, Inventory.from_nbrs(0, 1, 0, 0, 0, 0, 0)), 2: Incantation(2, Inventory.from_nbrs(0, 1, 1, 1, 0, 0, 0)), 3: Incantation(2, Inventory.from_nbrs(0, 2, 0, 1, 0, 2, 0)), 4: Incantation(4, Inventory.from_nbrs(0, 1, 1, 2, 0, 1, 0)), 5: Incantation(4, Inventory.from_nbrs(0, 1, 2, 1, 3, 0, 0)), 6: Incantation(6, Inventory.from_nbrs(0, 1, 2, 3, 0, 1, 0)), 7: Incantation(6, Inventory.from_nbrs(0, 2, 2, 2, 2, 2, 1)) }
def test_action_to_perform(self): trantor = TestTrantor.new_trantor(2, Inventory.from_nbrs(5, 5, 5, 5, 5, 5, 5)) trantor.messages.add_msg('message 0 0 0 0 0 ' + message.incantation_call(2)[10:]) action = trantor.action_to_perform() self.assertTrue(action == State.JOIN_TRANTOR_FOR_INCANTATION)
class Trantor: """ Trantorian is the player """ def __init__(self, team): self.inventory = Inventory() self.voir = None self.state = None self.level = 1 self.team = team self.messages = MessageList() def up_level(self): self.level += 1 print('new level: ', self.level) def action_to_perform(self): """ define next actio to perform by the trantor """ if self.inventory.nb_food < 4: return State.SEARCH_FOOD if self.messages.someone_to_join(self.team, self.level) != None: return State.JOIN_TRANTOR_FOR_INCANTATION if Incantation.is_trantor_ready(self): return State.START_INCANTATION return State.SEARCH_STONE def action_to_find_resource(self, res): if self.voir == None: return 'voir' elif self.voir[0].get_qt(res) >= 1: return 'prend ' + str(res) elif self.voir[2].get_qt(res) >= 1: return 'avance' elif len(self.voir) > 7 and self.voir[6].get_qt(res) >= 1: return 'avance' else: action = random.randint(1, 3) if action == 1: return 'gauche' elif action == 2: return 'droite' else: return 'avance' def stone_to_find(self): if self.voir == None: return None resources = Incantation.missing_resources(self) if resources == []: return None # first take the resources we can have imediately for res in resources: if self.voir[0].get_qt(res) > 0: return res return resources[0] def enough_trantor_for_incantation(self): if self.level == 1: return True incant = Incantation.incantation_to_level_up(self.level) trant_ready = self.messages.nb_of_trantor_ready_for_incantation( self.team, self.level) + 1 return incant.nb_player <= trant_ready # every branch of play must return a command, if not the player freeze # because the server won't send back a ok or ko command => the main_loop # recv will block indefinitely def play(self): # define what the trantor should do self.state = self.action_to_perform() if self.state == State.SEARCH_FOOD: return self.action_to_find_resource(Resource.FOOD) # check number of food hold by this trantor (the food will # be decreased by the server without the client being notifed, refresh # inventory to check current state of food) if random.randint(1, 30) == 1: return 'inventaire' # check if there is enough connection slots for new trantors to join if random.randint(1, 150) == 1: return 'connect_nbr' if self.state == State.SEARCH_STONE: if self.voir == None: return 'voir' res = self.stone_to_find() # self.action_to_perform evaluate if we have all required resources # so res should not be none if res == None: return 'inventaire' return self.action_to_find_resource(res) if self.state == State.JOIN_TRANTOR_FOR_INCANTATION: msg = self.messages.someone_to_join(self.team, self.level) action = msg.action_to_join_sender() if action == None: return message.message_to_cmd( message.incantation_ready(self.team, self.level), self) else: return action if self.state == State.START_INCANTATION: if self.enough_trantor_for_incantation(): return 'incantation' return message.message_to_cmd( message.incantation_call(self.team, self.level), self) def commit_cmd(self, cmd): if 'avance' in cmd: self.voir = None if 'gauche' in cmd: self.voir = None if 'droite' in cmd: self.voir = None if 'prend ' in cmd: res = Resource.from_str(cmd[6:]) self.inventory.add(res, 1) self.voir = None return None if 'incantation' in cmd[:11]: self.up_level() return 'inventaire' def update_vision(self, cmd): cmd = cmd[cmd.index('{') + 1:] cmd = cmd[:cmd.index('}')] cases = cmd.split(', ') self.voir = [] for case in cases: new = Inventory.from_str(case) self.voir.append(new) def update_inventaire(self, cmd): cmd = cmd[11:] self.inventory = Inventory.from_str(cmd) def interpret_cmd(self, prev_cmd, new_cmd): if 'ko' in new_cmd[:2]: return self.play() if 'ok' in new_cmd[:2]: cmd = self.commit_cmd(prev_cmd) if cmd != None: return cmd else: return self.play() if 'voir ' in new_cmd[:6]: self.update_vision(new_cmd) return None if 'inventaire ' in new_cmd[:11]: self.update_inventaire(new_cmd) return None if 'message ' in new_cmd[:9]: self.messages.add_msg(new_cmd) return None if 'suc' in new_cmd[:3]: print('unknow command: ' + prev_cmd) return None if 'incantation' in new_cmd[:11]: self.up_level() if 'connect_nbr ' in new_cmd[:13]: m = re.match(r'connect_nbr (\d+)', new_cmd) if m == None: print('Error: invalid connect_nbr command', new_cmd) return self.play() nb_connection_slot = int(m.group(1)) if nb_connection_slot <= 1: return 'fork' if 'relaunch' in new_cmd[:9]: print('relaunch') cmd = self.commit_cmd(prev_cmd) if cmd != None: return cmd else: return self.play() if 'seg ' in new_cmd[:4]: print('Team', new_cmd[4:], 'is victorious !') exit(0)
def update_inventaire(self, cmd): cmd = cmd[11:] self.inventory = Inventory.from_str(cmd)