def __init__(self, sock, client, rules, name, data_queue): Thread.__init__(self) if not isinstance(sock, socket.socket) or sock is None: raise TypeError("Necessite une vraie socket") self.__socket = sock self.__client = client self.__rules = rules self.__name = name self.__data_queue = data_queue self.__grid = Grid(self.__rules)
def run(self): print("[PLAYER - {}] Démarrage".format( self.__player_name.capitalize())) self.__sock.send("NME".encode("ascii")) # Initialization # SET header = self.__sock.recv(3).decode("ascii") if header.strip() != "SET": print("[PLAYER - {}] Protocol Error at SET".format( self.__player_name.capitalize())) else: size_n, size_m = self.__receive_data(16, "1q1q") # HUM header = self.__sock.recv(3).decode("ascii") if header.strip() != "HUM": print("[PLAYER - {}] Protocol Error at HUM".format( self.__player_name.capitalize())) else: number_of_homes = self.__receive_data(8, "1q")[0] homes_raw = self.__receive_data(number_of_homes * 2 * 8, "{}q".format(number_of_homes * 2)) homes = list(self.__grouper(2, homes_raw)) # HME header = self.__sock.recv(3).decode("ascii") if header.strip() != "HME": print("[PLAYER - {}] Protocol Error at HME".format( self.__player_name.capitalize())) else: start_position = self.__receive_data(16, "1q1q") # MAP header = self.__sock.recv(3).decode("ascii") if header.strip() != "MAP": print("[PLAYER - {}] Protocol Error at HME".format( self.__player_name.capitalize())) else: number_map_commands = self.__receive_data(8, "1q")[0] map_commands_raw = self.__receive_data( number_map_commands * 8 * 5, "{}q".format(number_map_commands * 5)) map_commands = list(self.__grouper(5, map_commands_raw)) # A ce stade, toutes les infos nécessaires sont disponibles print("[PLAYER - {}] Received all the data. Initializing map".format( self.__player_name.capitalize())) self.__gamerules = GameRules(self.__parameters) self.__gamerules.loadgame(map_commands) self.__grid = Grid(self.__gamerules.rules) print("[PLAYER - {}] Map done: {}".format( self.__player_name.capitalize(), self.__grid))
def __init__(self, socks, clients, parameters): Thread.__init__(self) if not isinstance(socks[0], socket.socket) or \ not isinstance(socks[0], socket.socket) or \ socks[0] is None or \ socks[1] is None: raise TypeError("Necessite une vraie socket") self.__sockets = socks self.__clients = clients self.__vampires_thread = None self.__werewolves_thread = None self.__data_queue = Queue() self.__rules = GameRules(parameters).creategame() self.__grid = Grid(self.__rules) print("[GAME] Map initialized") print("[GAME] Rules: {}".format(self.__rules))
class BasePlayer(Thread): """ A player """ def __init__(self, host, port): Thread.__init__(self) self.__host = host self.__port = port self.player_name = "" self.enemy_name = "" self.__sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.__sock.connect((self.__host, int(self.__port))) self.grid = None self.current_turn = 0 self.__gameover = False self.__homes = [] @property def gameover(self): return self.__gameover @property def homes(self): return self.__homes def __receive_data(self, size, fmt): data = bytes() while len(data) < size: data += self.__sock.recv(size - len(data)) return struct.unpack(fmt, data) @staticmethod def __grouper(_n, iterable): args = [iter(iterable)] * _n return zip(*args) def __initialize_game(self, nme=True): """ Runs the different checks and instanciate a map """ print("[PLAYER - {}] Démarrage".format(self.player_name.capitalize())) if nme: # Envoi de la commande NME self.__sock.send("NME".encode("ascii")) self.__sock.send(struct.pack("1B", 6)) self.__sock.send("Hummus".encode("ascii")) # SET header = self.__sock.recv(3).decode("ascii") if header != "SET": print("[PLAYER - {}] Protocol Error at SET".format( self.player_name.capitalize())) else: size_n, size_m = self.__receive_data(2, "2B") #print(size_n) #print(size_m) # HUM header = self.__sock.recv(3).decode("ascii") if header != "HUM": print("[PLAYER - {}] Protocol Error at HUM".format( self.player_name.capitalize())) else: number_of_homes = self.__receive_data(1, "1B")[0] homes_raw = self.__receive_data(number_of_homes * 2, "{}B".format(number_of_homes * 2)) self.__homes = list(self.__grouper(2, homes_raw)) #print(homes) # HME header = self.__sock.recv(3).decode("ascii") if header != "HME": print("[PLAYER - {}] Protocol Error at HME".format( self.player_name.capitalize())) else: start_position = tuple(self.__receive_data(2, "2B")) #print(start_position) # MAP header = self.__sock.recv(3).decode("ascii") if header != "MAP": print("[PLAYER - {}] Protocol Error at MAP".format( self.player_name.capitalize())) else: number_map_commands = self.__receive_data(1, "1B")[0] map_commands_raw = self.__receive_data( number_map_commands * 5, "{}B".format(number_map_commands * 5)) map_commands = list(self.__grouper(5, map_commands_raw)) #print(map_commands) for command in map_commands: if command[0] == start_position[0] and command[ 1] == start_position[1]: if command[3] != 0: self.player_name = "Vampires" self.enemy_name = "Werewolves" else: self.player_name = "Werewolves" self.enemy_name = "Vampires" # A ce stade, toutes les infos nécessaires sont disponibles print("[PLAYER - {}] Received all the data. Initializing map".format( self.player_name.capitalize())) self.grid = Grid(size_n, size_m) self.grid.update_grid(map_commands) print(self.grid) # def is_gameover(self): # beasts = self.grid.get_beasts(self.player_name.lower()) # if len(beasts) == 0: # return True # else: # return False def __reset_game(self): """ Resets the game to a blank map """ self.grid = None def get_available_moves(self): """ Returns a list of neighbours represented as a list of tuples by group of beasts """ beasts = self.grid.get_beasts(self.player_name.lower()) n = self.grid.size_n #nb of lines m = self.grid.size_m #nb of columns new_neighbors = [[]] for i in range(len(beasts)): x = beasts[i][0] y = beasts[i][1] temp_neighbors = [(x - 1, y - 1), (x - 1, y), (x - 1, y + 1), (x, y - 1), (x, y + 1), (x + 1, y - 1), (x + 1, y), (x + 1, y + 1)] for (k, l) in temp_neighbors: if 0 <= k < m and 0 <= l < n: new_neighbors[i] += [(k, l)] return new_neighbors def get_next_moves(self): """ Function to be overridden by the players Returns a list of the different moves """ pass def __process_update(self): number_of_moves = self.__receive_data(1, "1B")[0] upd_commands_raw = self.__receive_data( number_of_moves * 5, "{}B".format(number_of_moves * 5)) upd_commands = list(self.__grouper(5, upd_commands_raw)) self.grid.update_grid(upd_commands) def __send_moves(self, beasts, new_beasts): """ Creates and sends the MOV command """ commands = [] for i in range(len(beasts)): commands.append((beasts[i][0], beasts[i][1], beasts[i][2], new_beasts[i][0], new_beasts[i][1])) number_of_moves = len(commands) self.__sock.send("MOV".encode("ascii")) self.__sock.send(struct.pack("1B", number_of_moves)) for move in commands: self.__sock.send(struct.pack("5B", *move)) def run(self): """ Thread """ self.__initialize_game() while True: header = self.__sock.recv(3).decode("ascii") if header == "END": self.__reset_game() self.__gameover = True # self.__initialize_game(nme=False) elif header == "BYE": print("[PLAYER - {}] - Goodbye !".format( self.player_name.capitalize())) self.__sock.close() return True elif header == "UPD": self.current_turn += 1 print("[PLAYER - {}] - Turn {}".format( self.player_name.capitalize(), self.current_turn)) self.__process_update() (beasts, new_beasts) = self.get_next_moves() self.__send_moves(beasts, new_beasts) # Send data to the server
def __initialize_game(self, nme=True): """ Runs the different checks and instanciate a map """ print("[PLAYER - {}] Démarrage".format(self.player_name.capitalize())) if nme: # Envoi de la commande NME self.__sock.send("NME".encode("ascii")) self.__sock.send(struct.pack("1B", 6)) self.__sock.send("Hummus".encode("ascii")) # SET header = self.__sock.recv(3).decode("ascii") if header != "SET": print("[PLAYER - {}] Protocol Error at SET".format( self.player_name.capitalize())) else: size_n, size_m = self.__receive_data(2, "2B") #print(size_n) #print(size_m) # HUM header = self.__sock.recv(3).decode("ascii") if header != "HUM": print("[PLAYER - {}] Protocol Error at HUM".format( self.player_name.capitalize())) else: number_of_homes = self.__receive_data(1, "1B")[0] homes_raw = self.__receive_data(number_of_homes * 2, "{}B".format(number_of_homes * 2)) self.__homes = list(self.__grouper(2, homes_raw)) #print(homes) # HME header = self.__sock.recv(3).decode("ascii") if header != "HME": print("[PLAYER - {}] Protocol Error at HME".format( self.player_name.capitalize())) else: start_position = tuple(self.__receive_data(2, "2B")) #print(start_position) # MAP header = self.__sock.recv(3).decode("ascii") if header != "MAP": print("[PLAYER - {}] Protocol Error at MAP".format( self.player_name.capitalize())) else: number_map_commands = self.__receive_data(1, "1B")[0] map_commands_raw = self.__receive_data( number_map_commands * 5, "{}B".format(number_map_commands * 5)) map_commands = list(self.__grouper(5, map_commands_raw)) #print(map_commands) for command in map_commands: if command[0] == start_position[0] and command[ 1] == start_position[1]: if command[3] != 0: self.player_name = "Vampires" self.enemy_name = "Werewolves" else: self.player_name = "Werewolves" self.enemy_name = "Vampires" # A ce stade, toutes les infos nécessaires sont disponibles print("[PLAYER - {}] Received all the data. Initializing map".format( self.player_name.capitalize())) self.grid = Grid(size_n, size_m) self.grid.update_grid(map_commands) print(self.grid)
class GameThread(Thread): """ A thread to communicate with a client """ def __init__(self, sock, client, rules, name, data_queue): Thread.__init__(self) if not isinstance(sock, socket.socket) or sock is None: raise TypeError("Necessite une vraie socket") self.__socket = sock self.__client = client self.__rules = rules self.__name = name self.__data_queue = data_queue self.__grid = Grid(self.__rules) def __getcommand(self): data = bytes() while len(data) < 3: data += self.__socket.recv(3 - len(data)) return data.decode("ascii") def __createcommand(self, ordre): if ordre == "SET": code = "SET".encode("ascii") command = struct.pack( "1q1q", self.__rules["size_n"], self.__rules["size_m"] ) commands = [code, command] elif ordre == "HUM": code = "HUM".encode("ascii") positions_of_homes = [] for home in self.__rules["positions_of_homes"]: positions_of_homes.append(home[0]) positions_of_homes.append(home[1]) command_1 = struct.pack( "1q", self.__rules["number_of_homes"] ) command_2 = struct.pack( "{}q".format(self.__rules["number_of_homes"] * 2), *positions_of_homes ) commands = [code, command_1, command_2] elif ordre == "HME": code = "HME".encode("ascii") command = struct.pack( "1q1q", \ self.__rules["{}_start".format(self.__name)][0], \ self.__rules["{}_start".format(self.__name)][1] ) commands = [code, command] elif ordre == "MAP": # Send the command... number_of_orders, orders = self.__grid.compute_map() code = "MAP".encode("ascii") command_1 = struct.pack( "1q", number_of_orders ) command_2 = struct.pack( "{}q".format(number_of_orders * 5), \ *orders ) commands = [code, command_1, command_2] elif ordre == "END": commands = [struct.pack("3s", "END".encode("ascii"))] elif ordre == "BYE": commands = [struct.pack("3s", "BYE".encode("ascii"))] else: commands = None return commands def __sendcommands(self, commands): if commands: for command in commands: self.__socket.send(command) else: print( "[GAMETHREAD - {}] La commande n'est pas reconnue".format( self.__name.capitalize() ) ) def __printerror(self, message): print(message) try: self.__socket.close() except Exception: print( "[GAMETHREAD - {}] Erreur lors de la fermeture de la socket".format( self.__name.capitalize() ) ) def run(self): print("[GAMETHREAD - {}] Just connected".format(self.__name.capitalize())) # Implementation du protocole # L'idée est d'attendre en permanence une instruction du master commande = self.__getcommand() if commande != "NME": self.__printerror( "[GAMETHREAD - {}] Erreur de protocole: attendu NME".format( self.__name.capitalize() ) ) return else: print( "[GAMETHREAD - {}] Reçu NME".format(self.__name.capitalize()) ) print( "[GAMETHREAD - {}] Starting Initialization".format(self.__name.capitalize()) ) self.__data_queue.put("Hello from {}".format(self.name)) # On peut envoyer les différentes informations de jeu self.__sendcommands(self.__createcommand("SET")) self.__sendcommands(self.__createcommand("HUM")) self.__sendcommands(self.__createcommand("HME")) self.__sendcommands(self.__createcommand("MAP")) self.__socket.close() def stop(self): """ Close the socket correctly """ print("[GAMETHREAD - {}] Closing Socket".format(self.__name.capitalize())) self.__socket.close()
def copy_grid(self): previous_grid = Grid(self.grid.size_n, self.grid.size_m) for i in range(self.grid.size_n): for j in range(self.grid.size_m): previous_grid.grid[j][i] = copy(self.grid.grid[j][i]) return previous_grid