0

im working on a project for my networking class which is a 2 clients plaing 4 in a row

I have almost everything figured out but i have one major issue, i need to get data from the server and in the same time do the mainloop beacuse i need the butons to appear, the mainloop line is blocking so when the code get to there he doesnt continue to the line that recv data from the server, how can i do the main loop and the recv data from the server at the same time?

any help would be great thanks. the server is:

import socket
import select
from tkinter import *
from functools import partial
from tkinter import messagebox

MAX_MSG_LENGTH = 1024
SERVER_PORT = 8820
SERVER_IP = "127.0.0.1"

count = 0

print("Setting up server...")
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((SERVER_IP, SERVER_PORT))
server_socket.listen()
print("Listening for clients...")
client_sockets = []
messages_to_send = []

def IsWinner(l):
    #checks rows
    for i in range(0, len(current_state)):
        for j in range(0, len(current_state[i]) - 3):
            if current_state[i][j] == l and current_state[i][j + 1] == l and current_state[i][j + 2] == l and current_state[i][j + 3] == l:
                return True
    #checks columns
    for i in range(0, len(current_state) - 3):
        for j in range(0, len(current_state[i])):
            if current_state[i][j] == l and current_state[i + 1][j] == l and current_state[i + 2][j] == l and current_state[i + 3][j] == l:
                return True
    # checks diagonals down
    for i in range(0, len(current_state) - 3):
        for j in range(0, len(current_state[i]) - 3):
            if current_state[i][j] == l and current_state[i + 1][j + 1] == l and current_state[i + 2][j + 2] == l and current_state[i + 3][j + 3] == l:
                return True
    # checks diagonals up
    for i in range(0, len(current_state) - 3):
        for j in range(3, len(current_state[i])):
            if current_state[i][j] == l and current_state[i + 1][j - 1] == l and current_state[i + 2][j - 2] == l and current_state[i + 3][j - 3] == l:
                return True
    return False

#checks if tie
def IsFull():
    for i in range(len(current_state)):
        for j in range(len(current_state[0])):
            if(current_state[i][j] == 'e'):
                return False
    return True


#checks if squre can be placed
def CanPlace(i, j):
    print(5 - i)
    print(columns[j])
    print(5 - i)
    return columns[j] == 5 - i

#draws yellow or red circle
##############################################################################no root in parameters
def DrawColor(i, j):
    global TURN
    print(CanPlace(i,j))
    if(CanPlace(i, j)):
        columns[j] += 1
        print(TURN)
        if(TURN % 2 == 0):
            #my_canvas = Canvas(root, width = 10, height = 10, bg = "red")
            #my_canvas.grid(row=i, column=j)
            current_state[i][j] = 'r'
            TURN += 1
            if(IsWinner('r')):
                #box = messagebox.showinfo("red wins!", "red wins!")
                return "r" + "#" + str(i) + "#" + str(j)
            if(IsFull()):
                return "t" + "#" + str(i) + "#" + str(j)
            return "cr" + "#" + str(i) + "#" + str(j)
        else:
            #my_canvas = Canvas(root, width = 10, height = 10, bg = "yellow")
            #my_canvas.grid(row=i, column=j)
            current_state[i][j] = 'y' + "#" + str(i) + "#" + str(j)
            TURN += 1
            if(IsWinner('y')):
                #box = messagebox.showinfo("yellow wins!", "yellow wins!")
                return "y" + "#" + str(i) + "#" + str(j)
            if(IsFull()):
                return "t" + "#" + str(i) + "#" + str(j)
            return "cy" + "#" + str(i) + "#" + str(j)
    return "f" + "#" + str(i) + "#" + str(j)

global current_state
current_state = [['e', 'e', 'e', 'e', 'e', 'e', 'e'],
                 ['e', 'e', 'e', 'e', 'e', 'e', 'e'],
                 ['e', 'e', 'e', 'e', 'e', 'e', 'e'],
                 ['e', 'e', 'e', 'e', 'e', 'e', 'e'],
                 ['e', 'e', 'e', 'e', 'e', 'e', 'e'],
                 ['e', 'e', 'e', 'e', 'e', 'e', 'e']]

global columns
columns = [0,0,0,0,0,0,0]

TURN = 0


while True:
    rlist, wlist, xlist = select.select([server_socket] + client_sockets, [], [])
    for current_socket in rlist:
        if current_socket is server_socket:
            connection, client_address = current_socket.accept()
            print("New client joined!", client_address)
            client_sockets.append(connection)
            connection.send(str(count % 2).encode())
            count += 1
        else:
            print("'waiting for data..'")
            data = current_socket.recv(MAX_MSG_LENGTH).decode()
            print(data)
            if data == "":
                print("Connection closed", )
                client_sockets.remove(current_socket)
                current_socket.close()
            else:
                print(data)
                position = data.split("#")
                print(position)
                ai = int(position[0])
                aj = int(position[1])
                print(ai)
                print(aj)
                messages_to_send.append(DrawColor(ai, aj))
    for message in messages_to_send:
        data = message
        print(data)
        for s in client_sockets:
            s.send(data.encode())
        #if current_socket in client_sockets:
        #   current_socket.send(data.encode())
        messages_to_send.remove(message)

and the client:

import socket
from tkinter import *
from functools import partial
import time
from tkinter import messagebox
import threading

SERVER_PORT = 8820
SERVER_IP = "127.0.0.1"
MAX_MSG_LENGTH = 1024

bl = True
turn = 0
count = 0


def StartGame(root):
    global turn
    global count
    turn = int(my_socket.recv(MAX_MSG_LENGTH).decode())
    print(turn)
    if (turn % 2 == 0):
        print("youre first!, and red")
        count = 0
    else:
        print("youre second, and yellow")
        count = 1
    root.mainloop()

# all data contains data + i + j
def Recv(root):
    global count
    if(count % 2 == 1):
        alldata = my_socket.recv(MAX_MSG_LENGTH).decode()
        alldatalst = alldata.split('#')
        data = alldatalst[0]
        i = alldatalst[1]
        j = alldatalst[2]
        DrawColor(root, data, i, j)


# all data contains data + i + j
def GetData(root):
    global bl
    while bl:
        print("waiting")
        alldata = my_socket.recv(MAX_MSG_LENGTH).decode()
        alldatalst = alldata.split("#")
        data = alldatalst[0]
        i = alldatalst[1]
        j = alldatalst[2]
        DrawColor(root, data, i, j)


# draws yellow or red circle
def GetAction(root, i, j):
    global count
    if(count % 2 == 1):
        print("not your turn, wait!")
    else:
        word = str(i) + "#" + str(j)
        print(word)
        my_socket.send(word.encode())
        alldata = my_socket.recv(MAX_MSG_LENGTH).decode()
        alldatalst = alldata.split("#")
        data = alldatalst[0]
        i = alldatalst[1]
        j = alldatalst[2]
        DrawColor(root, data, i, j)

def DrawColor(root, data, i, j):
    global count
    if (data == "cr"):
        my_canvas = Canvas(root, width=10, height=10, bg="red")
        my_canvas.grid(row=i, column=j)
    if (data == "cy"):
        my_canvas = Canvas(root, width=10, height=10, bg="yellow")
        my_canvas.grid(row=i, column=j)
    if (data == "r"):
        my_canvas = Canvas(root, width=10, height=10, bg="red")
        my_canvas.grid(row=i, column=j)
        box = messagebox.showinfo("red wins!", "red wins!")
        time.sleep(2)
        root.destroy()
    if (data == "y"):
        my_canvas = Canvas(root, width=10, height=10, bg="yellow")
        my_canvas.grid(row=i, column=j)
        box = messagebox.showinfo("yellow wins!", "yellow wins!")
        time.sleep(2)
        root.destroy()
    if (data == "t"):
        box = messagebox.showinfo("tie game", "tie!")
        time.sleep(2)
        root.destroy()
    count += 1


my_socket = socket.socket()
my_socket.connect((SERVER_IP, SERVER_PORT))

root = Tk()
root.geometry('800x800')
board = [[],
         [],
         [],
         [],
         [],
         []]
for i in range(6):
    for j in range(7):
        abc = partial(GetAction, root, i, j)
        board[i].append(Button(root, text=' ', bd='10', command=abc))
for i in range(6):
    for j in range(7):
        board[i][j].grid(row=i, column=j)
print("right here!")
startThread = threading.Thread(target=StartGame(root))
startThread.start()
print("2345")
while True:
    Recv(root)

0 Answers0