Python multiplayer quiz only sends one guess to the server

Viewed 33

I have been working on a quiz game with python using tkinter, sockets, SQLite3 and threading. I have been trying to make that when you press a button, the answer gets sent to the server and the server calculates who is right or if both right, or nobody right (not added yet).

When I try and submit a choice on my two clients, the server only detects one choice and the second one is ignored. How do I fix this?

Here is the client code:

def connect():
    MenuFrame.destroy()
    quizGame()
    p1name["text"] = "P1: " + your_name
    connect_to_server(your_name)

def connect_to_server(name):
    global client, HOST_PORT, HOST_ADDR, your_name
    try:
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        print("trying to connect")
        print("client connect " + name)

        client.connect((HOST_ADDR, HOST_PORT))

        client.send(name.encode()) # Send name to server after connecting
        # disable widgets
        #enable_disable_buttons("disable")

        # start a thread to keep receiving message from server
        # do not block the main thread :)
        threading._start_new_thread(receive_message_from_server, (client, "m"))
    except Exception as e:
        messagebox.showerror(title="ERROR!!!", message="Cannot connect to host: " + HOST_ADDR + " on port: " + str(HOST_PORT) + " Server may be Unavailable. Try again later")
        quizGameFrame.destroy()
        Menu()

def count_down(my_timer, nothing):
    global game_round
    if game_round <= TOTAL_NO_OF_ROUNDS:
        game_round = game_round + 1

    timer["text"] = "Game round " + str(game_round) + " starts in"

    while my_timer > 0:
        my_timer = my_timer - 1
        #print("game timer is: " + str(my_timer))
        #lbl_timer["text"] = my_timer
        timer["text"] = my_timer
        sleep(1)


def receive_message_from_server(sck, m):
    global your_name, opponent_name, game_round, setupRoundInProgress
    global your_choice, opponent_choice, your_score, opponent_score
    global question, c1, c2, c3, c4

    while True:

        from_server = sck.recv(4096).decode()
        messageToServer = ""
        setupRoundInProgress = False
        if not from_server: break

        if from_server.startswith("welcome"):
            if from_server == "welcome1":
                globalmessage["text"] = "Server says: Welcome " + your_name + "! Waiting for player 2"
            elif from_server == "welcome2":
                globalmessage["text"] = "Server says: Welcome " + your_name + "! Game will start soon"
            #lbl_line_server.pack()

        elif from_server.startswith("opponent_name$"):
            opponent_name = from_server.replace("opponent_name$", "")
            p2name["text"] = "Opponent: " + opponent_name

            # we know two users are connected so game is ready to start
            threading._start_new_thread(count_down, (5, ""))
            setupRoundInProgress = True
            client.send(b"roundSetup$")
            print("round setup")
            sleep(5)
        elif from_server.startswith("question$"):
            question = from_server.replace("question$", "")
            questionLabel["text"] = question
            client.send(b"getChoices")
        elif from_server.startswith("choice1$"):
                c1 = from_server.replace("choice1$", "")
                gameChoice1["text"] = c1
        elif from_server.startswith("choice2$"):
                c2 = from_server.replace("choice2$", "")
                gameChoice2["text"] = c2
        elif from_server.startswith("choice3$"):
                c3 = from_server.replace("choice3$", "")
                gameChoice3["text"] = c3
        elif from_server.startswith("choice4$"):
                c4 = from_server.replace("choice4$", "")
                gameChoice4["text"] = c4
        elif from_server.startswith("startRound$"):
            threading._start_new_thread(count_down, (game_timer, ""))
            enable_disable_buttons("enable")


def quizGame():
    global quizGameFrame, p1name, p2name, globalmessage, timer, questionLabel, gameChoice1, gameChoice2, gameChoice3, gameChoice4

    quizGameFrame = Frame(root)
    quizGameFrame.pack(side=TOP)

    lbl_yourName = Label(root)
    ft = tkFont.Font(family='Times', size=20)
    lbl_yourName = Label(quizGameFrame, text="You: " + your_name, font=ft)
    lbl_yourName.grid(row=0)
    p1name = lbl_yourName

    lbl_opponent_name = Label(root)
    lbl_opponent_name = Label(quizGameFrame, text="P2: ", font=ft)
    lbl_opponent_name.grid(row=1)
    p2name = lbl_opponent_name

    lbl_gamemessage = Label(root)
    ft = tkFont.Font(family='Times', size=18)
    lbl_gamemessage = Label(quizGameFrame, text="test", font=ft)
    lbl_gamemessage.grid(row=5, column=0)
    globalmessage = lbl_gamemessage

    lbl_question = Label(root)
    lbl_question = Label(quizGameFrame, text="Question: ", font=ft)
    lbl_question.grid(row=2)
    questionLabel = lbl_question

    btn_a = Button(root)
    btn_a["bg"] = "#efefef"
    btn_a = Button(quizGameFrame, text="1948 ", font=ft, width=15, state=DISABLED, command=lambda : choose("a"))
    btn_a.grid(row=3, column=0, pady=50, columnspan=1)
    gameChoice1 = btn_a

    btn_b = Button(root)
    btn_b["bg"] = "#efefef"
    btn_b = Button(quizGameFrame, text="2022", font=ft, width=15, state=DISABLED, command=lambda : choose("b"))
    btn_b.grid(row=3, column=1, pady=50, columnspan=1)
    gameChoice2 = btn_b

    btn_c = Button(root)
    btn_c["bg"] = "#efefef"
    btn_c = Button(quizGameFrame, text="1947", font=ft, width=15, state=DISABLED, command=lambda : choose("c"))
    btn_c.grid(row=4, column=0, columnspan=1)
    gameChoice3 = btn_c

    btn_d = Button(root)
    btn_d["bg"] = "#efefef"
    btn_d = Button(quizGameFrame, text="1976", font=ft, width=15, state=DISABLED, command=lambda : choose("d"))
    btn_d.grid(row=4, column=1, columnspan=1)
    gameChoice4 = btn_d

    lbl_score = Label(root)
    ft = tkFont.Font(family='Times', size=28)
    lbl_score = Label(quizGameFrame, text="Score: ", font=ft)
    lbl_score.grid(row=0, column=1)

    lbl_time = Label(root)
    ft = tkFont.Font(family='Times', size=28)
    lbl_time = Label(quizGameFrame, text="", font=ft)
    lbl_time.grid(row=1, column=1)
    timer = lbl_time

and the server code:

def questionCount():
    questionDatabase()
    cursor.execute("SELECT COUNT (*) FROM `questions`")
    rowcount = cursor.fetchone()[0]
    cursor.close()
    conn.close()
    return rowcount

def getQuestion(id):
    global gameQuestion, c1, c2, c3, c4, ans
    if id <= questionCount():
        questionDatabase()
        cursor.execute("SELECT * FROM `questions` WHERE `q_id` = ?", (id,))
        for row in cursor:
            gameQuestion = row[1]
            c1 = row[2]
            c2 = row[3]
            c3 = row[4]
            c4 = row[5]
            ans = row[6]



def generateSetIds(): #generate sets of questions
    for i in range(10):
        gQ_id = random.randint(0, questionCount())
        questionSetId.append(gQ_id)


def accept_clients(the_server, y):
    while True:
        if len(clients) < 2:
            client, addr = the_server.accept()
            clients.append(client)

            # use a thread so as not to clog the gui thread
            threading._start_new_thread(send_receive_client_message, (client, addr))


def send_clients(msg):
    i=0
    for i in range(len(clients)):
        clients[i].send(msg)


def send_receive_client_message(client_connection, client_ip_addr):
    global server, client_name, clients, player_data, player0, player1, roundIndex

    client_msg = " "

    # send welcome message to client
    client_name = client_connection.recv(4096)
    if len(clients) < 2:
        client_connection.send("welcome1".encode())
    else:
        client_connection.send("welcome2".encode())

    clients_names.append(client_name)
    update_client_names_display(clients_names)  # update client names display

    if len(clients) > 1:
        sleep(1)

        # send opponent name
        clients[0].send("opponent_name$".encode() + clients_names[1])
        clients[1].send("opponent_name$".encode() + clients_names[0])
        generateSetIds()
        # go to sleep

    while True:
        roundIndex = 0
        data = client_connection.recv(4096)
        if not data: break
        getQuestion(questionSetId[roundIndex])
        if data.startswith(b"roundSetup"):
            c_Question = gameQuestion.encode()
            c_choice1 = c1.encode()
            c_choice2 = c2.encode()
            c_choice3 = c3.encode()
            c_choice4 = c4.encode()
            c_ans = ans.encode()
            send_clients("question$".encode() + c_Question)
        elif data.startswith(b"getChoices"):
            send_clients("choice1$".encode() + c_choice1)
            send_clients("choice2$".encode() + c_choice2)
            send_clients("choice3$".encode() + c_choice3)
            send_clients("choice4$".encode() + c_choice4)
            send_clients("startRound$".encode())


        # get the player choice from received data
        player_choice = data[11:len(data)]

        msg = {
            "choice": player_choice,
            "socket": client_connection
        }


Thank you!

0 Answers
Related