Python 多人游戏角落和十字架

Python Multiplayer noughts and crosses

所以我不久前在学校 Python 做了一个单人球员的传中。

score=[[' ',' ',' '],[' ',' ',' '],[' ',' ',' ']]
global attempts
attempts = 0
from random import randint
from time import sleep

def grid(): #draws playing grid
    hideturtle()
    speed(0)
    pensize(0)
    penup()
    setpos(-200, -67)
    pendown()
    fd(400)
    penup()
    setpos(-200, 66)
    pendown()
    fd(400)
    penup()
    seth(90)
    setpos(-67, -200)
    pendown()
    fd(400)
    penup()
    setpos(66, -200)
    pendown()
    fd(400)

def drawShape(s, x, y): #draws shape in grid box x and y = coord, s = shape type
    hideturtle()
    speed(100)
    pensize(6)
    penup()
    if s == 'X': #draws 'X'
        pencolor("orange")
        setpos(-266+(133*x), -266+(133*y))
        pendown()
        seth(135)
        fd(50)
        rt(180)
        fd(100)
        rt(180)
        fd(50)
        rt(90)
        fd(50)
        rt(180)
        fd(100) 
    elif s == 'O': #draws 'O'
        pencolor("green")
        setpos(-266+(133*x), -266+(133*y)-40)
        seth(0)
        pendown()
        circle(40)



def ai(): #EXPERIMENTAL AI
    x=0
    y=0
    d='O'
    e='O'
    f='O'
    for i in range(3): #checks positions
        if i == 0:
            d=' '
        elif i == 1:
            d='O'
            e=' '
        elif i == 2:
            d='O'
            e='O'
            f=' '
        for c in range(3):
            if score[c][0] == d and score[c][1] == e and score[c][2] == f:
                x = c+1
                y = i+1
                print('v',c)
            elif score[c][0] == d and score[c][1] == e and score[c][2] == f:
                x = i=1
                y = c+1
                print('h',c)
        if score[0][0] == d and score[1][1] == e and score[2][2] == f:
            print('lr',i)
            x = i+1
            y = i+1
        elif score[0][2] == d and score[1][1] == e and score[2][0] == f:
            print('rl',i)
            x = i+1
            y = 4-i
    d='X'
    e='X'
    f='X'
    if x == 0 and y == 0: #checks oposition positions
        for i in range(3):
            if i == 0:
                d=' '
            elif i == 1:
                d='X'
                e=' '
            elif i == 2:
                d='X'
                e='X'
                f=' '
            for c in range(3): 
                if score[c][0] == d and score[c][1] == e and score[c][2] == f:
                    x = c+1
                    y = i+1
                    print('op v')
                elif score[c][0] == d and score[c][1] == e and score[c][2] == f:
                    x = i=1
                    y = c+1
                    print('op v')
            if score[0][0] == d and score[1][1] == e and score[2][2] == f:
                x = i+1
                y = i+1
                print('op bt')
            elif score[0][2] == d and score[1][1] == e and score[2][0] == f:
                x = i+1
                y = 4-i
                print('op tb')

    if x == 0 and y == 0: #if no playable positions uses random
        x = randint(1,3)
        y = randint(1,3)
    return x, y

def valid(u,x,y): #checks player move is valid
    global attempts
    if x > 3 or y > 3:
        print ('Coordinate must be between 1 & 3')
    elif x == '' or y == '':
        print("Enter something!")
    elif score[y-1][x-1] == ' ':
        score[y-1][x-1] = u
        drawShape(u, x, y)
        attempts +=1
        return True
    elif score[y-1][x-1] == u:
        print("You've already gone here! ")
        return False
    elif score[y-1][x-1] != u:
        print("The other player is here! ")
        return False


def userAgent(u): #makes AI or user prompts and sets array
    global attempts
    global a
    global b
    if u == 0:
        a, b = ai()
        score[b-1][a-1] = 'O'
        print("The computer is taking its turn...")
        print(a,b)
        sleep(1)
        drawShape('O', a, b)
        attempts +=1
    else:
        x = input("Player "+u+": enter x coordinate (1-3) ")
        y = input("Player "+u+": enter y coordinate (1-3) ")
        try:
            x = int(x)
            y = int(y)
        except ValueError:
            print("That's not a valid number!")
            userAgent(u)
        while True:
            if valid(u,x,y) == True:
                break
            x = input("Player "+u+": enter x coordinate (1-3) ")
            y = input("Player "+u+": enter y coordinate (1-3) ")
            try:
                x = int(x)
                y = int(y)
            except ValueError:
                print("That's not a valid number!")


def checkWin(n): #checks for a player win (3 in row) or stalemate
    for i in range(3):
        if score[i][0] == n and score[i][1] == n and score[i][2] == n:
            print("Player "+n+" won!")
            return True
        elif score[0][i] == n and score[1][i] == n and score[2][i] == n:
            print("Player "+n+" won!")
            return True
    if score[0][0] == n and score[1][1] == n and score[2][2] == n:
        print("Player "+n+" won!")
        return True
    elif score[0][2] == n and score[1][1] == n and score[2][0] == n:
        print("Player "+n+" won!")
        return True
    elif attempts == 9:
        print("Stalemate!")
        return True
    else:
        return False

def printGrid():
    print(score[2])
    print(score[1])
    print(score[0])

from turtle import *
grid()
p = input("Are you playing by yourself? (SINGLE PLAYER EXPERIMENTAL) (y/n) ")

while True: #runs game until player win
    if p == 'y':
        userAgent('X')
        printGrid()
        if checkWin('X') == True:
            break
        userAgent(0)
        printGrid()
        if checkWin('O') == True:
            break

    elif p == 'n':
        userAgent('X')

        if checkWin('X') == True:
            break
        userAgent('O')

        if checkWin('O') == True:
            break

    else:
        print("You need to type y or n - try again!")
        p = input("Are you playing by yourself? (SINGLE PLAYER EXPERIMENTAL) (y/n) ")

input('Press ENTER to exit')

请忽略 AI 功能,它现在是永久实验性的(不起作用),但这不是问题所在。

我正在学校的开放晚会上帮忙,我想如果 2 个人可以在不同的计算机上对战会很酷。所以我会在我的家用 PC 上通过端口转发托管服务器,执行所有逻辑,客户端只需接收输入,将它们发送到服务器并绘制两个玩家的动作。我知道 HTTP POST/GET,但我如何让服务器告诉客户端另一个玩家移动了?我研究了 Twisted,它看起来不错,但我真的不明白 类(我只编程了一段时间)。

这将在学校计算机上进行,因此我无法访问客户端的端口转发。理想情况下,我还有一个 IP 白名单,这样只有我想要的计算机才能访问服务器....

太棒了,有人可以帮我吗?我只需要了解服务器需要哪些代码以及客户端如何与其交互。谢谢:)

让两个客户端通过服务器进行交互的最简单方法是让两个客户端轮询服务器以获取更新。 (您可以执行服务器端事件,但这对于您要查找的内容来说太复杂了)。

但是,如果它们在同一个网络中,我建议在每个直接通信的设备上打开一个套接字服务器和客户端。

我的做法是这样的:

  1. 套接字服务器在两台机器上都打开
  2. 谁开始游戏谁就打开一个套接字客户端并直接向服务器发送一个移动,然后重新打开一个套接字服务器
  3. 计算机的下一步动作会打开客户端并将动作发回服务器。

这会删除 运行 服务器的所有不必要代码。

请参阅 python 套接字手册。 server/client 的底部都有很好的例子。

https://docs.python.org/2/library/socket.html

您可能想看看 ZeroMQ。 http://zeromq.org/

具体来说,您需要 PyZMQ。 http://zeromq.github.io/pyzmq/api/zmq.html

设置简单,两台电脑直接连接即可。您将能够在两者之间来回发送消息。

一定要阅读文档,但您可能需要 Request/Reply 模式。

您可以从the twisted chatserver example

开始
"""The most basic chat protocol possible.

run me with twistd -y chatserver.py, and then connect with multiple
telnet clients to port 1025
"""

from twisted.protocols import basic



class MyChat(basic.LineReceiver):
    def connectionMade(self):
        print "Got new client!"
        self.factory.clients.append(self)

    def connectionLost(self, reason):
        print "Lost a client!"
        self.factory.clients.remove(self)

    def lineReceived(self, line):
        print "received", repr(line)
        for c in self.factory.clients:
            c.message(line)

    def message(self, message):
        self.transport.write(message + '\n')


from twisted.internet import protocol
from twisted.application import service, internet

factory = protocol.ServerFactory()
factory.protocol = MyChat
factory.clients = []

application = service.Application("chatserver")
internet.TCPServer(1025, factory).setServiceParent(application)

客户端可以使用Python的内置telnetlib来连接

稍后您可以根据需要升级到使用 twisted 进行客户端连接。