Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
    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))
Ejemplo n.º 3
0
 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)
Ejemplo n.º 6
0
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()
Ejemplo n.º 7
0
 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