I really need help on a project I'm currently doing. Basically I have a game of Tetris, and I want to implement a multiplayer function to it which will send the scores to each other's screen within a LAN. I've been trying so hard and it is still not working, I'm using sockets to do so, by that, I created a server, and 2 clients run simultaneous as the "multiplayer" but the scores just wouldn't sync, if anyone could help me? I don't know if I'm declaring some variables wrongly, or there are some error with the logic / code. It would be so good if someone could help!
Here is my code:
This is for the server.
import socket
import _thread
from _thread import *
import sys
server = "192.168.1.93"
port = 3456
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
s.bind((server, port))
except socket.error as e:
str(e)
score1 = str(0)
score2 = str(0)
s.listen(2)
print("Waiting for a connection, server started!")
def threaded_client(conn,player):
conn.send(str.encode(score2))
conn.send(str.encode(score1))
reply = ""
while True:
try:
data = conn.recv(2048).decode()
score1 = data
if not data:
print("disconnected")
break
else:
if player == 0:
reply = score1
else:
reply = score2
print("Received: ", data)
print ("Sending: ", reply)
conn.sendall(str.encode(reply))
except:
break
print("Lost connection")
conn.close()
currentPlayer = 0
while True:
conn, addr = s.accept()
print("connected to:", addr)
start_new_thread(threaded_client, (conn, currentPlayer))
currentPlayer += 1
And Here is the Network module which I'll call it in n.
import socket
class Network:
def __init__(self):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server = "192.168.1.93"
self.port = 3456
self.addr = (self.server, self.port)
self.score = self.connect()
def getscore(self):
return self.score
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 self.client.recv(2048).decode()
except socket.error as e:
print(e)
Here is the code I use for the game that runs multiplayer (client number 1):
def multigame():
n = Network()
score2 = str(n.getscore())
score1 = str(n.getscore())
score = 0
global grid
locked_positions = {} #dicitionary set above
grid = create_grid(locked_positions)
change_piece = False
run = True # works with the while loop
current_piece = get_shape()
next_piece = get_shape()
clock = pygame.time.Clock()
fall_time = 0
fall_speed = 0.27
while run:
grid = create_grid(locked_positions)
fall_time += clock.get_rawtime()
clock.tick()
if fall_time/1000 >= fall_speed:
fall_time = 0
current_piece.y += 1
if not (valid_space(current_piece, grid)) and current_piece.y > 0:
current_piece.y -= 1
change_piece = True
for event in pygame.event.get(): #Control quitting the game
if event.type == pygame.QUIT:
run = False
pygame.display.quit()
quit()
if event.type == pygame.KEYDOWN: # Control the movements when a key is being pressed
if event.key == pygame.K_LEFT: # when the left key is being pressed
current_piece.x -= 1 #from getshape function, which returns a random shape chosen form the list of shapes, then move it's x value which is the x coords by 1, because it's negative it moves it to the left
if not valid_space(current_piece, grid): #to prevent the block from moving outside the grid, we check using valid space function, when it is not reaching the requirement( eg no space) then it will counter the action
current_piece.x += 1
elif event.key == pygame.K_RIGHT: # when the right key is being pressed
current_piece.x += 1 # same idea but adding value to x coords makes it goes right by 1
if not valid_space(current_piece, grid):
current_piece.x -= 1
elif event.key == pygame.K_UP: # when the up key is being pressed
current_piece.rotation += 1 #as set early above, rotation is default 0, which corresponds the index of the list of shapes and now we add it by 1 it rotates it towards the next index within the list of a shape
if not valid_space(current_piece, grid):
current_piece.rotation -= 1
if event.key == pygame.K_DOWN: #when the down key is being pressed
current_piece.y += 1 # adds the y coords by 1, kinda did it in the inverse way which we start from 0 at the top and higher y value at the bottom
if not valid_space(current_piece, grid):
current_piece.y -= 1
#Terminates the program in game with ESC
if event.key == pygame.K_ESCAPE:
pygame.quit()
if event.key == pygame.K_SPACE: #drop instantly
while valid_space(current_piece, grid):
current_piece.y +=1
current_piece.y -=1
shape_pos = convert_shape_format(current_piece)
# add piece to the grid for drawing
for i in range(len(shape_pos)):
x, y = shape_pos[i]
if y > -1:
grid[y][x] = current_piece.color
# Function when the piece hits the bottom level it can reach and therefore locking it into the "gird" frame
if change_piece:
for pos in shape_pos:
p = (pos[0], pos[1])
locked_positions[p] = current_piece.color
current_piece = next_piece
next_piece = get_shape()
change_piece = False
# call four times to check for multiple clear rows
score += clear_rows(grid, locked_positions) * 10
scorev = str(score)
draw_windowmultiplayer(win, grid, score, score2)
draw_next_shape(next_piece, win)
pygame.display.update()
if check_lost(locked_positions):
run = False
draw_text_middle("You Lost", 40, (255, 255, 255), win)
pygame.display.update()
pygame.time.delay(2000)
Then here is the multiplayer I use to run Client number 2:
def multigame():
n = Network()
score2 = str(n.getscore())
score1 = str(n.getscore())
score = 0
global grid
locked_positions = {} #dicitionary set above
grid = create_grid(locked_positions)
change_piece = False
run = True # works with the while loop
current_piece = get_shape()
next_piece = get_shape()
clock = pygame.time.Clock()
fall_time = 0
fall_speed = 0.27
while run:
grid = create_grid(locked_positions)
fall_time += clock.get_rawtime()
clock.tick()
if fall_time/1000 >= fall_speed:
fall_time = 0
current_piece.y += 1
if not (valid_space(current_piece, grid)) and current_piece.y > 0:
current_piece.y -= 1
change_piece = True
for event in pygame.event.get(): #Control quitting the game
if event.type == pygame.QUIT:
run = False
pygame.display.quit()
quit()
if event.type == pygame.KEYDOWN: # Control the movements when a key is being pressed
if event.key == pygame.K_LEFT: # when the left key is being pressed
current_piece.x -= 1 #from getshape function, which returns a random shape chosen form the list of shapes, then move it's x value which is the x coords by 1, because it's negative it moves it to the left
if not valid_space(current_piece, grid): #to prevent the block from moving outside the grid, we check using valid space function, when it is not reaching the requirement( eg no space) then it will counter the action
current_piece.x += 1
elif event.key == pygame.K_RIGHT: # when the right key is being pressed
current_piece.x += 1 # same idea but adding value to x coords makes it goes right by 1
if not valid_space(current_piece, grid):
current_piece.x -= 1
elif event.key == pygame.K_UP: # when the up key is being pressed
current_piece.rotation += 1 #as set early above, rotation is default 0, which corresponds the index of the list of shapes and now we add it by 1 it rotates it towards the next index within the list of a shape
if not valid_space(current_piece, grid):
current_piece.rotation -= 1
if event.key == pygame.K_DOWN: #when the down key is being pressed
current_piece.y += 1 # adds the y coords by 1, kinda did it in the inverse way which we start from 0 at the top and higher y value at the bottom
if not valid_space(current_piece, grid):
current_piece.y -= 1
#Terminates the program in game with ESC
if event.key == pygame.K_ESCAPE:
pygame.quit()
if event.key == pygame.K_SPACE: #drop instantly
while valid_space(current_piece, grid):
current_piece.y +=1
current_piece.y -=1
shape_pos = convert_shape_format(current_piece)
# add piece to the grid for drawing
for i in range(len(shape_pos)):
x, y = shape_pos[i]
if y > -1:
grid[y][x] = current_piece.color
# Function when the piece hits the bottom level it can reach and therefore locking it into the "gird" frame
if change_piece:
for pos in shape_pos:
p = (pos[0], pos[1])
locked_positions[p] = current_piece.color
current_piece = next_piece
next_piece = get_shape()
change_piece = False
# call four times to check for multiple clear rows
score += clear_rows(grid, locked_positions) * 10
scorev = str(score2)
draw_windowmultiplayer(win, grid, score, score2)
draw_next_shape(next_piece, win)
pygame.display.update()
if check_lost(locked_positions):
run = False
draw_text_middle("You Lost", 40, (255, 255, 255), win)
pygame.display.update()
pygame.time.delay(2000)