【Python五子棋】基于Socket的多人五子棋-通信部分

【Python五子棋】基于Socket的多人五子棋-通信部分

这篇博客中介绍了基于Python语言编写的多人五子棋(两人或三人)游戏主体框架中的多人联机通信部分,考虑到多人五子棋通常情况下是在本地网络下进行,因此我选择了使用连接更加稳定的TCP/IP协议的socket作为五子棋对局过程中多机通讯的主要手段。
由于我们小组项目中选择的五子棋对局结构是CS结构,下面的博客主要介绍了Server端从开始到建立连接并开始游戏再到最终的判断胜负并返回过程中的代码逻辑,此处展示的代码只是一个包含有基本逻辑的中间工程代码,并非最终完成的代码部分,如果想要完整的多人联机五子棋和AI算法代码的话可以去我的CSDN共享资源中寻找完整的压缩包。
话不多说,下面直接提供通信部分框架的主要代码逻辑,采用Socket依次轮询并发送指定信息实现棋子位置的选择。
可以提供的代码改进部分提示:
①为了防止Server和Client之间Socket传递信息出现粘连,可以使用time.sleep()函数设置一个1秒以内的短延时;
②为了保证不在当前回合的client能接收到当前回合的client下子的位置信息,可以加上附加的判断部分实现这一功能(这里提供的中间代码没有包含这个功能)
③需要注意加上棋局是否完结的判断函数,这里的中间代码预留了这个借口但并没有详细定义这个函数

下面提供的是Server端示范逻辑的中间代码:

import socket

#判断输赢函数,此处未给出详细定义
def judgeResult(i, j, value):
    pass

def whowins( x, y, i, win, winclient): #函数的形参为s1,s2,s3为对三个client端的socket连接,win为胜利指示变量,i为胜利者的client编号
    mark = judgeResult(x, y, i)
    if(mark==1):
        print("当前棋局已经分出胜负,获胜者是{}!".format(i))
        win=1
        winclient=i
    elif(mark==0):
        win=0
        print("游戏继续!")




#初始化并创建监听socket部分
ip1=input("请输入主机ip地址")
ip_port = (ip1,1234)         #设置主机IP地址和端口
back_log = 5                 #设置客户端最大监听数量
buf_size = 1024              #设置默认buf文本区大小
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)   # 初始化TCP连接的socket
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)  # 对socket的配置重用ip和端口号
s.bind(ip_port)              #绑定端口号和socket
s.listen(back_log)           #设置socket端监听对象链接
print("成功创建socket,等待client端链接中...")

#设置client连接顺序部分
i=0 #设置i为表示client连接顺序的标记变量
j=0 #设置j为标志断开连接的指示变量
while True:
    c,address = s.accept()  #阻塞式等待client端的链接
    if(i==0):
        i=1
        msg0=("{}".format(i))
        c.send(msg0.encode('utf-8'))   #向client端传递客户机编号
        addr1=address
        c1=c                #第一次监听到连接时,设置连接为client1
        print("接收到来自{}地址的client端连接,连接编号为{}".format(address,i))
    elif(i>0):
        if((address!=addr1) & (i==1)):
            i=2
            msg0=("{}".format(i))
            c.send(msg0.encode('utf-8'))   #向client端传递客户机编号
            addr2=address
            c2=c            #监听到不同的的连接时,设置连接为client2
            print("接收到来自{}地址的client端连接,连接编号为{}".format(address,i))
        elif((address!=addr1) & (address!=addr2) & (i==2)):
            i=3
            msg0=("{}".format(i))
            c.send(msg0.encode('utf-8'))   #向client端传递客户机编号
            addr3=address
            c3=c            #监听到第三个不同ip地址的连接时,设置连接为client3
            print("接收到来自{}地址的client端连接,连接编号为{}".format(address,i))
        elif(i==3):
            print("已达到最大连接client数量,额外连接被挂起!")
            msg0=("end")
            c.send(msg0.encode('utf-8'))   #向client端传递终止连接命令

#连接的玩家数不为最大值时,确定加入的电脑数量
    if(i!=3):
        start=input("当前连接的玩家数为{}人,是否添加电脑?Y/N".format(i))
        if(start=='Y'):
            numc=int (input("可添加的电脑玩家数量上限为{}".format(3-i)))
            if(i+numc<=3):
                i=i+numc
                gamestart=1
            else:
                print("您输入的电脑数量有误!")
        elif(i==2):
            start2=input("当前连接数为2,确认开始2人的PVP游戏吗?-Y/N")
            if(start2=='Y'):
                gamestart=1
    elif(i==3):
        print("当前连接的玩家数量已满3人,游戏开始!")
        gamestart=1
#判断当client数量已经满足要求时,开始轮询过程

    if(i==2 & gamestart == 1): 
        print("2人游戏开始!")
        win=0
        winclient=0     #初始化棋盘胜负状态变量win和winclient  
        while 1:
            i=1
            msg='1'
            c1.send(msg.encode('utf-8'))
            msgw=("{}".format(win))
            c1.send(msgw.encode('utf-8'))
            msgw=("{}".format(winclient))
            c1.send(msgw.encode('utf-8'))
            msgx1 = c1.recv(buf_size)
            if(msgx1=='end'):
                print("Client1已关闭")
            else:
                print('服务器接受到来自client1端行坐标为{}'.format(msgx1.decode('utf-8')))
                msgy1 = c1.recv(buf_size)
                print('服务器接受到来自client1端列坐标为{}'.format(msgy1.decode('utf-8')))
                x1=msgx1
                y1=msgy1
                whowins( x1, y1, i, win, winclient)

            i=2
            msg='2'
            c2.send(msg.encode('utf-8')) 
            msgw=("{}".format(win))
            c2.send(msgw.encode('utf-8'))
            msgw=("{}".format(winclient))
            c2.send(msgw.encode('utf-8'))
            msgx2 = c2.recv(buf_size)
            if(msgx2=='end'):
                print("Client2已关闭")
            else:
                print('服务器接受到来自client2端行坐标为{}'.format(msgx2.decode('utf-8')))
                msgy2 = c2.recv(buf_size)
                print('服务器接受到来自client2端列坐标为{}'.format(msgy2.decode('utf-8')))
                x2=msgx2
                y2=msgy2
                whowins( x2, y2, i, win, winclient)

            #循环轮次判定结束   
            if (win == 0): 
                continue
            else:            
                print('通信已经结束,连接断开') 
                j=1
                break
        
    elif(i==3 & gamestart == 1): 
        print("3人游戏开始!")
        win=0
        winclient=0     #初始化棋盘胜负状态变量win和winclient  
        while 1:
            i=1
            msg='1'
            c1.send(msg.encode('utf-8'))
            msgw=("{}".format(win))
            c1.send(msgw.encode('utf-8'))
            msgw=("{}".format(winclient))
            c1.send(msgw.encode('utf-8'))
            msgx1 = c1.recv(buf_size)
            if(msgx1=='end'):
                print("Client1已关闭")
            else:
                print('服务器接受到来自client1端行坐标为{}'.format(msgx1.decode('utf-8')))
                msgy1 = c1.recv(buf_size)
                print('服务器接受到来自client1端列坐标为{}'.format(msgy1.decode('utf-8')))
                x1=msgx1
                y1=msgy1
                whowins( x1, y1, i, win, winclient)

            i=2
            msg='2'
            c2.send(msg.encode('utf-8')) 
            msgw=("{}".format(win))
            c2.send(msgw.encode('utf-8'))
            msgw=("{}".format(winclient))
            c2.send(msgw.encode('utf-8'))
            msgx2 = c2.recv(buf_size)
            if(msgx2=='end'):
                print("Client2已关闭")
            else:
                print('服务器接受到来自client2端行坐标为{}'.format(msgx2.decode('utf-8')))
                msgy2 = c2.recv(buf_size)
                print('服务器接受到来自client2端列坐标为{}'.format(msgy2.decode('utf-8')))
                x2=msgx2
                y2=msgy2
                whowins( x2, y2, i, win, winclient)

            msg='3'
            c3.send(msg.encode('utf-8')) 
            msgw=("{}".format(win))
            c3.send(msgw.encode('utf-8'))
            msgw=("{}".format(winclient))
            c3.send(msgw.encode('utf-8'))
            msgx3 = c3.recv(buf_size)
            if(msgx3=='end'):
                print("Client3已关闭")
            else:
                print('服务器接受到来自client3端行坐标为{}'.format(msgx3.decode('utf-8')))
                msgy3 = c1.recv(buf_size)
                print('服务器接受到来自client3端列坐标为{}'.format(msgy3.decode('utf-8')))
                x3=msgx3
                y3=msgy3
                whowins( x3, y3, i, win, winclient)
            #循环轮次判定结束   
            if (win == 0): 
                continue
            else:            
                print('通信已经结束,连接断开') 
                j=1
                break
    if(j==1):
        break
s.close() #关闭监听主socket,服务端程序结束
print("连接已断开!")


这里是Client端的逻辑示范中间代码:

import socket
 
buf_size=1024
p = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#创建socket并设置server端连接的IP地址和端口
ip1=(input("请输入server端的IP地址"))
p.connect((ip1,1234))
msg = p.recv(buf_size) #接收server端反馈的信息编号
if(msg!='end'):
    print("已连接到ip为{}的server端,本机编号为{}".format(ip1,msg.decode('utf-8')))  # 连接成功时将server端ip地址反馈到client端
    num=msg                #定义client端编号为num  
elif(msg=='end'):
    print("server端连接数量已达上限!当前连接断开!")

#成功连接时开启主循环
if(msg!='end'):
    while 1:
        msg = p.recv(buf_size)           # 接收server端发送的当前client编号
        if(num!=msg):
            continue
        msg0 = p.recv(buf_size)          #接受广播信息-获胜情况和游戏进行状态
        msg1 = p.recv(buf_size)
        if msg0 =='1':
            print("Player{} wins!".format(msg1))
            msg=('end')
            p.send(msg.encode('utf-8'))  #向server传递关机信息
            break
        elif msg == '0':
            msgx=input("请输入传递给server端的落子坐标行信息")
            p.send(msgx.encode('utf-8')) 
            msgy=input("请输入传递给server端的落子坐标列信息")
            p.send(msgy.encode('utf-8'))   
            print("信息已经发送至server端!") 
p.close()
print("连接已断开!")

完整的代码可以在我共享的资源文件中找到。

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 当然可以!这里有一些基本的步骤供你参考: 1. 确定你的游戏的目标和规则。例如,你可能想要做一个五子棋游戏,在这种情况下,你需要确定游戏规则,例如谁先手,怎么获胜等。 2. 定义你的游戏类。这将是你的游戏的主要部分,包含游戏的状态(例如棋盘,棋子的位置,当前玩家等)和方法(例如轮流落子,判断输赢等)。 3. 创建服务器和客户端程序。服务器将负责维护游戏的状态并处理玩家的动作,客户端将负责显示游戏界面并向服务器发送动作请求。 4. 在服务器上运行你的游戏类,并在客户端上连接到服务器。这样就可以进行多人游戏了! 希望这些信息对你有帮助! ### 回答2: 用Python做一个多人游戏可以有很多种方式,下面我会介绍一种简单的实现方式。 首先,我们需要使用Python的网络编程库,比如socket或者Twisted等,来创建一个服务器来管理游戏的逻辑和处理多个玩家之间的通信。 服务器端的主要任务是接受来自客户端的连接,并为每个连接的客户端创建一个独立的线程来处理该客户端的请求。服务器可以通过监听特定的端口并接受客户端的连接来实现。 在游戏的逻辑部分,服务器可以维护一个游戏状态,比如地图信息、玩家位置等。每个客户端连接成功后,可以将游戏状态发送给客户端,并接受客户端发送的游戏操作指令。服务器需要根据客户端的指令更新游戏状态,并将更新后的状态发送给所有连接的客户端。 客户端的任务是与服务器建立连接,并接受服务器发送的游戏状态。客户端可以将服务器发送的游戏状态显示在界面上,并接受玩家的操作指令发送给服务器。 在多人游戏中,玩家之间的通信可以通过服务器来实现。当一个玩家发送指令时,服务器可以将该指令发送给所有其他玩家,以实现玩家之间的互动。 此外,为了确保游戏的流畅运行,服务器还需要处理多个客户端同时发送请求的情况,可以通过多线程或者异步编程的方式来实现。 总结起来,用Python实现一个多人游戏主要包括创建一个服务器来处理多个客户端的连接和通信,以及在服务器端实现游戏的逻辑和处理玩家指令的流程。客户端则主要负责与服务器的通信和显示游戏状态。 ### 回答3: 用Python创建一个多人游戏可以通过使用网络编程和多线程来实现。以下是一种可能的实现方式: 首先,我们需要使用Pythonsocket模块来创建一个服务器和多个客户端。服务器将负责管理游戏的逻辑和状态,而客户端将与服务器进行通信并显示游戏界面。 在服务器端,我们可以创建一个用于接受和处理客户端请求的线程。服务器将接受来自客户端的连接,并将其分配给一个独立的线程进行处理。这样,多个客户端可以同时连接服务器并参与游戏。 在客户端,我们可以创建一个GUI界面来显示游戏画面和与服务器进行通信。当客户端启动时,它将尝试连接服务器,并接收服务器发送的游戏数据。客户端将显示游戏画面,并向服务器发送玩家的操作信息。 在游戏逻辑方面,服务器将接收来自客户端的操作信息,并根据玩家的操作更新游戏状态。服务器将再次向所有客户端发送更新后的游戏数据,然后客户端将更新其游戏界面以反映最新状态。这样,所有玩家将同时看到游戏界面的更新。 为了提供多人游戏的交互性,可以在游戏中加入聊天功能,以便玩家可以在游戏中交流和协作。服务器将负责接收和转发玩家的聊天信息。 总的来说,使用Python创建一个多人游戏需要服务器和多个客户端之间的网络通信,以及对游戏逻辑和状态的管理。通过这种方式,玩家可以同时参与游戏,并与其他玩家进行交互。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值