class Servidor:
    def __init__(self):
        '''Inicializador de servidor.

        Crea socket de servidor, lo vincula a un puerto.'''
        # -----------------------------------------
        # Completar y agregar argumentos desde aquí

        self.host = None
        self.port = None
        self.socket_servidor = None

        # Aqui deberas preparar el socket para que escuche una conexion

        # Completar y agregar argumentos hasta aquí
        # -----------------------------------------
        print("Servidor iniciado.")
        self.juego = None  # Juego comienza nulo.
        self.socket_cliente = None  # Aún no hay cliente.

    def esperar_conexion(self):
        '''Espera a la conectarse con un cliente y obtiene su socket.'''
        print("Esperando cliente...")
        # --------------------
        # Completar desde aquí

        # Debes actualizar el valor de self.socket_cliente al conectar

        # Completar hasta aquí
        # --------------------
        print("¡Servidor conectado a cliente!")
        self.interactuar_con_cliente()

    def interactuar_con_cliente(self):
        '''Comienza ciclo de interacción con cliente.

        Recibe un acción y responde apropiadamente.'''
        self.enviar_estado('', True)
        while self.socket_cliente:
            accion = self.recibir_accion()
            self.manejar_accion(accion)

    def enviar_estado(self, mensaje, continuar):
        '''Envia estado del juego en el servidor.'''
        if continuar:
            if self.juego is not None:
                mensaje = f'{self.juego.tablero_string()}\n{mensaje}\n'
            acciones = ("¿Qué deseas hacer?\n"
                        "Para jugar nuevo juego: \\juego_nuevo\n"
                        "Para jugar en una columna: \\jugada columna\n"
                        "Para salir: \\salir\n")
            mensaje = mensaje + acciones
        # -----------------------------------------------------
        # Completar y usar un metodo para todo largo de mensaje

        mensaje_codificado = None

        # Completar hasta aquí
        # --------------------

    def recibir_accion(self):
        '''Recibe mensaje desde el cliente y lo decodifica.'''
        # -----------------------------------------------------
        # Completar y usar un metodo para todo largo de mensaje

        bytes_recibidos = self.socket_cliente.recv(
            100)  # Rayos, esto es demasiado po

        accion = None  # Respuesta resultante

        # Completar hasta aquí
        # --------------------
        return accion

    def manejar_accion(self, accion):
        '''Maneja la acción recibida del cliente.'''
        print(f'Acción recibida: {accion}')
        # --------------------
        # Completar desde aquí

        tipo = None  # Obtener el tipo de acción que envió el cliente.

        # Completar hasta aquí
        # --------------------
        if tipo == '\\juego_nuevo':
            self.juego = Juego()
            self.juego.crear_tablero()
            self.enviar_estado('', True)
        elif tipo == '\\salir':
            self.enviar_estado('¡Adios!', False)
            self.juego = None
            self.socket_cliente.close()
            print('Cliente desconectado.\n')
            self.socket_cliente = None
        elif tipo == '\\jugada':
            if self.juego is None:
                self.enviar_estado('Ningún juego ha iniciado.', True)
            else:
                # --------------------
                # Completar desde aquí

                # Obtener la jugada que envió el cliente.
                jugada = None

                # Completar hasta aquí
                # --------------------
                if not self.juego.es_jugada_valida(jugada):
                    self.enviar_estado('Jugada inválida.', True)
                else:
                    gano = self.juego.turno_jugador(jugada)
                    if gano:
                        self.enviar_estado('¡Ganaste! Se acabó el juego.',
                                           True)
                        self.juego = None
                    else:
                        perdio = self.juego.turno_cpu()
                        if perdio or self.juego.empate():
                            self.enviar_estado(
                                'No ganaste :( Se acabó el juego.', True)
                            self.juego = None
                        else:
                            self.enviar_estado('', True)
示例#2
0
class Servidor:
    def __init__(self):
        '''Inicializador de servidor.

        Crea socket de servidor, lo vincula a un puerto.'''
        # -----------------------------------------
        # Completar y agregar argumentos desde aquí

        self.host = socket.gethostbyname(socket.gethostname())
        self.port = 9001
        self.socket_servidor = socket.socket(socket.AF_INET,
                                             socket.SOCK_STREAM)

        # Aqui deberas preparar el socket para que escuche una conexion

        self.socket_servidor.bind((self.host, self.port))
        self.socket_servidor.listen()

        # Completar y agregar argumentos hasta aquí
        # -----------------------------------------
        print("Servidor iniciado.")
        self.juego = None  # Juego comienza nulo.
        self.socket_cliente = None  # Aún no hay cliente.

    def esperar_conexion(self):
        '''Espera a la conectarse con un cliente y obtiene su socket.'''
        print("Esperando cliente...")
        # --------------------
        # Completar desde aquí

        # Debes actualizar el valor de self.socket_cliente al conectar

        try:
            self.socket_cliente, address = self.socket_servidor.accept()
        except ConnectionError:
            print("Ocurrió un error.")

        # Completar hasta aquí
        # --------------------
        print("¡Servidor conectado a cliente!")
        self.interactuar_con_cliente()

    def interactuar_con_cliente(self):
        '''Comienza ciclo de interacción con cliente.

        Recibe un acción y responde apropiadamente.'''
        self.enviar_estado('', True)
        while self.socket_cliente:
            accion = self.recibir_accion()
            self.manejar_accion(accion)

    def enviar_estado(self, mensaje, continuar):
        '''Envia estado del juego en el servidor.'''
        if continuar:
            if self.juego is not None:
                mensaje = f'{self.juego.tablero_string()}\n{mensaje}\n'
            acciones = ("¿Qué deseas hacer?\n"
                        "Para jugar nuevo juego: \\juego_nuevo\n"
                        "Para jugar en una columna: \\jugada columna\n"
                        "Para salir: \\salir\n")
            mensaje = mensaje + acciones
        # -----------------------------------------------------
        # Completar y usar un metodo para todo largo de mensaje

        dict_msg = {"mensaje": mensaje, "continuar": continuar}
        mensaje_codificado = pickle.dumps(dict_msg)

        largo_msg = len(mensaje_codificado).to_bytes(4, byteorder='big')
        self.socket_cliente.sendall(largo_msg + mensaje_codificado)

        # Completar hasta aquí
        # --------------------

    def recibir_accion(self):
        '''Recibe mensaje desde el cliente y lo decodifica.'''
        # -----------------------------------------------------
        # Completar y usar un metodo para todo largo de mensaje

        largo_msg = int.from_bytes(self.socket_cliente.recv(4),
                                   byteorder='big')
        bytes_recibidos = bytearray()
        while len(bytes_recibidos) < largo_msg:
            largo_leer = min(200, largo_msg - len(bytes_recibidos))
            bytes_recibidos.extend(self.socket_cliente.recv(largo_leer))

        mensaje_serializado = bytes_recibidos.decode("UTF-8")
        accion = json.loads(mensaje_serializado)

        # Completar hasta aquí
        # --------------------
        return accion

    def manejar_accion(self, accion):
        '''Maneja la acción recibida del cliente.'''
        print(f'Acción recibida: {accion}')
        # --------------------
        # Completar desde aquí

        tipo = accion[
            "comando"]  # Obtener el tipo de acción que envió el cliente.

        # Completar hasta aquí
        # --------------------
        if tipo == '\\juego_nuevo':
            self.juego = Juego()
            self.juego.crear_tablero()
            self.enviar_estado('', True)
        elif tipo == '\\salir':
            self.enviar_estado('¡Adios!', False)
            self.juego = None
            self.socket_cliente.close()
            print('Cliente desconectado.\n')
            self.socket_cliente = None
        elif tipo == '\\jugada':
            if self.juego is None:
                self.enviar_estado('Ningún juego ha iniciado.', True)
            else:
                # --------------------
                # Completar desde aquí

                # Obtener la jugada que envió el cliente.
                jugada = int(accion["columna"])

                # Completar hasta aquí
                # --------------------
                if not self.juego.es_jugada_valida(jugada):
                    self.enviar_estado('Jugada inválida.', True)
                else:
                    gano = self.juego.turno_jugador(jugada)
                    if gano:
                        self.enviar_estado('¡Ganaste! Se acabó el juego.',
                                           True)
                        self.juego = None
                    else:
                        perdio = self.juego.turno_cpu()
                        if perdio or self.juego.empate():
                            self.enviar_estado(
                                'No ganaste :( Se acabó el juego.', True)
                            self.juego = None
                        else:
                            self.enviar_estado('', True)
示例#3
0
class Servidor:
    def __init__(self):
        '''Inicializador de servidor.

        Crea socket de servidor, lo vincula a un puerto.'''
        # -----------------------------------------
        # Completar y agregar argumentos desde aquí

        # PAUTA - Host y Port
        self.host = "localhost"
        self.port = 14502
        self.socket_servidor = socket.socket(socket.AF_INET,
                                             socket.SOCK_STREAM)

        # Aqui deberas preparar el socket para que escuche una conexion
        # PAUTA - Se inicia el socket
        self.socket_servidor.bind((self.host, self.port))
        # PAUTA - El socket escucha conexiones
        self.socket_servidor.listen()

        # Completar y agregar argumentos hasta aquí
        # -----------------------------------------
        print("Servidor iniciado.")
        self.juego = None  # Juego comienza nulo.
        self.socket_cliente = None  # Aún no hay cliente.

    def esperar_conexion(self):
        '''Espera a la conectarse con un cliente y obtiene su socket.'''
        print("Esperando cliente...")
        # --------------------
        # Completar desde aquí
        # Debes actualizar el valor de self.socket_cliente al conectar
        # PAUTA - Se conecta y guarda el socket
        self.socket_cliente, _ = self.socket_servidor.accept()

        # Completar hasta aquí
        # --------------------
        print("¡Servidor conectado a cliente!")
        self.interactuar_con_cliente()

    def interactuar_con_cliente(self):
        '''Comienza ciclo de interacción con cliente.

        Recibe un acción y responde apropiadamente.'''
        self.enviar_estado('', True)
        while self.socket_cliente:
            accion = self.recibir_accion()
            self.manejar_accion(accion)

    def enviar_estado(self, mensaje, continuar):
        '''Envia estado del juego en el servidor.'''
        if continuar:
            if self.juego is not None:
                mensaje = f'{self.juego.tablero_string()}\n{mensaje}\n'
            acciones = ("¿Qué deseas hacer?\n"
                        "Para jugar nuevo juego: \\juego_nuevo\n"
                        "Para jugar en una columna: \\jugada columna\n"
                        "Para salir: \\salir\n")
            mensaje = mensaje + acciones
        # -----------------------------------------------------
        # Completar y usar un metodo para todo largo de mensaje

        dict_ = {"mensaje": mensaje, "continuar": continuar}

        # PAUTA - Se usa pickle para serializar (BONUS)
        mensaje_codificado = pickle.dumps(dict_)
        bytes_length = len(mensaje_codificado).to_bytes(4, byteorder="little")

        # PAUTA - Se envía el mensaje
        self.socket_cliente.send(bytes_length)
        self.socket_cliente.send(mensaje_codificado)

        # Completar hasta aquí
        # --------------------

    def recibir_accion(self):
        '''Recibe mensaje desde el cliente y lo decodifica.'''
        # -----------------------------------------------------
        # Completar y usar un metodo para todo largo de mensaje

        # PAUTA - Se recibe el mensaje
        bytes_length = self.socket_cliente.recv(4)
        msg_length = int.from_bytes(bytes_length, byteorder="little")
        bytes_recibidos = self.socket_cliente.recv(msg_length)
        # En caso de que se cierre la conexión con el cliente
        if not bytes_length:
            print("Ha ocurrido un error de conexión con el cliente")
            return None

        # PAUTA - Se usa JSON para deserializar (BONUS)
        dict_recibido = json.loads(bytes_recibidos.decode(encoding="utf-8"))

        accion = dict_recibido["accion"]  # Respuesta resultante

        # Completar hasta aquí
        # --------------------
        return accion

    def manejar_accion(self, accion):
        '''Maneja la acción recibida del cliente.'''
        print(f'Acción recibida: {accion}')
        # --------------------
        # Completar desde aquí

        # Obtener el tipo de acción que envió el cliente.
        # PAUTA - Se obtiene el comando del cliente (1/2)
        if accion is None:
            self.socket_cliente.close()
            print('Cliente desconectado.\n')
            self.socket_cliente = None
            return
        if re.match(r'\\juego_nuevo$', accion):
            tipo = '\\juego_nuevo'
        elif re.match(r'\\salir$', accion):
            tipo = '\\salir'
        elif re.match(r'\\jugada [0-9]+$', accion):
            tipo = '\\jugada'
        else:
            raise ValueError("QUE PAAAASOO")
        # Completar hasta aquí
        # --------------------
        if tipo == '\\juego_nuevo':
            self.juego = Juego()
            self.juego.crear_tablero()
            self.enviar_estado('', True)
        elif tipo == '\\salir':
            self.enviar_estado('¡Adios!', False)
            self.juego = None
            self.socket_cliente.close()
            print('Cliente desconectado.\n')
            self.socket_cliente = None
        elif tipo == '\\jugada':
            if self.juego is None:
                self.enviar_estado('Ningún juego ha iniciado.', True)
            else:
                # --------------------
                # Completar desde aquí

                # Obtener la jugada que envió el cliente.
                # PAUTA - Se obtiene el comando del cliente (2/2)
                jugada = int(re.search(r'[0-9]+', accion).group())

                # Completar hasta aquí
                # --------------------
                if not self.juego.es_jugada_valida(jugada):
                    self.enviar_estado('Jugada inválida.', True)
                else:
                    gano = self.juego.turno_jugador(jugada)
                    if gano:
                        self.enviar_estado('¡Ganaste! Se acabó el juego.',
                                           True)
                        self.juego = None
                    else:
                        perdio = self.juego.turno_cpu()
                        if perdio or self.juego.empate():
                            self.enviar_estado(
                                'No ganaste :( Se acabó el juego.', True)
                            self.juego = None
                        else:
                            self.enviar_estado('', True)