1

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)
  • 1
    Your clients' code shows a lot of irrelevant game stuff, but no sign of a call to `send` _which will send the scores to each other_. Perhaps that's the problem. Otherwise, you'd have to post runnable code, preferably without the `pygame` distraction. – Armali Mar 17 '21 at 10:50

0 Answers0