0

Ich möchte ein Quiz-Spiel mit Multi-Player programmieren. Der Server-Teil wählt die Frage und sendet sie an den Client. Der Client antwortet und sendet diese Antwort an den Server. Der Server überprüft dann, ob es richtig ist oder nicht. Ich möchte das in einer Schleife machen. Aber das Problem ist, gibt es ein Problem des Timings, manchmal mein Client nicht die Frage vor der Antwort erhalten. Ein anderes Problem ist, der Server erhält die Antwort nicht, wenn der Client es sendet und ich weiß wirklich nicht warum.Quiz Spiel mit Multiplayer, Server erhält keine Informationen von Kunden

Es ist mein erstes Mal, Netzwerk-Programmierung und es ist schwierig für mich, Threading und all dies zu verstehen. Vielen Dank für Ihre Hilfe =)

PS: Dies betraf eine andere Frage, die ich für diesen Code möchte mit einer einfachen grafischen Oberfläche zu arbeiten ... Aber das ist der nächste Schritt;)

Hier ist meine Client-Code:

import socket 
import threading 
import time 

tLock = threading.Lock() 
shutdown = False 

def receving(name, sock): 
    while not shutdown: 
      try: 
       tLock.acquire() 
       while True: 
         data,addr = sock.recvfrom(1024) 
         print(str(data)) 
      except: 
        pass 
      finally: 
        tLock.release() 

#host = '192.168.26.86' 
host = '127.0.0.1' 
port = 0 #pick any free port currently on the computer 
server = (host, 5000) 

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
s.bind((host,port)) 
s.setblocking(0) 

#receiving thread 
rT = threading.Thread(target=receving, args=("RecvThread", s)) 
rT.start() 

alias = raw_input("Name: ") 

#PLAYER ENTERS DATA 
message = raw_input(alias + "First msg ->") 

while message != 'q': 
     tLock.acquire() 
     message = raw_input(alias + "What is your answer ? ->") 
     tLock.release() 


     if message != '': 
      s.sendto(alias + ": " + message, server) 

     time.sleep(0.2) 

shutdown = True 
rT.join() 
s.close() 

Hier ist mein Server-Code:

import numpy as np 
from numpy.random import shuffle 
from random import randint 
import socket 
import time 

#LIST OF QUESTIONS AND ANSWERS 
question2 = ["What is the capital of France?","In which continent is Argentina?","Where is Big Ben?","What is the most densely populated country?","What language do they speak in Brazil?"] 
answer2 = [["Paris","London","Berlin","Madrid"], 
     ["South America","Africa","Europe","Asia"], 
     ["London","New York","Mexico","Jakarta"], 
     ["China","India","USA","Indonesia"], 
     ["Portuguese","Spanish","French","English"]] 
question_done=[0]*(len(question2)) 


#SCORE, stored as a list score[0]--> score of the player 1 
score=[0] 


#SHOW THE POSSIBLE ANSWERS 
def displayA(question,answer,i): 
    a = answer[i] 
    order = np.arange(4) 
    shuffle(order) #create list from 1 to 4 in different order --> to print the answers in random order 
    a_display = [[a[order[0]],a[order[1]]],[a[order[2]],a[order[3]]]] 
    print(a_display) 


#CHOOSE RANDOMLY A QUESTION IN THE LIST 
def chooseQuestion(question,answer): 
    k = randint(0,len(question)-1) 
    if (question_done[k]!=0): 
     while(question_done[k]!=0): 
      k = randint(0,len(question)-1) 
     question_done[k]=1 
    else : 
     question_done[k]=1 
    print(question[k]) 
    #displayA(question,answer,k) 
    return k 


#CHECK IF GOOD ANSWER OR NOT 
def checkAnswer(answer,agiven,qnb): 
    print("CHECK") 
    test = False 
    if(answer[qnb][0] in agiven): 
     test = True 
     score[0]=score[0]+1 
    print("ANSWER") 
    return test 



#END OF GAME, DISPLAY OF SCORES 
def final_score(score): 
    print("The scores are {}".format(score)) 

    maxi = max(score) 
    if(score.count(maxi)==1): 
     print("The winner is Player {}".format(score.index(max(score))+1)) 
    else : 
     winners = [] 
     for i in range(len(score)): 
      if(score[i]==maxi): 
       winners.append(i+1) 
     print("The winners are players {}".format(winners)) 


""" 

#Number of choosen questions, random order : GIVE THE QUESTION TO THE PLAYER 
nb = 3 

for k in range(nb): 
    nbq = chooseQuestion(question2,answer2) 
    agiven = raw_input("What is your answer? ") 
    result = checkAnswer(answer2,agiven,nbq) 
    print("Your answer is {}".format(result)) 



#Say who the winner is 
final_score(score) 



""" 
#START THE NETWORK CODE 
#host = '192.168.26.86' 
host = '127.0.0.1' 

port = 5000 

#list for all the players 
players = [] 

#creation of socket object UDP and bind 
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
s.bind((host, port)) 
#socket non blocking --> will always try to grab datas from the stream 
#not block it 
s.setblocking(0) 


quitting = False 
print "Server Started." 

#NUMBER OF QUESTIONS 
nb = 3 


while (not quitting and nb>0): 
    try: 
      data, addr = s.recvfrom(1024) 
      print("FIRST RECV {}".format(data)) 
      if "Quit" in str(data): 
       quitting = True 
      if addr not in players: 
       players.append(addr) 
       print("liste players {}".format(players)) 
       s.sendto("the game is starting ",players[len(players)-1]) 

      print time.ctime(time.time()) + ":" + str(data) 

      #GAME 

      #for k in range(nb): 
      print("question nb {}".format(nb)) 
      nbq = chooseQuestion(question2,answer2) 


      for i in range(len(players)): 
       print("ENTER FOR") 
       #s.sendto(question2[nbq], players[i]) 
       try: 
        s.sendto(question2[nbq], players[i]) 
        print("BEFORE GET ANSWER") 
        agiven, addr = s.recvfrom(1024) 
        print("GOT ANSWER") 

        print("agiven is : {}".format(agiven)) 
        checkAnswer(answer2,agiven,nbq) 

        if "Quit" in str(agiven): 
         quitting = True 
        if addr not in players: 
         s.sendto("You cannot enter the game now ",addr) 
        else: 
         players[i] = addr 
       except: 
        pass 

      nb=nb-1 

    except: 
      pass 



for i in range(len(players)): 
    try: 
     s.sendto("The game is finished, write q to quit",players[i]) 

    except: 
     pass 

final_score(score) 
s.close() 

Antwort

0

Ihr Code enthält die richtige Logik für die Fragen und Antworten, aber die dat Ein Transfer zwischen Client und Server war fragil und funktionierte nur, wenn das Timing perfekt war.

Ich habe Ihren Code geändert, um zu helfen, das Timing zu kontrollieren und zu verhindern, dass Dinge aus der Reihe kommen. Ich benutzte den Systemaufruf select(), um Timeouts zu verarbeiten, und im Client habe ich den Lese-Thread geändert, um die Hauptschleife zu benachrichtigen, wenn Fragen vom Server kommen.

Dieser Code ist ein langer Weg von der Perfektion, aber es funktioniert und es sollte Ihnen helfen, etwas Finales zu bauen, das so funktioniert, wie Sie es bevorzugen.

Hinweis: Ich habe den Code "Sie können dem Spiel jetzt nicht beitreten" entfernt, um mir beim Debuggen des ursprünglichen Codes zu helfen. Sie könnten das jetzt wahrscheinlich wieder einfügen. Ich hoffe, das ist hilfreich.

Client-Code:

import socket 
import threading 
import time 

tEv = threading.Event() 
tShutdown = threading.Event() 

def receving(name, sock): 
    shutdown = False 
    while not shutdown: 
     try: 
      data,addr = sock.recvfrom(1024) 
      print(str(data)) 
      if '?' in data: 
       tEv.set() 
      if data == "The game is finished": # message from server to stop 
       tShutdown.set() 
       shutdown = True 
     except: 
      pass 
     finally: 
      pass 

#host = '192.168.26.86' 
host = '127.0.0.1' 
port = 0 #pick any free port currently on the computer 
server = (host, 5000) 

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
s.bind((host,port)) 
s.setblocking(0) 

# Start listener 
rT = threading.Thread(target=receving, args=("RecvThread", s)) 
rT.start() 

# Join the game 
alias = raw_input("Name: ") 
s.sendto(alias, server) 

running = True 
while running: 
    if tEv.wait(1.0): 
     tEv.clear() 
     message = raw_input(alias + ", what is your answer ? -> ") 
     if message != '': 
      s.sendto(alias + ": " + message, server) 
    if tShutdown.is_set(): 
     running = False 

rT.join() 
s.close() 

Code Server:

import numpy as np 
from numpy.random import shuffle 
from random import randint 
import socket 
import time 
import select 

#LIST OF QUESTIONS AND ANSWERS 
question2 = ["What is the capital of France?","In which continent is Argentina?","Where is Big Ben?","What is the most densely populated country?","What language do they speak in Brazil?"] 
answer2 = [["Paris","London","Berlin","Madrid"], 
     ["South America","Africa","Europe","Asia"], 
     ["London","New York","Mexico","Jakarta"], 
     ["China","India","USA","Indonesia"], 
     ["Portuguese","Spanish","French","English"]] 
question_done=[0]*(len(question2)) 


#SCORE, stored as a list score[0]--> score of the player 1 
score=[0] 


#SHOW THE POSSIBLE ANSWERS 
def displayA(question,answer,i): 
    a = answer[i] 
    order = np.arange(4) 
    shuffle(order) #create list from 1 to 4 in different order --> to print the answers in random order 
    a_display = [[a[order[0]],a[order[1]]],[a[order[2]],a[order[3]]]] 
    print(a_display) 


#CHOOSE RANDOMLY A QUESTION IN THE LIST 
def chooseQuestion(question,answer): 
    k = randint(0,len(question)-1) 
    if (question_done[k]!=0): 
     while(question_done[k]!=0): 
      k = randint(0,len(question)-1) 
     question_done[k]=1 
    else : 
     question_done[k]=1 
    print(question[k]) 
    #displayA(question,answer,k) 
    return k 


#CHECK IF GOOD ANSWER OR NOT 
def checkAnswer(answer,agiven,qnb): 
    #print("CHECK") 
    test = False 
    if(answer[qnb][0] in agiven): 
     test = True 
     score[0]=score[0]+1 
    #print("ANSWER") 
    return test 



#END OF GAME, DISPLAY OF SCORES 
def final_score(score): 
    print("The scores are {}".format(score)) 

    maxi = max(score) 
    if(score.count(maxi)==1): 
     print("The winner is Player {}".format(score.index(max(score))+1)) 
    else : 
     winners = [] 
     for i in range(len(score)): 
      if(score[i]==maxi): 
       winners.append(i+1) 
     print("The winners are players {}".format(winners)) 


""" 
#Number of choosen questions, random order : GIVE THE QUESTION TO THE PLAYER 
nb = 3 

for k in range(nb): 
    nbq = chooseQuestion(question2,answer2) 
    agiven = raw_input("What is your answer? ") 
    result = checkAnswer(answer2,agiven,nbq) 
    print("Your answer is {}".format(result)) 

#Say who the winner is 
final_score(score) 
""" 
#START THE NETWORK CODE 
#host = '192.168.26.86' 
host = '127.0.0.1' 

port = 5000 

#list for all the players 
players = [] 

#creation of socket object UDP and bind 
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
s.bind((host, port)) 
#socket non blocking --> will always try to grab datas from the stream 
#not block it 
s.setblocking(0) 

print "Server Started." 

#INITIAL SETUP PERIOD 
secs = 20 
max_players = 5 

# WAIT FOR PLAYERS TO JOIN 
while ((secs > 0) and (len(players) < max_players)): 
    ready = select.select([s], [], [], 1) 
    if ready[0]: 
     data, addr = s.recvfrom(1024) 
     print("FIRST RECV {}".format(data)) 
     if addr not in players: 
      players.append(addr) 
      print("liste players {}".format(players)) 
      s.sendto("Wait for game to start... ",players[len(players)-1]) 
     print time.ctime(time.time()) + ":" + str(data) 
    secs = secs - 1 

#START GAME 
print("Game starting") 
for i in range(len(players)): 
    try: 
     s.sendto("Game starting", players[i]) 
    except: 
     pass 

#ASK QUESTIONS 
nb = 3 
for k in range(nb): 
    print("question nb {}".format(k)) 
    nbq = chooseQuestion(question2,answer2) 
    #print("ENTER FOR") 
    for i in range(len(players)): 
     try: 
      s.sendto(str(question2[nbq]), players[i]) 
      #print("BEFORE GET ANSWER") 
      agiven = "" 
      ready = select.select([s], [], [], 10) 
      if ready[0]: 
       agiven, addr = s.recvfrom(1024) 
       #print("GOT ANSWER") 
      print("agiven is : {}".format(agiven)) 
      checkAnswer(answer2,agiven,nbq) 
     except: 
      pass 

for i in range(len(players)): 
    try: 
     s.sendto("The game is finished", players[i]) 
    except: 
     pass 

final_score(score) 
s.close() 
+0

vielen Dank! Genau das habe ich gebraucht. Ich wusste nichts über die Auswahl und es ist wirklich interessant für mich =) –

Verwandte Themen