首页 > 技术文章 > 简单局域网五子棋游戏设计【PYTHON】【UDP】【tkinter】

SuperiorLQF 2021-04-02 15:55 原文

host端


  1 from tkinter import *
  2 import socket
  3 import os
  4 import time
  5 from pykeyboard import*
  6 import threading
  7 #初始化各种参数
  8 def initial_parameter():
  9     global BOARD_LENGTH,OFFSET,LINE_INTERVAL,all_chesspoint,YOURCHESS_COLOR,RIVALCHESS_COLOR,HOST_addr,\
 10         CLIENT_addr,aim_coordx,aim_coordy,x,y,over,flag
 11     #初始化棋盘参数
 12     BOARD_LENGTH=560
 13     OFFSET=20
 14     LINE_INTERVAL=40
 15     #初始化位置状态数组
 16     all_chesspoint=[[0 for i in range(15)]for j in range(15)]#用来存储棋盘格上每个点是否有棋子,1白棋,-1黑棋,0没有棋子
 17     YOURCHESS_COLOR=-1#您是黑棋(后行)
 18     RIVALCHESS_COLOR=1
 19     x=7;y=7#光标初始位置
 20     aim_coordx=OFFSET+x*LINE_INTERVAL;aim_coordy=OFFSET+y*LINE_INTERVAL#位置转像素坐标转化公式
 21     over=1
 22     flag=1
 23 #画棋盘函数
 24 def drawmap():
 25     cv.create_rectangle(20, 20, 580, 580, outline='brown', width=5)
 26     for i in range(13):
 27         cv.create_line(60+40*i,20,60+40*i,580,fill='brown')
 28     for i in range(13):
 29         cv.create_line(20,60+40*i,580,60+40*i,fill='brown')
 30 #画准心函数
 31 def drawaim(aim_coordx,aim_coordy):
 32     cv.create_rectangle(aim_coordx-18,aim_coordy-18,aim_coordx+18,aim_coordy+18,outline='red')
 33 #删除准心函数(用白色覆盖)
 34 def deleteaim(aim_coordx,aim_coordy):
 35     cv.create_rectangle(aim_coordx-18,aim_coordy-18,aim_coordx+18,aim_coordy+18,outline='white')
 36 #画一颗棋子
 37 def drawchess(aim_coordx,aim_coordy,color):#color=1为白棋,color=-1为黑棋,其他就不画
 38     if color==1:
 39         cv.create_oval(aim_coordx-15,aim_coordy-15,aim_coordx+15,aim_coordy+15,fill='white',outline='black',width=2)
 40     elif color==-1:
 41         cv.create_oval(aim_coordx-15,aim_coordy-15,aim_coordx+15,aim_coordy+15,fill='black',outline='black',width=2)
 42     else:
 43         pass
 44 #画全部棋子
 45 def drawallchess():#根据当下的位置状态数组画棋子
 46     global OFFSET,LINE_INTERVAL,all_chesspoint
 47     for i in range(15):
 48         for j in range(15):
 49             drawchess(OFFSET+i*LINE_INTERVAL,OFFSET+j*LINE_INTERVAL,all_chesspoint[i][j])
 50 def udpServer(udp_server,send_data):
 51     global all_chesspoint,HOST_addr,CLIENT_addr,over
 52     drawallchess()
 53     root.update_idletasks()
 54     udp_server.sendto(send_data.encode('utf-8'),CLIENT_addr) #发送数据
 55     recv_data, server_addr = udp_server.recvfrom(1024)#接受数据,等待对方反应......
 56     x_alter, y_alter = eval(recv_data.decode('utf-8'))
 57     all_chesspoint[int(x_alter)][int(y_alter)]= RIVALCHESS_COLOR#将改变后的数据在数组更新
 58     drawallchess()#刷新对方下完的棋盘
 59 #响应键盘事件
 60 def callback(event):
 61     global x,y,all_chesspoint,over,flag
 62     if over==1:#防止多次触发
 63         over = 0
 64         if event.char=='w' :
 65             deleteaim(OFFSET + x * LINE_INTERVAL, OFFSET + y * LINE_INTERVAL)
 66             if y>0:
 67                 y=y-1
 68             else:
 69                 y=14
 70             drawmap()
 71             drawaim(OFFSET + x * LINE_INTERVAL, OFFSET + y * LINE_INTERVAL)
 72             drawallchess()
 73         elif event.char=='s':
 74             deleteaim(OFFSET + x * LINE_INTERVAL, OFFSET + y * LINE_INTERVAL)
 75             if y<14:
 76                 y=y+1
 77             else:
 78                 y=0
 79             drawmap()
 80             drawaim(OFFSET + x * LINE_INTERVAL, OFFSET + y * LINE_INTERVAL)
 81             drawallchess()
 82         elif event.char=='a':
 83             deleteaim(OFFSET + x * LINE_INTERVAL, OFFSET + y * LINE_INTERVAL)
 84             if x>0:
 85                 x=x-1
 86             else:
 87                 x=14
 88             drawmap()
 89             drawaim(OFFSET + x * LINE_INTERVAL, OFFSET + y * LINE_INTERVAL)
 90             drawallchess()
 91         elif event.char=='d':
 92             deleteaim(OFFSET + x * LINE_INTERVAL, OFFSET + y * LINE_INTERVAL)
 93             if x<14:
 94                 x=x+1
 95             else:
 96                 x=0
 97             drawmap()
 98             drawaim(OFFSET + x * LINE_INTERVAL, OFFSET + y * LINE_INTERVAL)
 99             drawallchess()
100         elif event.keycode==13:
101             all_chesspoint[int(x)][int(y)]=YOURCHESS_COLOR
102             print(all_chesspoint)
103             udpServer(udp_server, '{},{}'.format(x,y))  # 发送并等待
104         else:
105             pass
106         over=1
107 def sub_func1(root):
108     recv_data, server_addr = udp_server.recvfrom(1024)  # 接受数据,等待对方反应......
109     x_alter, y_alter = eval(recv_data.decode('utf-8'))
110     all_chesspoint[int(x_alter)][int(y_alter)] = RIVALCHESS_COLOR  # 将改变后的数据在数组更新
111     drawmap()  # 刷新空棋盘
112     drawallchess()  # 刷新对方下完的棋盘
113     root.update_idletasks()
114     '''k = PyKeyboard()
115     time.sleep(5)
116     k.tap_key(k.alt_key)'''
117 
118 #主程序---------------------------------------------------------------------------
119 aim_coordx=0;aim_coordy=0
120 x=0;y=0;flag=0
121 over=0
122 HOST_PORT = 8081
123 HOST_addr = ('', HOST_PORT)
124 CLIENT_IP=input("请输入对方的IP地址")
125 CLIENT_PORT = 8080
126 CLIENT_addr = (CLIENT_IP, CLIENT_PORT)
127 initial_parameter()
128 root=Tk()#创建窗口
129 root.title("在线五子棋v1.0  UDP_HOST [您是黑子,对方先行]")
130 cv=Canvas(root,bg = 'white',height=600,width=600)#创建画布
131 cv.pack()  # 这句很重要,没有的话无法显示
132 cv.focus_set()
133 drawmap()#创建棋盘
134 drawaim(aim_coordx,aim_coordy)
135 cv.bind(sequence='<Key>',func=callback)
136 udp_server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
137 udp_server.bind(HOST_addr)#建立连接
138 sub_thread=threading.Thread(target=sub_func1,args=(root,))
139 sub_thread.start()
140 root.mainloop()

用户端


  1 from tkinter import *
  2 from tkinter.messagebox import *
  3 import socket
  4 import os
  5 import time
  6 from pykeyboard import*
  7 #初始化各种参数,请连接热点!!!!!
  8 def initial_parameter():
  9     global BOARD_LENGTH,OFFSET,LINE_INTERVAL,all_chesspoint,YOURCHESS_COLOR,RIVALCHESS_COLOR,HOST_addr,\
 10         CLIENT_addr,aim_coordx,aim_coordy,x,y,over
 11     #初始化棋盘参数
 12     BOARD_LENGTH=560
 13     OFFSET=20
 14     LINE_INTERVAL=40
 15     #初始化位置状态数组
 16     all_chesspoint=[[0 for i in range(15)]for j in range(15)]#用来存储棋盘格上每个点是否有棋子,1白棋,-1黑棋,0没有棋子
 17     YOURCHESS_COLOR=1#您是白棋(先行)
 18     RIVALCHESS_COLOR=-1
 19     x=7;y=7#光标初始位置
 20     aim_coordx=OFFSET+x*LINE_INTERVAL;aim_coordy=OFFSET+y*LINE_INTERVAL#位置转像素坐标转化公式
 21     over=1
 22 #画棋盘函数
 23 def drawmap():
 24     cv.create_rectangle(20, 20, 580, 580, outline='brown', width=5)
 25     for i in range(13):
 26         cv.create_line(60+40*i,20,60+40*i,580,fill='brown')
 27     for i in range(13):
 28         cv.create_line(20,60+40*i,580,60+40*i,fill='brown')
 29 #画准心函数
 30 def drawaim(aim_coordx,aim_coordy):
 31     cv.create_rectangle(aim_coordx-18,aim_coordy-18,aim_coordx+18,aim_coordy+18,outline='red')
 32 #删除准心函数(用白色覆盖)
 33 def deleteaim(aim_coordx,aim_coordy):
 34     cv.create_rectangle(aim_coordx-18,aim_coordy-18,aim_coordx+18,aim_coordy+18,outline='white')
 35 #画一颗棋子
 36 def drawchess(aim_coordx,aim_coordy,color):#color=1为白棋,color=-1为黑棋,其他就不画
 37     if color==1:
 38         cv.create_oval(aim_coordx-15,aim_coordy-15,aim_coordx+15,aim_coordy+15,fill='white',outline='black',width=2)
 39     elif color==-1:
 40         cv.create_oval(aim_coordx-15,aim_coordy-15,aim_coordx+15,aim_coordy+15,fill='black',outline='black',width=2)
 41     else:
 42         pass
 43 #画全部棋子
 44 def drawallchess():#根据当下的位置状态数组画棋子
 45     global OFFSET,LINE_INTERVAL,all_chesspoint
 46     for i in range(15):
 47         for j in range(15):
 48             drawchess(OFFSET+i*LINE_INTERVAL,OFFSET+j*LINE_INTERVAL,all_chesspoint[i][j])
 49 def udpClient(udp_client,send_data):
 50     global all_chesspoint,HOST_addr,CLIENT_addr,over
 51     drawallchess()
 52     root.update_idletasks()
 53     #test证明,它只有退出一次callback后才会刷新一次画面******
 54     udp_client.sendto(send_data.encode('utf-8'),HOST_addr) #发送数据
 55     recv_data, server_addr = udp_client.recvfrom(1024)#接受数据,等待对方反应......
 56     x_alter, y_alter = eval(recv_data.decode('utf-8'))
 57     all_chesspoint[int(x_alter)][int(y_alter)]= RIVALCHESS_COLOR#将改变后的数据在数组更新
 58     drawallchess()#刷新对方下完的棋盘
 59 def sub_draw():
 60     while True:
 61         drawallchess()
 62 #响应键盘事件
 63 def callback(event):
 64     global x,y,all_chesspoint,over
 65     if over==1:#防止多次触发
 66         over=0
 67         if event.char=='w' :
 68             deleteaim(OFFSET + x * LINE_INTERVAL, OFFSET + y * LINE_INTERVAL)
 69             if y>0:
 70                 y=y-1
 71             else:
 72                 y=14
 73             drawmap()
 74             drawaim(OFFSET + x * LINE_INTERVAL, OFFSET + y * LINE_INTERVAL)
 75             drawallchess()
 76         elif event.char=='s':
 77             deleteaim(OFFSET + x * LINE_INTERVAL, OFFSET + y * LINE_INTERVAL)
 78             if y<14:
 79                 y=y+1
 80             else:
 81                 y=0
 82             drawmap()
 83             drawaim(OFFSET + x * LINE_INTERVAL, OFFSET + y * LINE_INTERVAL)
 84             drawallchess()
 85         elif event.char=='a':
 86             deleteaim(OFFSET + x * LINE_INTERVAL, OFFSET + y * LINE_INTERVAL)
 87             if x>0:
 88                 x=x-1
 89             else:
 90                 x=14
 91             drawmap()
 92             drawaim(OFFSET + x * LINE_INTERVAL, OFFSET + y * LINE_INTERVAL)
 93             drawallchess()
 94         elif event.char=='d':
 95             deleteaim(OFFSET + x * LINE_INTERVAL, OFFSET + y * LINE_INTERVAL)
 96             if x<14:
 97                 x=x+1
 98             else:
 99                 x=0
100             drawmap()
101             drawaim(OFFSET + x * LINE_INTERVAL, OFFSET + y * LINE_INTERVAL)
102             drawallchess()
103         elif event.keycode==13:
104             all_chesspoint[int(x)][int(y)] = YOURCHESS_COLOR
105             print(all_chesspoint)
106             udpClient(udp_client, '{},{}'.format(x,y))  # 发送并等待
107         else:
108             pass
109         over=1
110 
111 #主程序---------------------------------------------------------------------------
112 aim_coordx=0;aim_coordy=0
113 x=0;y=0
114 over=0
115 HOST_IP = input("请输入对方的IP地址")
116 HOST_PORT = 8081
117 HOST_addr = (HOST_IP, HOST_PORT)
118 CLIENT_PORT = 8080
119 CLIENT_addr = ('', CLIENT_PORT)
120 initial_parameter()
121 root=Tk()#创建窗口
122 root.title("在线五子棋v1.0  UDP客户端 [您是白子,您先行]")
123 cv=Canvas(root,bg = 'white',height=600,width=600)#创建画布
124 cv.pack()  # 这句很重要,没有的话无法显示
125 cv.focus_set()
126 cv.bind(sequence='<Key>',func=callback)
127 udp_client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
128 udp_client.bind(CLIENT_addr)  # 建立连接
129 drawmap()#创建棋盘
130 drawaim(aim_coordx,aim_coordy)
131 root.mainloop()
132 #debug日志2.26:发现mainloop触发事件call 解决办法:    root.update_idletasks()

 

推荐阅读