一.本案例基于UDP的socket编程方法来制作五子棋程序,网络五子棋采用C/S架构,分为服务器端和客户端,游戏时服务端首先启动,当客户端启动连接后,服务器端可以走棋,轮到自己棋才可以在棋盘上落子,同时下方标签会显示对方走起信息,服务器端用户可以通过“退出游戏”按钮可以结束游戏;

1.数据通信协议

网络五子棋游戏设计的难点在于对方进行通信,这里使用面向非连接的Socket编程,Socket编程用于C/S开发,在这类应用中,客户端和服务器端通常需要先建立连接,然后发送和接收数据,交互完成后需要断开连接,本章采用基于UDP的Socket编程实现,这里虽然两台计算机不分主次,但涉及时候假设一台作为服务器端,等待其他方加入,其他想加入必须输入服务器端主机的IP;
下面展示一些 数据通信协议代码

def receiveMessage():global swhile True:global addrdata,addr=s.recvfrom(1024)data=data.decode('utf-8')a=data.split("|")if not data:print("client has exited!")breakelif a[0]=='join':  #连接服务器请求print('client 连接服务器!')label1["text"]='client连接服务器成功,请你走棋!'elif a[0]=='exit':print('client 对方退出!')label1["text"]='client对方退出,游戏结束!'elif a[0]=='over':print('对方赢信息!')label1["text"]=data.split("|")[0]showinfo(title="提示",message=data.split("|")[1])elif a[0]=='move':print('received:',data,'from',addr)p=a[1].split(",")x=int(p[0])y=int(p[1])print(p[0],p[1])label1["text"]="客户端走的位置"+p[0]+p[1]drawOtherChess(x,y)s.close()

2.判断输赢的算法

   本游戏关键技术就是判断输赢的算法,对于算法实现大致可以分为以下几个部分:

(1)判断X=Y轴上是否形成五子连珠;

(2)判断X=-Y轴上是否形成五子连珠;

(3)判断X轴上是否形成五子连珠;

(4)判断Y轴上是否形成五子连珠;

#输赢判断
def win_lose():a=str(turn)print("a=",a)for i in range(0,11):for j in range(0,11):if map[i][j]==a and map[i+1][j+1]==a and map[i+2][j+2]==a and map[i+3][j+3]==a and map[i+4][j+4]==a:print("x=y轴上形成五子连珠")return Truefor i in range(4,15):for j in range(0,11):if map[i][j]==a and map[i-1][j+1]==a and map[i-2][j+2]==a and map[i-3][j+3]==a and map[i-4][j+4]==a:print("x=-y轴上形成五子连珠")return Truefor i in range(0,15):for j in range(4,15):if map[i][j]==a and map[i][j-1]==a and map[i][j-2]==a and map[i][j-2]==a and map[i][j-4]==a:print("Y轴上形成了五子连珠")return Truefor i in range(0,11):for j in range(0,15):if map[i][j]==a and map[i+1][j]==a and map[i+2][j]==a and map[i+3][j]==a and map[i+4][j]==a:print("X轴形成五子连珠")return Truereturn False

二. 源代码:
1.客户端编程代码如下:

from tkinter import *
from tkinter.messagebox import *
import socket
import threading
import os
#主程序
root=Tk()
root.title("网络五子棋v2.0--UDP客户端")
imgs=[PhotoImage(file='E:\\game\\BlackStone.gif'),PhotoImage(file='E:\\game\\WhiteStone.gif')]
turn=0
Myturn=-1
#画对方棋子
def drawOtherChess(x,y):global turnimg1=imgs[turn]cv.create_image((x*40+20,y*40+20),image=img1)cv.pack()map[x][y]=str(turn)#换下一方走棋if turn==0:turn=1else:turn=0
#发送消息
def sendMessage(pos):global ss.sendto(pos.encode(),(host,port))
#退出函数
def callexit(event):pos="exit|"sendMessage(pos)os._exit(0)
#走棋函数
def callback(event):global turnglobal Myturnif Myturn==-1:Myturn=turnelse:if(Myturn!=turn):showinfo(title="提示",message="还没轮到自己走棋")return#print("clicked at",event.x,event.y)x=(event.x)//40y=(event.y)//40print("clicked at",x,y,turn)if map[x][y]!=" ":showinfo(title="提示",message="已有棋子")else:img1=imgs[turn]cv.create_image((x*40+20,y*40+20),image=img1)cv.pack()map[x][y]=str(turn)pos=str(x)+','+str(y)sendMessage("move|"+pos)print("客户端走的位置",pos)label1["text"]="客户端走的位置"+pos#输出输赢信息if win_lose( )==True:if turn==0:showinfo(title="提示",message="黑方你赢了")sendMessage("over|黑方你赢了!")else:showinfo(title="提示",message="白方你赢了!")sendMessage("over|白方你赢了!")#换下一方走棋:if turn==0:turn=1else:turn=0
#画棋盘
def drawQiPan( ): #画棋盘for i in range(0,15):cv.create_line(20,20+40*i,580,20+40*i,width=2)for i in range(0,15):cv.create_line(20+40*i,20,20+40*i,580,width=2)cv.pack()
#输赢判断
def win_lose():a=str(turn)print("a=",a)for i in range(0,11):for j in range(0,11):if map[i][j]==a and map[i+1][j+1]==a and map[i+2][j+2]==a and map[i+3][j+3]==a and map[i+4][j+4]==a:print("x=y轴上形成五子连珠")return Truefor i in range(4,15):for j in range(0,11):if map[i][j]==a and map[i-1][j+1]==a and map[i-2][j+2]==a and map[i-3][j+3]==a and map[i-4][j+4]==a:print("x=-y轴上形成五子连珠")return Truefor i in range(0,15):for j in range(4,15):if map[i][j]==a and map[i][j-1]==a and map[i][j-2]==a and map[i][j-2]==a and map[i][j-4]==a:print("Y轴上形成了五子连珠")return Truefor i in range(0,11):for j in range(0,15):if map[i][j]==a and map[i+1][j]==a and map[i+2][j]==a and map[i+3][j]==a and map[i+4][j]==a:print("X轴形成五子连珠")return Truereturn False#接受消息
def receiveMessage(): #接受消息global swhile True:data = s.recv(1024).decode('utf-8')a = data.split("|")if not data:print('server has exited!')breakelif a[0] == 'exit':print('对方退出!')lanel1["text"] = '对方退出!游戏结束!'elif a[0] == 'over':print('对方赢信息!')label1["text"] = data.split("|")[0]showinfo(title="提示", message=data.split("|")[1])elif a[0] == 'move':print('received:', data)p = a[1].split(",")x = int(p[0])y = int(p[1])print(p[0], p[1])label1["text"] = "服务器走的位置" + p[0] + p[1]drawOtherChess(x,y)s.close()
#启动线程接受客户端消息
def startNewThread():thread=threading.Thread(target=receiveMessage,args=())thread.setDaemon(True)thread.start()
#主程序map=[[" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "] for y in range(15)]
cv=Canvas(root,bg='green',width=610,height=610)
drawQiPan()
cv.bind("<Button-1>",callback)
cv.pack()
label1=Label(root,text="客户端...")
label1.pack()
button1=Button(root,text="退出游戏")
button1.bind("<Button-1>",callexit)
button1.pack()
#创建UDP
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
port=8000
host='localhost'
pos='join|'
sendMessage(pos)
startNewThread()
root.mainloop()

2.数据通信协议源代码:
下面展示一些 数据通信协议源代码

def receiveMessage():global swhile True:global addrdata,addr=s.recvfrom(1024)data=data.decode('utf-8')a=data.split("|")if not data:print("client has exited!")breakelif a[0]=='join':  #连接服务器请求print('client 连接服务器!')label1["text"]='client连接服务器成功,请你走棋!'elif a[0]=='exit':print('client 对方退出!')label1["text"]='client对方退出,游戏结束!'elif a[0]=='over':print('对方赢信息!')label1["text"]=data.split("|")[0]showinfo(title="提示",message=data.split("|")[1])elif a[0]=='move':print('received:',data,'from',addr)p=a[1].split(",")x=int(p[0])y=int(p[1])print(p[0],p[1])label1["text"]="客户端走的位置"+p[0]+p[1]drawOtherChess(x,y)s.close()
#输赢判断
def win_lose():a=str(turn)print("a=",a)for i in range(0,11):for j in range(0,11):if map[i][j]==a and map[i+1][j+1]==a and map[i+2][j+2]==a and map[i+3][j+3]==a and map[i+4][j+4]==a:print("x=y轴上形成五子连珠")return Truefor i in range(4,15):for j in range(0,11):if map[i][j]==a and map[i-1][j+1]==a and map[i-2][j+2]==a and map[i-3][j+3]==a and map[i-4][j+4]==a:print("x=-y轴上形成五子连珠")return Truefor i in range(0,15):for j in range(4,15):if map[i][j]==a and map[i][j-1]==a and map[i][j-2]==a and map[i][j-2]==a and map[i][j-4]==a:print("Y轴上形成了五子连珠")return Truefor i in range(0,11):for j in range(0,15):if map[i][j]==a and map[i+1][j]==a and map[i+2][j]==a and map[i+3][j]==a and map[i+4][j]==a:print("X轴形成五子连珠")return Truereturn False
def checkwin(x,y):flag=Falsecount=1color=map[x][y]i=1#横向判断while color==map[x+i][y]:count=count+1i=i+1i=1while color==map[x-i][y]:count=count+1i=i+1if count>=5:flag=True#竖向判断i=1while color==map[x][y+i]:count=count+1i=i+1i=1while color==map[x][y-i]:count=count+1i=i+1if count>=5:flag=True#x=y判断i=1j=1while color==map[x+i][y+i]:count=count+1i=i+1j=j+1if count>=5:flag=Truej=1i=1while color==map[x-i][y-i]:count=count+1i=i+1j=j+1if count>=5:flag=True

3.服务器端源代码

客户端源代码如下:
from tkinter import *
from tkinter.messagebox import *
import socket,threading,os
def drawQiPan():for i in range(0,15):cv.create_line(20,20+40*i,580,20+40*i,width=2)for i in range(0,15):cv.create_line(20+40*i,20,20+40*i,580,width=2)cv.pack()
#走棋函数
def callpos(event):global turnglobal Myturnif Myturn==-1:  #第一次确认自己的角色Myturn=turnelse:if(Myturn!=turn):showinfo(title="提示",message="还没轮到自己下棋")return#print("clicked at",event.x,event.y,true)x=(event.x)//40y=(event.y)//40print("clicked at",x,y,turn)if map[x][y]!=" ":showinfo(title="提示",message="已有棋子")else:img1=imgs[turn]cv.create_image((x*40+20,y*40+20),image=img1)cv.pack()map[x][y]=str(turn)pos=str(x)+","+str(y)sendMessage("move|"+pos)print("服务器走的位置",pos)label1["text"]="服务器走的位置"+pos#输出输赢信息if win_lose( )==True:if turn==0:showinfo(title="提示",message="黑方你赢了")sendMessage("over|黑方你赢了")else:showinfo(title="提示", message="白方你赢了")sendMessage("over|白方你赢了")#换下一方走棋if turn==0:turn=1else:turn=0
#发送消息
def sendMessage(pos):global sglobal addrs.sendto(pos.encode(),addr)
#退出函数
def callexit(event):pos="exit|"sendMessage(pos)os._exit(0)#画对方棋子
def drawOtherChess(x,y):global turnimg1=imgs[turn]cv.create_image((x*40+20,y*40+20),image=img1)cv.pack()map[x][y]=str(turn)#换下一方走棋if turn==0:turn=1else:turn=0#判断整个棋盘的输赢
def win_lose():a=str(turn)print("a=",a)for i in range(0,11):for j in range(0,11):if map[i][j]==a and map[i+1][j+1]==a and map[i+2][j+2]==a and map[i+3][j+3]==a and map[i+4][j+4]==a:print("x=y轴上形成五子连珠")return Truefor i in range(4,15):for j in range(0,11):if map[i][j]==a and map[i-1][j+1]==a and map[i-2][j+2]==a and map[i-3][j+3]==a and map[i-4][j+4]==a:print("x=-y轴上形成五子连珠")return Truefor i in range(0,15):for j in range(4,15):if map[i][j]==a and map[i][j-1]==a and map[i][j-2]==a and map[i][j-2]==a and map[i][j-4]==a:print("Y轴上形成了五子连珠")return Truefor i in range(0,11):for j in range(0,15):if map[i][j]==a and map[i+1][j]==a and map[i+2][j]==a and map[i+3][j]==a and map[i+4][j]==a:print("X轴形成五子连珠")return Truereturn False
#输出map地图
def print_map():for j in range(0,15):for i in range(0,15):print(map[i][j],end=' ')print('w')
#接受消息
def receiveMessage():global swhile True:#接受客户端发送的消息global addrdata,addr=s.recvfrom(1024)data=data.decode('utf-8')a=data.split("|")if not data:print('client has exited!')breakelif a[0]=='join':#连接服务器的请求print('client 连接服务器!')label1["text"]='client连接服务器成功,请你走棋!'elif a[0]=='exit':print('client对方退出!')label1["text"]='client对方退出,游戏结束!'elif a[0]=='over':print('对方赢信息!')labl1["text"]==data.split("|")[0]showinfo(title="提示",message=data.split("1")[1])elif a[0]=='move':print('received:',data,'from',addr)p=a[1].split(",")x=int(p[0])y=int(p[1])print(p[0],p[1])label1["text"]="客户端走的位置"+p[0]+p[1]drawOtherChess(x,y)s.close()
def startNewThread( ):#启动新线程来接受客户端消息thread=threading.Thread(target=receiveMessage,args=())thread.setDaemon(True)thread.start()
root=Tk()
root.title("网络五子棋v2.0-服务器端")
imgs=[PhotoImage(file='E:\\game\\BlackStone.gif'),PhotoImage(file='E:\\game\\WhiteStone.gif')]
turn=0
Myturn=-1
map=[[" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "] for y in range(15)]
cv=Canvas(root,bg='green',width=610,height=610)
drawQiPan()
cv.bind("<Button-1>",callpos)
cv.pack()
label1=Label(root,text="服务器端...")
label1.pack()
button1=Button(root,text="退出游戏")
button1.bind("<Button-1>",callexit)
button1.pack()
#创建UDP SOCKET
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind(('localhost',8000))
addr=('localhost',8000)
startNewThread()
root.mainloop()

运行结果展示:

所有的都在这里了,欢迎各位大佬批评指正,

python网络编程案例—五子棋游戏相关推荐

  1. python网络编程案例_Python 网络编程_python网络编程基础_python高级编程

    Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...

  2. python网络编程案例_python网络编程实例简析

    本文实例讲述了python网络编程,分享给大家供大家参考. 具体方法如下: 服务端代码如下: from SocketServer import(TCPServer as TCP, StreamRequ ...

  3. python网络编程(苦肝一夜,近万字)

    文章目录 一.TCP/IP简介 二.网络设计模块 1.Socket简介 2.python中的socket模块,使用该模块建立服务器需要6个步骤. 1.创建socket对象. 2.将socket绑定(指 ...

  4. 肝!Python 网络编程

    什么是网络? 网络就是一种辅助双方或者多方能够连接在一起,然后可以进行数据传递的工具. 就是为了联通多方然后进行通信用的,即把数据从一方传递给另外一方,为了让在不同的电脑上运行的软件,之间能够互相传递 ...

  5. python网络编程要学吗_总算发现如何学习python网络编程

    为了提高模块加载的速度,每个模块都会在__pycache__文件夹中放置该模块的预编译模块,命名为module.version.pyc,version是模块的预编译版本编码,一般都包含Python的版 ...

  6. 读书笔记 - -《Python网络编程》重点

    文章目录 一.前言 二.客户/服务器网络编程简介 三.UDP 3.1 端口号 3.2 套接字 3.3 UDP分组 3.4 小结 四.TCP 4.1 TCP工作原理 4.2 绑定接口 4.3 死锁 4. ...

  7. python网络编程--socket简单实现

    python网络编程                                                                                           ...

  8. python网络编程-异常处理-异常捕获-抛出异常-断言-自定义异常-UDP通信-socketserver模块应用-03

    python网络编程-异常处理-异常捕获-抛出异常-断言-自定义异常-UDP通信-socketserver模块应用-03 参考文章: (1)python网络编程-异常处理-异常捕获-抛出异常-断言-自 ...

  9. python编程入门指南怎么样-学习python网络编程怎么入门

    第一部分底层网络学习 Python提供了访问底层操作系统Socket接口的全部方法,需要的时候这些接口可以提供灵活而强有力的功能. (1)基本客户端操作 在<python 网络编程基础>一 ...

最新文章

  1. java.io.FileNotFoundException: /storage/emulated/0/one.mp4 (Permission denied)
  2. Spring Cloud开发实践 - 04 - Docker部署
  3. linux操作python
  4. hihocoder 1122 : 二分图二•二分图最大匹配之匈牙利算法
  5. 祁门木板厂深夜失火,及早安装火灾报警器
  6. [蓝桥杯][历届试题]连号区间数
  7. 一次查找sqlserver死锁的经历
  8. 用浏览器管理 Docker
  9. Log4net之开始使用
  10. 跑步与读书都废掉了...工作目前也在换新的.
  11. LOCK TABLES
  12. MFC的Dialogbox多行文本框(CEdit)有最大字符限制,默认最大显示长度
  13. Net设计模式实例之观察者模式(Observer Pattern)
  14. mysql56数据库的创建_如何在Mysql下用命令创建数据库用户方法
  15. mybatis plus 动态创建表和字段_mybatis-plus maven代码生成器
  16. hyperledger fabric v2.4 默认区块大小 配置文件位置
  17. shift 位置参数左移命令
  18. EXCEL生成SQL脚本
  19. [Everyday Mathematic]20150217
  20. Java基础语法总结

热门文章

  1. 中国互联网企业员工平均年龄出炉:字节跳动、拼多多最年轻仅 27 岁
  2. 预告 | 10月北京,工信部人才交流中心5G行业应用系列培训全面开启
  3. 多表查询时,执行速度耗时太多
  4. Java岗大厂面试百日冲刺 - 日积月累,每日三题【Day16】—— Spring框架2
  5. c语言编程三角波,STM32 三角波输出
  6. Openwrt编译feeds机制
  7. edptrayicon怎么卸载_怎么彻底卸载北信源监控软件?(2)
  8. c++代码实现我的世界
  9. mysql去重分组_mysql 分组 去重
  10. JSON对象数组去重