Я создаю онлайн-игру в шахматы с помощью модуля python -chess. где любой человек из любой точки мира может играть друг против друга, и я почти закончил, но я застрял в этой одной проблеме. Сама игра хороша и работает, если вы играете в автономном режиме, но проблема заключается в подключении нескольких человек к совместной игре. У меня есть два сценария. Скрипт server.py, который является сервером, и скрипт Chess.py, в котором есть игра и клиент. Я пытаюсь отправить информацию от другого клиента туда и обратно, но она не работает. Из моего устранения неполадок, я не думаю, что проблема в сценарии Chess.py, а вместо этого в сценарии server.py. Всякий раз, когда я подключаюсь к серверу с двумя клиентами, чтобы играть. С клиентом player2 он делает все как положено, но с клиентом player1 он просто застревает на экране «Ожидание противника ...». Не могли бы вы, ребята, помочь мне найти проблему?
Вот код для сценария server.py:
import socket
import threading
import time
import random
HEADER = 64
SERVER = socket.gethostbyname(socket.gethostname())
PORT = 5555
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MSG = "!DISCONNECT"
one = 0
two = 0
player1 = ''
player2 = ''
player1_nick = ''
player2_nick = ''
Connected = []
Game = []
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
def handle_client(conn, addr):
global player1, player2, one, Connected, player1_nick, player2_nick, Game
Connected = []
if addr not in Connected:
Connected.append(addr)
msg_len = conn.recv(HEADER).decode(FORMAT)
msg_len = int(msg_len)
user_nick = conn.recv(msg_len).decode(FORMAT)
if one == 0:
player1 = addr
player1_nick = user_nick
one = 1
else:
player2 = addr
player2_nick = user_nick
print(f"[NEW CONNECTION] '{user_nick}' from {addr} has connected to the server.")
while True:
try:
msg_len = conn.recv(HEADER).decode(FORMAT)
except:
print(f"[DISCONNECTION] '{user_nick}' from {addr} has disconnected")
for i in Connected:
if i == addr:
Connected.pop(i)
break
if msg_len:
msg_len = int(msg_len)
msg = conn.recv(msg_len).decode(FORMAT)
if msg == DISCONNECT_MSG:
print(f"[DISCONNECTION] '{user_nick}' from {addr} has disconnected")
for i in Connected:
if i == addr:
Connected.pop(i)
break
for i in Game:
if addr == Game[0]:
if i == Game[1]:
conn.send(f"{msg}".encode(FORMAT))
elif addr == Game[1]:
if i == Game[0]:
conn.send(f"{msg}".encode(FORMAT))
conn.close()
def start():
global player1, player2, player1_nick, player2_nick, Game, two
server.listen()
print(f"[LISTENING] The server is listening on port {PORT} and on server {SERVER}")
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
time.sleep(2)
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
worb = random.randint(1, 3)
if threading.activeCount() - 1 == 2:
Game.append(player1)
Game.append(player2)
print(f"\n[NEW GAME] A game has been started between '{player1_nick}' and '{player2_nick}'")
for i in Connected:
conn.send(f"!W:{player2_nick}".encode(FORMAT))
print("The server is starting...")
start()
А вот код для сценария Chess.py:
import chess
import chess.variant
import subprocess
import pickle
import socket
HEADER = 64
SERVER = socket.gethostbyname(socket.gethostname())
PORT = 5555
FORMAT = 'utf-8'
DISCONNECT_MSG = "!DISCONNECT"
ADDR = (SERVER, PORT)
one = 0
received_msg = 0
white_or_black = 0
user_nick = str(input("Please enter your nickname you want other people to see : "))
input("press ENTER to connect to server...\n")
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client.connect(ADDR)
except ConnectionRefusedError:
print("[ERROR] The server is currently down. Please try again later.")
quit()
def start():
global received_msg
print("Waiting for an opponent...")
try:
received_msg = client.recv(1024).decode(FORMAT)
except ConnectionResetError:
print("[ERROR] The server got shutdown. Sorry for the inconvenience. Please try to join again later.")
quit()
game()
def send(msg):
global received_msg
try:
message = msg.encode(FORMAT)
msg_len = len(message)
send_len = str(msg_len).encode(FORMAT)
send_len += b' ' * (HEADER - len(send_len))
client.send(send_len)
client.send(message)
except ConnectionResetError:
print("[ERROR] The server got shutdown. Sorry for the inconvenience. Please try to join again later.")
quit()
send(user_nick)
board = chess.Board()
mover = "WHITE"
draw_offer = 0
test = 999
move_count = 0
def game():
global mover, draw_offer, test, move_count, received_msg, white_or_black
subprocess.call('cls', shell=True)
print(board)
print("---------------")
print("a b c d e f g h\n")
print(f"{mover} TO MOVE\n")
white_or_black = received_msg.split(":")[0]
opponent_name = received_msg.split(":")[1]
if white_or_black == "!B":
print(f"\nYou are black and playing against '{opponent_name}'")
else:
print(f"\nYou are white and playing against '{opponent_name}'")
print("\nUppercase letters are White's pieces and lowercase letters are Black's pieces.")
while not board.is_game_over():
if white_or_black == "!B":
print("\nWaiting for your opponent's move...")
try:
board.push_san(str(client.recv(1024).decode(FORMAT)))
except:
print("[ERROR] The server got shutdown. Sorry for the inconvenience. Please try to join again later.")
quit()
if mover == "WHITE":
mover = "BLACK"
else:
mover = "WHITE"
subprocess.call('cls', shell=True)
print(board)
print("_______________")
print("a b c d e f g h\n")
if not board.is_game_over():
print(f"{mover} TO MOVE")
white_or_black = "!W"
continue
elif white_or_black == "!W":
if test != move_count:
if draw_offer == 1:
if mover == "WHITE":
print("\nBlack offered a draw.")
else:
print("\nWhite offered a draw.")
try:
move = input("\nPlease type the correct notation of the move you want to make. You can also type 'resign' to resign or 'draw' to offer/accept a draw : ")
board.push_san(str(move))
if move == "resign":
if mover == "WHITE":
print(f"\nWHITE RESIGNED! BLACK WINS!")
send(DISCONNECT_MSG)
quit()
else:
print(f"\nBLACK RESIGNED! WHITE WINS!")
send(DISCONNECT_MSG)
quit()
elif move == "draw":
if test == move_count:
print("\nDraw already offered! Make a move.")
continue
if draw_offer == 0:
draw_offer = 1
test = move_count
print("\nDraw offered. Make a move.")
continue
elif draw_offer == 1:
print("\nBOTH PLAYERS AGREED TO A DRAW")
send(DISCONNECT_MSG)
quit()
except ValueError:
if board.is_check():
print(f"\nYour king is in check!")
continue
print("\nThis is an illegal move or you didn't specify which piece went to that square! Please try again.")
continue
subprocess.call('cls', shell=True)
if test < move_count:
if draw_offer == 1:
draw_offer = 0
if mover == "WHITE":
mover = "BLACK"
else:
mover = "WHITE"
print(board)
print("_______________")
print("a b c d e f g h\n")
if not board.is_game_over():
print(f"{mover} TO MOVE")
move_count += 1
white_or_black = "!B"
send(move)
continue
if mover == "WHITE":
mover = "BLACK"
else:
mover = "WHITE"
if board.is_checkmate():
print(f"\nCHECKMATE! {mover} WINS.")
send(DISCONNECT_MSG)
quit()
elif board.is_stalemate():
print("\nIT'S A STALEMATE! IT'S A DRAW.")
send(DISCONNECT_MSG)
quit()
elif board.is_insufficient_material():
print("\nINSUFFICIENT MATERIAL! IT'S A DRAW.")
send(DISCONNECT_MSG)
quit()
elif board.can_claim_draw():
print("IT'S A DRAW.")
send(DISCONNECT_MSG)
quit()
if __name__ == "__main__":
start()
Я знаю, что мой код действительно грязный, но, надеюсь, вы можете это понять.