You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
5.2 KiB
160 lines
5.2 KiB
import socket
|
|
import threading
|
|
|
|
class Jugador:
|
|
def __init__(self):
|
|
self._nick = "" #nombre del jugador
|
|
self._addr = "" #dirección del cliente
|
|
self._jugada= "" #piedra/papel/tijera
|
|
self._puntos= 0
|
|
|
|
@property
|
|
def nick(self):
|
|
return self._nick
|
|
|
|
@property
|
|
def addr(self):
|
|
return self._addr
|
|
|
|
@property
|
|
def jugada(self):
|
|
return self._jugada
|
|
|
|
@property
|
|
def puntos(self):
|
|
return self._puntos
|
|
|
|
@property
|
|
def libre(self):
|
|
if self._nick == "":
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
@property
|
|
def sinJugar(self):
|
|
if self._jugada == "":
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
@nick.setter
|
|
def nick(self, nombre):
|
|
self._nick = nombre
|
|
|
|
@addr.setter
|
|
def addr(self, nombre):
|
|
self._addr = nombre
|
|
|
|
@jugada.setter
|
|
def jugada(self, nombre):
|
|
if nombre in ["piedra","papel","tijera",""]:
|
|
self._jugada = nombre
|
|
|
|
@puntos.setter
|
|
def puntos(self, nombre):
|
|
self._puntos = nombre
|
|
|
|
def puntuar(self):
|
|
print (self._puntos)
|
|
self._puntos += 1
|
|
|
|
def arbitrar(self,otroJugador):
|
|
#devuelve 0 si empate, -1 si gana otroJugador, 1 si gana el objeto actual
|
|
if ((self.jugada =="piedra" and otroJugador.jugada =="tijera") or
|
|
(self.jugada =="tijera" and otroJugador.jugada =="papel") or
|
|
(self.jugada =="papel" and otroJugador.jugada =="piedra")):
|
|
return 1
|
|
elif ((otroJugador.jugada =="piedra" and self.jugada =="tijera") or
|
|
(otroJugador.jugada =="tijera" and self.jugada =="papel") or
|
|
(otroJugador.jugada =="papel" and self.jugada =="piedra")):
|
|
return -1
|
|
else:
|
|
return 0
|
|
|
|
class ManejoCliente(threading.Thread):
|
|
def __init__(self,clientAddress,clientsocket):
|
|
threading.Thread.__init__(self)
|
|
self.csocket = clientsocket
|
|
self.cAddress = clientAddress
|
|
print ("Cliente conectado desde: ", self.cAddress)
|
|
|
|
def run(self):
|
|
global numJugadaActual
|
|
print ("Escuchando a peticiones de cliente: ", self.cAddress)
|
|
#mensaje de bienvenida con el protocolo
|
|
bienvenida ="#INSCRIBIR#nombre#\n#JUGADA#{piedra|papel|tijera}#\n#RESULTADOJUGADA#numeroJugada#\n#PUNTUACION#"
|
|
self.csocket.send(bytes(bienvenida,'UTF-8'))
|
|
|
|
while True:
|
|
data = self.csocket.recv(512).decode("utf_8")
|
|
print ("Enviado desde cliente:<",data,">")
|
|
subdatos = data.split("#")
|
|
respuesta="#OK#"
|
|
if subdatos[1] == "INSCRIBIR":
|
|
if jugador1.libre:
|
|
jugador1.nick = subdatos[2]
|
|
jugador1.addr = self.cAddress
|
|
elif jugador2.libre:
|
|
jugador2.nick = subdatos[2]
|
|
jugador2.addr = self.cAddress
|
|
else:
|
|
respuesta="#NOK#ya hay dos jugadores#"
|
|
elif subdatos[1] == "JUGADA":
|
|
#comprobra valor válido
|
|
if subdatos[2] not in ["piedra","papel","tijera"]:
|
|
respuesta="#NOK#valores válidos: piedra/papel/tijera#"
|
|
#comprobar autenticidad IP+puerto registrados
|
|
elif self.cAddress in [jugador1.addr, jugador2.addr]:
|
|
#estamos con el jugador 1
|
|
if self.cAddress == jugador1.addr:
|
|
jugador1.jugada = subdatos[2]
|
|
#estamos con el jugador 2
|
|
else:
|
|
jugador2.jugada = subdatos[2]
|
|
respuesta="#OK#" +str(numJugadaActual+1) +"#"
|
|
#comprobamos si podemos arbitrar jugada
|
|
with lock:
|
|
if (not jugador1.sinJugar and not jugador2.sinJugar):
|
|
#gana el 1
|
|
if jugador1.arbitrar(jugador2)>0:
|
|
jugador1.puntuar()
|
|
historicoJug[len(historicoJug):] =["#OK#GANADOR:" + jugador1.nick + "#"]
|
|
#gana el 2
|
|
elif jugador1.arbitrar(jugador2)<0:
|
|
jugador2.puntuar()
|
|
historicoJug[len(historicoJug):] =["#OK#GANADOR:" + jugador2.nick + "#"]
|
|
else:
|
|
historicoJug[len(historicoJug):] =["#OK#EMPATE#"]
|
|
jugador1.jugada =""
|
|
jugador2.jugada =""
|
|
numJugadaActual +=1
|
|
#la ip+puerto del jugador no estaba en la partida
|
|
else:
|
|
respuesta="#NOK#el jugador no está en la partida#"
|
|
elif subdatos[1] == "RESULTADOJUGADA":
|
|
if int(subdatos[2])>0 and int(subdatos[2]) <= numJugadaActual:
|
|
respuesta =historicoJug[int(subdatos[2])-1]
|
|
else:
|
|
respuesta = "#NOK#número de jugada no válido#"
|
|
elif subdatos[1] == "PUNTUACION":
|
|
respuesta="#OK#" + jugador1.nick + ":" + str(jugador1.puntos) + "#" + jugador2.nick + ":" + str(jugador2.puntos) + "#"
|
|
|
|
self.csocket.send(bytes(respuesta,'UTF-8'))
|
|
|
|
if __name__ == '__main__':
|
|
jugador1 = Jugador()
|
|
jugador2 = Jugador()
|
|
numJugadaActual = 0 #almacena el número actual de jugada
|
|
historicoJug = [] #mensajes de ganador para cada jugada
|
|
lock = threading.Lock()
|
|
HOST = ""
|
|
PORT = 2000
|
|
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
server.bind((HOST, PORT))
|
|
print("Servidor iniciado. Esperando clientes...")
|
|
while True:
|
|
server.listen(1)
|
|
clientsock, clientAddress = server.accept()
|
|
t = ManejoCliente(clientAddress, clientsock)
|
|
t.start() |