def takeNow(self, obj): if obj == GameObj.Player: return self.waitForPlace() self.CSLink_.take(linksR[obj]) self.pendingRqt_ += [(Command.Take, obj)] dPrint(self.debug_, colored("Take " + linksR[obj], "blue"))
def msgReceived(self): self.serverMsg = self.read() if self.serverMsg is None: return False dPrint(self.debug_, colored("Message Received: " + self.serverMsg, "red")) return True
def normalLifeMsg(self, dirC, msg): """ AI go for stone and food [Gestion Des messages] """ msg = self.updateComNbs(msg) if msg is None: return if msg[0] == 'LEAD' and self.level_ == int(msg[1]) and self.inventory_[ GameObj.Food] > 30 and self.level_ < 8: dPrint(self.debugInv_, colored("CO FOUND", "red")) self.leadID = int(msg[2]) self.othIncNb_ = int(msg[3]) self.situation_ = "waitForGoNoLead" self.broadcast(' '.join([ str(self.newNb()), 'OK', str(self.leadID), str(self.othIncNb_), str(self.id_), invToStr(self.inventory_) ])) return if msg[0] == 'NEW_INFO' and int(msg[1]) == self.id_: self.comNbs += msg[3].split('-') self.comNbs = list(dict.fromkeys(self.comNbs)) self.matesNb += 1 if int(msg[2]) not in self.helpedIds or int(msg[2]) > self.id_: self.first = False
def updateIncantation(self, msg, moment=None): if moment is not None: dPrint( self.debugInv_, Colors.FAIL + "Update Incantation " + moment + " \"" + msg + "\"" + Colors.ENDC) else: dPrint( self.debugInv_, Colors.FAIL + "Update Incantation " + " \"" + msg + "\"" + Colors.ENDC) if moment is not None: if 'Current level' in msg: self.level_ += 1 self.situation_ = 'normalLife' if 'ko' in msg: self.broadcast(' '.join([ str(self.newNb()), 'CANCELALL', str(self.id_), str(self.myIncNb_) ])) self.situation_ = "normalLife" self.sameLvlIDs_.clear() if moment is None: if "ko" in msg: self.situation_ = 'normalLife' if 'Current level' in msg: self.level_ += 1 self.situation_ = 'normalLife'
def updateSet(self, msg, obj): """ check """ dPrint(self.debug_, Colors.HEADER + "Update Set" + Colors.ENDC, msg, obj, self.inventory_[obj]) assert msg == 'ok', "Set can't fail " + obj
def goToIncantationNoLeadMsg(self, dirC, msg): """ On se dirige vers l'incantation (en faisant en sorte d'avoir de la nourriture) [Gestion Des messages] """ msg = self.updateComNbs(msg) if msg is None: return if msg[0] == 'UPDATE' and int( msg[1]) == self.leadID and self.id_ == int(msg[2]): self.elevDir = dirC if self.elevDir == 0: self.broadcast(' '.join([ str(self.newNb()), 'PLACED', str(self.leadID), str(self.id_) ])) dPrint(self.debugInv_, colored("ASKIP JE SUIS PLACED", "yellow")) self.situation_ = 'waitForInstructions' return if msg[0] == 'CANCELALL' and int( msg[1]) == self.leadID and self.othIncNb_ == int(msg[2]): self.situation_ = 'normalLife' self.leadID = -1 return if msg[0] == 'ALERT' and int(msg[1]) == self.leadID: self.elevDir = -1 self.leadID = -1 self.situation_ = 'normalLife' return
def goToIncantationNoLead(self): """ On se dirige vers l'incantation (en faisant en sorte d'avoir de la nourriture) """ dPrint(self.debugInv_, Colors.SMALL + "goToIncantationNoLead" + Colors.ENDC, self.id_, self.leadID) self.emergency() # getattr(self, self.foodStageForElev_[min([va if self.inventory_[GameObj.Food] < va else self.maxFoodStage for va, v in self.foodStageForElev_.items()])])() self.goSlowEat() # FIXME ? self.updateDataFromServForce() if self.elevDir is not None and self.elevDir != 0 and self.situation_ == 'goToIncantationNoLead': self.goToDir(self.elevDir, self.countNbMoves) self.updateDataFromServForce() self.broadcast(' '.join( [str(self.newNb()), 'ASKED', str(self.leadID), str(self.id_)])) if self.countNbMoves > 1: self.countNbMoves -= 1 self.elevDir = None if self.elevDir == 0 and self.situation_ == 'goToIncantationNoLead': self.updateDataFromServForce() self.broadcast(' '.join( [str(self.newNb()), 'ASKED', str(self.leadID), str(self.id_)]))
def take(self, obj): if obj == GameObj.Player: return if len(self.pendingRqt_) < self.maxServCommands_: self.CSLink_.take(linksR[obj]) self.pendingRqt_ += [(Command.Take, obj)] dPrint(self.debug_, colored("Take " + linksR[obj], "blue"))
def removeItemThatShouldntBeThereSecondLead(self): self.lookAroundNow() for i, j in elevRqrmts[self.level_].items(): for _ in range(0, self.around_[self.currentPos_].count(i) - j): self.takeNow(i) dPrint(self.debugInv_, Colors.OKGREEN + "TAKE " + Colors.ENDC, i) for _ in range(0, self.around_[self.currentPos_].count(GameObj.Food)): self.takeNow(GameObj.Food)
def waitForInstructions(self): """ J'attend de savoir ce que je dois poser par terre / Je ne fais rien s'il n'y pas d'instructions (incantation en cours) """ dPrint(self.debugInv_, Colors.SMALL + "waitForInstructions" + Colors.ENDC, self.id_, self.leadID) self.emergency()
def secureElevationSecondLead(self): """ On vérifie le bon fonctionnement de l'incantation """ dPrint(self.debugInv_, Colors.SMALL + "secureElevationSecondLead" + Colors.ENDC, self.id_, self.leadID) self.emergency() if self.placeIsReadyToElevLead() is False: dPrint(self.debugInv_, "Try to fix place") self.removeItemThatShouldntBeThereSecondLead()
def waitForGoNoLead(self): """ On attend de savoir si on doit se diriger vers une incantation ou si c'est cancel """ dPrint(self.debugInv_, Colors.SMALL + "waitForGoNoLead" + Colors.ENDC, self.id_, self.leadID) self.emergency() getattr( self, self.foodStage_[min([ va if self.inventory_[GameObj.Food] < va else self.maxFoodStage for va, v in self.foodStage_.items() ])])() self.getStones()
def updateLookAround(self, msg, _): """ Parse Look Around """ dPrint(self.debug_, Colors.HEADER + "Look Around" + Colors.ENDC, msg, self.around_) self.around_ = [[ links[e] for e in list( filter( lambda x: True if x.replace(' ', '') is not None and x. replace(' ', '') != '' else False, i.split(' '))) ] for i in msg.replace('[', '').replace(']', '').split(',')] self.currentPos_ = 0 self.currentDir_ = Command.Forward
def updateInv(self, msg, _): """ Parse Inventory """ dPrint(self.debug_, Colors.HEADER + "Update Inventory" + Colors.ENDC, msg, self.inventory_) self.inventory_ = { links[v[0]]: int(v[1]) for v in [ list( filter(lambda x: True if x != '' and x != ' ' else False, i.split(' '))) for i in msg.replace('[', '').replace(']', '').split(',') ] }
def waitForOthersCmgLead(self): """ On attend que les autres viennent. Quand ils sont là, ils envoient un msg et leur status passe à True dans comingsIDs_ On envoie la position régulièrement """ dPrint(self.debugInv_, Colors.SMALL + "waitForOthersCmgLead" + Colors.ENDC, self.id_, self.leadID) self.emergency() for i, j in self.sameLvlIDs_.items(): if j[0] is False: return self.setUpElevLead() self.situation_ = "setOrganizationLead"
def emergency(self): if self.inventory_[GameObj.Food] <= 7: self.broadcast(' '.join( [str(self.newNb()), "ALERT", str(self.id_)])) dPrint( self.debugInv_, Colors.OKGREEN + "ALLLLLLLLLLLLLLLLLERRRRRRRRRTTT" + Colors.ENDC) for i in range(15): self.lookAroundNow() self.goFastEat() self.countLimit_ = self.limit_ self.countItersBeforeCancel = self.itersBeforeCancel self.countCoolDown = 10 self.sameLvlIDs_.clear() self.situation_ = 'normalLife'
def rcvBroadCast(self): msg = self.CSLink_.getServerMsg() if 'message' in msg: self.CSLink_.clearServerMsg() msg = msg[len('message '):] dirC = int(msg.split(',')[0]) msg = msg.split(',')[1][1:] dPrint(self.debugInv_, "Broadcast Received: " + msg + " " + self.situation_) getattr(self, self.situation_ + "Msg")(dirC, msg) return True if ('Elevation underway' in msg or 'Current level:' in msg) and (len(self.pendingRqt_) == 0 or self.pendingRqt_[0][0] != Command.Incantation): self.CSLink_.clearServerMsg() self.updateIncantation(msg) return True return False
def placeIsReadyToElevLead(self): self.lookAroundNow() for i, j in elevRqrmts[self.level_].items(): if self.around_[self.currentPos_].count(i) != j: dPrint(self.debugInv_, 'Invalid ', self.around_[self.currentPos_].count(i), j, i) return False if self.around_[self.currentPos_].count( GameObj.Player) != elevPlayers[self.level_]: dPrint( self.debugInv_, colored( "MISSING there is " + str(self.around_[self.currentPos_].count(GameObj.Player)) + ' need: ' + str(elevPlayers[self.level_]), "red")) return False if self.around_[self.currentPos_].count(GameObj.Food) != 0: return False return True
def normalLife(self): dPrint(self.debugInv_, Colors.SMALL + "Normal Life" + Colors.ENDC, self.id_, self.leadID) self.emergency() getattr( self, self.foodStage_[min([ va if self.inventory_[GameObj.Food] < va else self.maxFoodStage for va, v in self.foodStage_.items() ])])() self.getStones() # dPrint(self.debugInv_, self.eggCreated, self.places, self.first, self.inventory_[GameObj.Food]) if self.eggCreated is False and self.places < 8 and self.first is True and self.inventory_[ GameObj.Food] > 30 and time.time() - self.startTime > 4: while self.places < 8: self.fork() self.forward() self.places += 1 self.eggCreated = True self.countCoolDown -= 1 if self.haveGoodAmountOfStones( ) and self.situation_ == 'normalLife' and self.inventory_[ GameObj.Food] > foodLevel[ self. level_] and self.countCoolDown <= 0 and self.level_ < 8: self.countLimit_ = self.limit_ self.countCoolDown = self.coolDown self.countItersBeforeCancel = self.itersBeforeCancel if self.level_ > 1: self.sameLvlIDs_.clear() self.countLimit_ = self.limit_ self.situation_ = "waitForAnswersLead" self.myIncNb_ += 1 else: self.setUpElevLead() self.situation_ = "setOrganizationLead"
def waitForAnswersLeadMsg(self, dirC, msg): """ On attend que les autres répondent à notre requête Si trop de temps est écoulé on retourne au cas 1 [Gestion Des messages] """ msg = self.updateComNbs(msg) if msg is None: return if msg[0] == 'OK' and int(msg[1]) == self.id_ and int( msg[2]) == self.myIncNb_: self.sameLvlIDs_[int(msg[3])] = [False, strToinv(msg[4])] return if msg[0] == 'LEAD' and self.level_ == int( msg[1]) and int(msg[2]) > self.id_: dPrint(self.debugInv_, colored("CO FOUND REPLACE", "red")) self.broadcast(' '.join([ str(self.newNb()), 'CANCELALL', str(self.id_), str(self.myIncNb_) ])) self.situation_ = "normalLife" self.sameLvlIDs_.clear() # self.broadcast(' '.join([str(self.newNb()), 'OK', str(self.leadID), str(self.othIncNb_), str(self.id_), invToStr(self.inventory_)])) return if msg[0] == 'ALERT' and int(msg[1]) in list(self.sameLvlIDs_.keys()): self.broadcast(' '.join([ str(self.newNb()), 'CANCELALL', str(self.id_), str(self.myIncNb_) ])) self.sameLvlIDs_.clear() self.situation_ = 'normalLife' return
def setUpElevLead(self): missing = elevRqrmts[self.level_].copy() msg = {} dPrint(self.debugInv_, Colors.UNDERLINE + "Setup Elevation" + Colors.ENDC) self.inventory() self.lookAroundNow() for i in self.around_[self.currentPos_]: # Make elevation place empty self.takeNow(i) dPrint(self.debugInv_, Colors.UNDERLINE + "SET WHAT S NEEDED" + Colors.ENDC) for i, j in missing.items(): # Pour chaque item for e in range( min(self.inventory_[i], j) ): # On en set le nombre min entre l'inventaire et ce qu'il manque self.set(i) missing[i] -= 1 assert missing[i] >= 0 if missing[i] == 0: continue for p, pv in self.sameLvlIDs_.items(): # Pour chaque player if p not in msg.keys(): msg[p] = {i: 0 for i in self.inventory_} msg[p][i] = min(pv[1][i], missing[i]) missing[i] -= msg[p][i] dPrint(self.debugInv_, "MIN ", min(self.inventory_[i], j)) dPrint(self.debugInv_, "INV ", msg[p][i]) dPrint(self.debugInv_, Colors.UNDERLINE + "END SETUP ELEVATION" + Colors.ENDC) if len(list(msg.keys())) > 0: self.broadcast(' '.join([ str(self.newNb()), 'SET', str(self.id_), setRequestToStr(msg) ]))
def readWrite(self): try: while self.thread_running is True: read_sckt = [self.socket] write_sckt = [] while self.stopM is True: self.stopT = True self.stopT = False if len(self.buffers["write"]) != 0: write_sckt.append(self.socket) readable, writable, useless = select.select( read_sckt, write_sckt, [], 0) if len(readable) != 0: buf = str(readable[0].recv(1024), 'utf-8') if len(buf) == 0: self.activeConnection = False exit(0) self.buffers["read"] += buf if len(writable) != 0 and len(self.buffers["write"]) != 0: tmp = self.buffers["write"] # dPrint(self.debug_, colored("tmp \"" + str(tmp) + "\"", "green"), tmp.find(b'\n')) while tmp.find(b'\n') != -1: tmp2 = tmp[:tmp.find(b'\n') + 1] tmp = tmp[tmp.find(b'\n') + 1:] dPrint( self.debug_, colored("send \"" + str(tmp2) + "\" to server", "green")) writable[0].send(bytes(tmp2)) self.buffers["write"] = self.buffers["write"][len(tmp2 ):] except: self.activeConnection = False self.thread_running = False exit(0) pass
def setOrganizationLead(self): """ Dés qu'il y a la bonne quantité d'élément on incante. Puis on passe à la situation suivante """ dPrint(self.debugInv_, Colors.SMALL + "setOrganizationLead" + Colors.ENDC, self.id_, self.leadID) self.emergency() if self.placeIsReadyToElevLead() is False: dPrint(self.debugInv_, "Place is not ready") self.removeItemThatShouldntBeThereSecondLead() self.countLimit_ -= 1 if self.countLimit_ <= 0: self.broadcast(' '.join([ str(self.newNb()), 'CANCELALL', str(self.id_), str(self.myIncNb_) ])) self.situation_ = 'normalLife' self.eject() self.sameLvlIDs_.clear() self.countLimit_ = self.limit_ return if self.level_ > 1: pass # Définir un second leader dPrint(self.debugInv_, "INCANTATION PLACE", self.around_[self.currentPos_]) if self.level_ > 1: self.broadcast(' '.join([ self.newNb(), 'SAFE', str(self.id_), str(self.myIncNb_), str(list(self.sameLvlIDs_.keys())[0]) ])) self.incantation() self.updateDataFromServBlock((Command.Incantation, "End"))
def idsTohaveEnoughStones(self): possibilities = list( itertools.combinations(list(self.sameLvlIDs_.keys()), elevPlayers[self.level_] - 1)) dPrint(self.debugInv_, colored("recherche des combinaisons ", "red"), possibilities) for p in possibilities: others = [self.sameLvlIDs_[i][1] for i in p] dPrint(self.debugInv_, "OTHERS INVS ", others) others = { key: sum(e[key] for e in others) for key in others[0].keys() } dPrint(self.debugInv_, "OTHERS INVS 2 ", others) for s in elevRqrmts[self.level_]: if self.inventory_[s] + others[s] < elevRqrmts[self.level_][s]: others = None break if others is not None: return p return None
def forward(self): self.waitForPlace() self.CSLink_.forward() self.currentPos_ = self.getPosForward(self.currentPos_) self.pendingRqt_ += [(Command.Forward, None)] dPrint(self.debug_, colored("Go forward", "blue"))
def right(self): self.waitForPlace() self.CSLink_.right() self.currentDir_ = Command.Right self.pendingRqt_ += [(Command.Right, None)] dPrint(self.debug_, colored("Turn Right", "blue"))
def fork(self): pass self.waitForPlace() self.CSLink_.fork() self.pendingRqt_ += [(Command.Fork, None)] dPrint(self.debugInv_, Colors.UNDERLINE + "Fork" + Colors.ENDC)
def connectNbr(self): pass self.waitForPlace() self.CSLink_.connectNbr() self.pendingRqt_ += [(Command.Connect_nbr, None)] dPrint(self.debugInv_, Colors.UNDERLINE + "Connect nbr" + Colors.ENDC)
def incantation(self): self.waitForPlace() self.CSLink_.incantation() self.pendingRqt_ += [(Command.Incantation, "Start")] self.pendingRqt_ += [(Command.Incantation, "End")] dPrint(self.debugInv_, Colors.UNDERLINE + "ELEVATION" + Colors.ENDC)
def left(self): self.waitForPlace() self.CSLink_.left() self.currentDir_ = Command.Left self.pendingRqt_ += [(Command.Left, None)] dPrint(self.debug_, colored("Turn Left", "blue"))