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!