I followed the youtube video and used python to make a multiplayer online game of rock-paper-scissors. When I execute the script, the console displays "Couldn't get game", which is generated when the client script does not receive the game sent by the server. My server script and client script can't seem to exchange information.
This program is not finished yet. The client script refers to the network script to receive and send messages, and the server script refers to the game script to execute the game.
This is the server script
import socket
from _thread import *
import pickle
from game import Game
server = socket.gethostbyname(socket.gethostname())
port = 5555
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.bind((server, port))
except socket.error as e:
str(e)
s.listen()
print("Waiting for connection, Server Started")
connected = set()
games = {}
idCount = 0
def threaded_client(conn, p, gameId):
global idCount
conn.send(str.encode(str(p)))
reply = ""
while True:
try:
data = conn.recv(4096).decode()
if gameId in games:
game = games[gameId]
if not data:
break
else:
if data == "reset":
game.resetWent()
elif data != "get":
game.play(p, data)
reply = game
conn.sendall(pickle.dumps(reply))
else:
break
except:
break
try:
del games[gameId]
print("Closing game", gameId)
except:
pass
idCount -= 1
conn.close()
while True:
conn, addr = s.accept()
print("Connected to:", addr)
idCount = 1
p = 0
gameId = (idCount - 1)//2
if idCount % 2:
games[gameId] = Game(gameId)
print("Creating a new game...")
else:
games[gameId].ready = True
p = 1
start_new_thread(threaded_client, (conn, p, gameId))
This is the client script
import pygame
from network import Network
import pickle
import datetime
pygame.font.init()
width = 500
height = 500
win = pygame.display.set_mode((width, height))
pygame.display.set_caption('Client')
class Button:
def __init__(self, text, x, y, color):
self.text = text
self.x = x
self.y = y
self.color = color
self.width = 150
self.height = 100
def draw(self, win):
pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height))
font = pygame.font.SysFont("comicsans", 40)
text = font.render(self.text, 1, (255,255,255))
win.blit(text, (self.x round(self.width/2) - round(text.get_width()/2), self.y round(self.height/2) - round(text.get_height()/2)))
def click(self, pos):
x1 = pos[0]
y1 = pos[1]
if self.x <= x1 <= self.x self.width and self.y <= y1 <= self.y self.height:
return True
else:
return False
def redrawWindow(win, game, p):
win.fill((128, 128, 128))
if not(game.connected()):
font = pygame.font.SysFont('comicsans', 80)
text = font.render("Wait for Player...", 1, (255,0,0), True)
win.blit(text, (width/2 - text.get_width()/2, height/2 - text.get_height()/2))
else:
font = pygame.font.SysFont('comicsans', 60)
text = font.render("Your Move", 1, (0, 255, 255), True)
win.blit(text, (80, 200))
text = font.render("Opponent", 1, (0, 255, 255), True)
win.blit(text, (380, 200))
move1 = game.get_player_move(0)
move2 = game.get_player_move(1)
if game.bothWent():
text1 = font.render(move1, 1, (0,0,0))
text2 = font.render(move2, 1, (0,0,0))
else:
if game.p1Went and p == 0:
text1 = font.render(move1, 1, (0,0,0))
elif game.p1Went:
text1 = font.render("Locked In", 1, (0,0,0))
else:
text1 = font.render("Waiting...", 1, (0,0,0))
if game.p2Went and p == 1:
text2 = font.render(move2, 1, (0,0,0))
elif game.p1Went:
text2 = font.render("Locked In", 1, (0,0,0))
else:
text2 = font.render("Waiting...", 1, (0,0,0))
if p == 1:
win.blit(text2, (100, 350))
win.blit(text1, (400, 350))
else:
win.blit(text1, (100, 350))
win.blit(text2, (400, 350))
for btn in btns:
btn.draw(win)
pygame.display.update()
btns = [Button("Rock", 50, 500, (0,0,0)), Button("Scissors", 250, 500, (255,0,0)), Button("Paper", 450, 500, (0,255,0))]
def main():
run = True
clock = pygame.time.Clock()
n = Network()
player = int(n.getP())
x = datetime.datetime.now()
print(x.strftime("%X"), "You are player", player)
while run:
clock.tick(60)
try:
game = n.send("get")
except:
run = False
x = datetime.datetime.now()
print(x.strftime("%X"), "Couldn't get game")
break
if game.bothWent():
redrawWindow(win, game, player)
pygame.time.delay(500)
try:
game = n.send("reset")
except:
run = False
x = datetime.datetime.now()
print(x.strftime("%X"), "Couldn't get game")
break
font = pygame.font.SysFont("comicsans", 90)
if (game.winner() == 1 and player == 1) or (game.winner() == 0 and player == 0):
text = font.render("You Won!", 1, (255,0,0))
elif game.winner == -1:
text = font.render("Tie Game!", 1, (255, 0, 0))
else:
text = font.render("You Lost...!", 1, (255, 0, 0))
win.blit(text, (width/2 - text.get_width()/2, height/2 - text.get_height()/2))
pygame.display.update()
pygame.time.delay(2000)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
for btn in btns:
if btn.click(pos) and game.connected():
if player == 0:
if not game.p1Went:
n.send(btn.text)
else:
if not game.p2Went:
n.send(btn.text)
redrawWindow(win, game, player)
main()
This is the network script.
import socket
import pickle
class Network:
def __init__(self):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server = "240.2.2.1"
self.port = 5555
self.addr = (self.server, self.port)
self.p = self.connect()
def getP(self):
return self.p
def connect(self):
try:
self.client.connect(self.addr)
return self.client.recv(2048).decode()
except:
pass
def send(self, data):
try:
self.client.send(str.encode(data))
return pickle.loads(self.client.recv(2048))
except socket.error as e:
str(e)
CodePudding user response:
In the question you put three scripts network.py client.py server.py.
server.py called "Game" class from "game.py" and you did not put this script, firstly add this file to your project and run server.py, then run client1 and client2 (client2 it's a copy from client1), your code running well in my device after add "game.py" and "client2.py"
You can use the code in the following link, it's from the same source
https://github.com/BigYeser/multiplayer
I also advise you to change the ip address to 127.0.0.1
in server.py
server = "127.0.0.1"
port = 5555
in network.py
self.server = "127.0.0.1"
self.port = 5555