diff --git a/ai/src/AI.py b/ai/src/AI.py index e5fbe188..1ae48270 100644 --- a/ai/src/AI.py +++ b/ai/src/AI.py @@ -40,7 +40,7 @@ class AI: """ - def __init__(self, host, port, teamName): + def __init__(self, host, port, teamName, logs): """ Constructor of the AI class Assign the API, the player and the team name @@ -53,14 +53,15 @@ def __init__(self, host, port, teamName): teamName : str the name of the team """ - self.api = API(host, port) - self.player = Player(teamName) + self.api = API(host, port, logs) + self.player = Player(teamName, logs) self.teamName = teamName self.threads = [] self.creationTime = time.time_ns() self.myuuid = str(uuid.uuid4()) self.isRunning = True self.buffer = "" + self.logs = logs def serverCommunicationInThread(self): @@ -91,7 +92,8 @@ def serverCommunicationInThread(self): self.player.actions.pop(0) self.player.commands.pop(0) self.player.callbacks.pop(0) - print("Regrouping Start", flush=True, file=sys.stderr) + if self.logs: + print("Regrouping Start", flush=True, file=sys.stderr) while self.isRunning: responses = self.api.receiveData(0.1) if responses is not None: @@ -135,7 +137,9 @@ def run(self): and send it to the server and after that, it will receive the response from the server and handle it """ - fileName = createLogs(self.myuuid) + fileName = "" + if self.logs: + fileName = createLogs(self.myuuid) self.api.connect() self.api.initConnection(self.teamName, fileName) @@ -154,12 +158,14 @@ def run(self): if self.player.inventory.food <= 8: for msg in self.player.broadcastReceived: if msg[1].message == "Yes": - print("I'm a slave", flush=True, file=sys.stderr) + if self.logs: + print("I'm a slave", flush=True, file=sys.stderr) self.player.isLeader = Role.SLAVE self.player.broadcastReceived.remove(msg) break if self.player.isLeader == Role.UNDEFINED: - print("I'm a leader", flush=True, file=sys.stderr) + if self.logs: + print("I'm a leader", flush=True, file=sys.stderr) self.player.isLeader = Role.LEADER if self.player.isLeader == Role.LEADER: @@ -167,8 +173,6 @@ def run(self): while True: if len(self.player.actions) == 0: - if self.player.currentMode != Mode.NONE: - print("Choose action", flush=True) self.player.chooseAction(self.teamName, self.myuuid, self.creationTime) if self.threads[0].is_alive() == False: break diff --git a/ai/src/Network/API.py b/ai/src/Network/API.py index 885a1b40..3933080f 100644 --- a/ai/src/Network/API.py +++ b/ai/src/Network/API.py @@ -45,7 +45,7 @@ class API: """ - def __init__(self, host : str, port : int): + def __init__(self, host : str, port : int, logs : bool): """ Constructor of the API class @@ -64,6 +64,7 @@ def __init__(self, host : str, port : int): self.inputs : list = [] self.outputs : list = [] self.sock : socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.logs = logs def connect(self): @@ -99,7 +100,8 @@ def sendData(self, data : str, timeout : int = None): for s in write: if s == self.sock: s.send(data.encode()) - print("sent : ", stringifyData(data), flush=True, file=sys.stderr) + if self.logs: + print("sent : ", stringifyData(data), flush=True, file=sys.stderr) def receiveData(self, timeout : float = None): @@ -121,7 +123,8 @@ def receiveData(self, timeout : float = None): print("Server disconnected") sys.exit(0) else: - print("received :", stringifyData(data.decode()), flush=True, file=sys.stderr) + if self.logs: + print("received :", stringifyData(data.decode()), flush=True, file=sys.stderr) return data.decode() return None @@ -173,9 +176,10 @@ def initConnection(self, teamName : str, fileName : str = ""): except Exception as e: raise APIException("invalid map size", fileName) - print("Connected to server") - print(f"Client number: {clientNum}") - print(f"Map size: x = {x}, y = {y}") + if self.logs: + print("Connected to server") + print(f"Client number: {clientNum}") + print(f"Map size: x = {x}, y = {y}") return clientNum, x, y diff --git a/ai/src/Player/Player.py b/ai/src/Player/Player.py index 7871c305..f190ec33 100644 --- a/ai/src/Player/Player.py +++ b/ai/src/Player/Player.py @@ -155,7 +155,7 @@ class Player: """ - def __init__(self, teamName : str): + def __init__(self, teamName : str, logs : bool = False): """ Constructor of the Player class """ @@ -185,6 +185,7 @@ def __init__(self, teamName : str): self.teamName = teamName self.enemyBroadcast = [] self.alliesUuid = [] + self.logs = logs def __str__(self): @@ -281,7 +282,8 @@ def broadcast(self, message : str = "Hello", teamName : str = "", myuuid : str = creationTime : int the creation time of the message """ - print("Broadcasting message: ", message, flush=True, file=sys.stderr) + if self.logs: + print("Broadcasting message: ", message, flush=True, file=sys.stderr) encryptedMsg = Message(teamName) encryptedMsg.createMessage(message, myuuid, creationTime) self.actions.append(Action.BROADCAST) @@ -453,9 +455,11 @@ def updateBroadcastReceived(self, message : str, aiTimestamp : int): message = message.split(", ")[1] msg = Message(self.teamName) if msg.createMessageFromEncryptedJson(message): - print("Received message: ", msg.message, flush=True, file=sys.stderr) + if self.logs: + print("Received message: ", msg.message, flush=True, file=sys.stderr) if msg in self.messageHistory or msg.messageTimestamp < aiTimestamp: - print("Already received this message", flush=True, file=sys.stderr) + if self.logs: + print("Already received this message", flush=True, file=sys.stderr) return self.broadcastReceived.append((direction, msg)) self.messageHistory.append(msg) @@ -463,7 +467,8 @@ def updateBroadcastReceived(self, message : str, aiTimestamp : int): if msg.senderUuid not in self.alliesUuid: self.alliesUuid.append(msg.senderUuid) else: - print("Received enemy message: ", message, flush=True, file=sys.stderr) + if self.logs: + print("Received enemy message: ", message, flush=True, file=sys.stderr) self.enemyBroadcast.append((direction, message)) @@ -515,7 +520,8 @@ def handleElevation(self, response : str, teamName : str, myuuid : str, creation self.currentlyElevating = False return False elif response == "ko": - print("Elevation failed", flush=True, file=sys.stderr) + if self.logs: + print("Elevation failed", flush=True, file=sys.stderr) if self.isLeader == Role.LEADER: self.currentMode = Mode.FOOD self.broadcast("Food", teamName, myuuid, creationTime) @@ -593,7 +599,8 @@ def connectMissingPlayers(self): """ Connect the missing players """ - print("Connecting missing players", flush=True, file=sys.stderr) + if self.logs: + print("Connecting missing players", flush=True, file=sys.stderr) for _ in range(0, min(self.unusedSlots, 5)): from ai.src.AI import forkAI forkAI() @@ -623,16 +630,19 @@ def updateModeLeader(self): if self.inventory.food < 35: self.currentMode = Mode.FOOD elif self.inventory.food >= 45 or self.currentMode != Mode.FOOD: - print(self.currentFood, self.inventory.food) + if self.logs: + print(self.currentFood, self.inventory.food) if self.currentFood != self.inventory.food and self.waitingResponse == True: if self.isTimed == True: - print("Handling response") + if self.logs: + print("Handling response") self.currentMode = Mode.HANDLINGRESPONSE self.isTimed = False else: self.isTimed = True elif self.currentFood != self.inventory.food and self.waitingResponse == False: - print("Broadcasting") + if self.logs: + print("Broadcasting") self.currentMode = Mode.BROADCASTING self.waitingResponse = True elif self.nbSlaves < 5 and self.waitingResponse == False: @@ -801,9 +811,11 @@ def handleResponseBroadcast(self): """ Handle the response of the broadcast """ - print(self.broadcastReceived, flush=True) + if self.logs: + print(self.broadcastReceived, flush=True) self.nbSlaves = len(self.broadcastReceived) - print("nb slaves: ", self.nbSlaves, flush=True) + if self.logs: + print("nb slaves: ", self.nbSlaves, flush=True) globalInv = Inventory(0, 0, 0, 0, 0, 0, 0, 0) minInv = Inventory(0, 8, 9, 10, 5, 6, 1, 0) if self.nbSlaves >= 5: @@ -818,8 +830,9 @@ def handleResponseBroadcast(self): if globalInv.hasMoreStones(minInv): self.currentMode = Mode.REGROUP else: - print("Not enough stones", flush=True, file=sys.stdout) - print("Not enough stones", flush=True, file=sys.stderr) + if self.logs: + print("Not enough stones", flush=True, file=sys.stdout) + print("Not enough stones", flush=True, file=sys.stderr) self.waitingResponse = False self.broadcastReceived = [] @@ -876,7 +889,8 @@ def waitingEveryone(self, teamName : str, myuuid : str, creationTime : int): the creation time of the message """ nbSlavesHere = self.countSlavesThatArrived(self.broadcastReceived) - print("nb slaves here: ", nbSlavesHere, flush=True) + if self.logs: + print("nb slaves here: ", nbSlavesHere, flush=True) if nbSlavesHere >= 5: self.broadcast("Drop", teamName, myuuid, creationTime) self.currentMode = Mode.DROPPING @@ -913,7 +927,8 @@ def waitingDrop(self): self.currentMode = Mode.ELEVATING self.broadcastReceived = [] self.nbSlavesHere = nbSlavesHere - print("nb slaves who finished droping: ", nbSlavesHere, flush=True) + if self.logs: + print("nb slaves who finished droping: ", nbSlavesHere, flush=True) if nbSlavesHere >= 5: self.currentMode = Mode.ELEVATING self.broadcastReceived = [] @@ -938,7 +953,8 @@ def dropping(self, teamName : str, myuuid : str, creationTime : int): if self.isLeader == Role.LEADER: self.waitingDrop() else: - print("Dropping", flush=True, file=sys.stderr) + if self.logs: + print("Dropping", flush=True, file=sys.stderr) if self.inventory.linemate > 0: self.set("linemate") if self.inventory.deraumere > 0: @@ -976,11 +992,12 @@ def regroupAction(self, teamName : str, myuuid : str, creationTime : int): else: isThereARegroup = False - if len(self.broadcastReceived) != 0: + if len(self.broadcastReceived) != 0 and self.logs: print(self.broadcastReceived, flush=True, file=sys.stderr) for broadcast in self.broadcastReceived: if broadcast[1].message == "Drop": - print("DROP MODE", flush=True, file=sys.stderr) + if self.logs: + print("DROP MODE", flush=True, file=sys.stderr) self.currentMode = Mode.DROPPING self.broadcastReceived = [] return @@ -1063,14 +1080,16 @@ def chooseAction(self, teamName : str, myuuid : str, creationTime : int): self.look(self.lookingForStones) return elif self.currentMode == Mode.FORKING: - print("Forking") + if self.logs: + print("Forking") from ai.src.AI import forkAI self.fork(forkAI) self.nbSlaves += 1 self.cmdInventory() return elif self.currentMode == Mode.BROADCASTING: - print("in broadcast") + if self.logs: + print("in broadcast") self.askSlavesForInventory(teamName, myuuid, creationTime) self.cmdInventory() return diff --git a/ai/src/main.py b/ai/src/main.py index b87b352a..64e553fa 100644 --- a/ai/src/main.py +++ b/ai/src/main.py @@ -27,12 +27,13 @@ def writeHelp(exitCode : int = 0): """ print("") print("Usage:") - print("\t./zappy_ai -p port -n name -h machine") + print("\t./zappy_ai -p port -n name -h machine [-l on/off]") print("") print("Description:") print("\t-p port\t\tis the port number") print("\t-n name\t\tis the name of the team") print("\t-h machine\tis the name of the machine; localhost by default") + print("\t-l on/off\tturn logs on or off; off by default") print("\t--help\t\tprint this help") print("") sys.exit(exitCode) @@ -51,6 +52,7 @@ def getArgs(av=sys.argv): host = LOCALHOST port = -1 name = "" + logs = False try: for i in range(1, len(av)): if av[i] == "-p": @@ -59,28 +61,34 @@ def getArgs(av=sys.argv): name = (av[i + 1]).replace("\n", "") elif av[i] == "-h": host = av[i + 1] + elif av[i] == "-l": + if av[i + 1].lower() == "on": + logs = True + elif av[i + 1].lower() == "off": + logs = False + else: + raise ArgsException("Error: invalid arguments") if port < PORT_MIN or port > PORT_MAX or name == "": raise ArgsException("Error: invalid arguments") except Exception as e: print("Error: invalid arguments", file=sys.stderr, flush=True) writeHelp(84) - return host, port, name + return host, port, name, logs def main(): """ Main function """ - host, port, teamName = getArgs() + host, port, teamName, logs = getArgs() try: - ai = AI(host, port, teamName) + ai = AI(host, port, teamName, logs) try: ai.run() except KeyboardInterrupt: - ai.api.close() ai.isRunning = False ai.threads[0].join() - print("The AI has been stopped by a keyboard interrupt", file=sys.stderr) + ai.api.close() except PlayerDeathException as e: print(e, file=sys.stderr) sys.exit(0) diff --git a/tests/ai/tests/Network/TestAPI.py b/tests/ai/tests/Network/TestAPI.py index 0e2856b7..e6129073 100644 --- a/tests/ai/tests/Network/TestAPI.py +++ b/tests/ai/tests/Network/TestAPI.py @@ -25,7 +25,7 @@ def testAPI(): def testAPIConstructor(): try: - api = API("localhost", 4242) + api = API("localhost", 4242, False) assert api.host == "localhost" assert api.port == 4242 assert api.inputs == [] diff --git a/tests/ai/tests/TestAI.py b/tests/ai/tests/TestAI.py index 51f0c50e..2dc95d43 100644 --- a/tests/ai/tests/TestAI.py +++ b/tests/ai/tests/TestAI.py @@ -18,7 +18,7 @@ def testAI(): def testAIConstructor(): try: - ai = AI("localhost", 4242, "test") + ai = AI("localhost", 4242, "test", False) assert ai.api.host == "localhost" assert ai.api.port == 4242 assert ai.teamName == "test"