from tkinter import *
from tkinter.messagebox import *
import socket
import threading
import os
主程序
root = Tk()
root.title('网络五子棋v2.0——服务器端')
imgs = [PhotoImage(file = 'BlackStone.gif'), PhotoImage(file='WhiteStone.gif')]
turn = 0
Myturn = -1
map = [[' '] * 15 for y in range(15)]
# print(map)
cv = Canvas(root, bg = 'green', width = 610, heigth = 610)
drawQiPan()
cv.bind('
创建UDP SOCKET
s =socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('localhost', 8000))
addr = ('localhost', 8000)
startNewThread() # 启动线程接收客户端消息
receiveMessage()
root.mainloop()
退出函数
def callexit(event):
pos = 'exit|'
sendMessage(pos)
os._exit(0)
走棋函数
def callpos(event):
global turn
global Myturn
if Myturn == -1:
Myturn = turn
else:
if Myturn != turn:
showinfo(title = '提示', message='还没轮到自己走棋')
return
x = (event.x) // 40
y = (event.y) // 40
print('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 = 1
else:
turn = 0
画对方棋子
def drawOtherChess(x, y):
global turn
img1 = imgs[turn]
cv.create_image((x*40+20, y*40+20), image = img1)
cv.pack()
map[x][y] = str(turn)
# 换下一方走棋
if turn == 0:
turn = 1
else:
turn = 0
画棋盘
def drawQiPan():
for i in range(15):
cv.create_line(20, 20+40*i, 580, 20+40*i, width = 2)
for i in range(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)
# 判断X=Y轴上是否形成五子连珠
for i in range(11):
for j in range(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 True
# 判断X=-Y轴上是否形成五子连珠
for i in range(4, 15):
for j in range(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 True
# 判断Y轴上是否形成五子连珠
for i in range(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-3]==a and map[i][j-4]==a:
print('Y轴上形成五子连珠!')
return True
# 判断X轴上是否形成五子连珠
for i in range(11):
for j in range(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 True
return False
输出map地图
def print_map():
for j in range(15):
for i in range(15):
print(map[i][j], end = ' ')
print('w')
处理接收消息data
通信协议具体实现
def receiveMessage(): # 接收消息函数!
global s
while True:
# 接收客户端发送的消息
global addr
data, addr = s.recvfrom(1024)
data = data.decode('utf-8')
a = data.split('|') # 分割数据!
if not data:
print('client has exited!')
break
elif 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('receive:', 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 sendMessage(pos):
global s
global addr
s.sendto(pos.encode(), addr)
启动线程接收客户端的消息
def startNewThread():
thread = threading.Thread(target=receiveMessage, args = ())
thread.setDaemon(True)
thread.start()
2、客户端程序设计的步骤
from tkinter import *
from tkinter.messagebox import *
import socket
import threading
import os
主程序
root = Tk()
root.title('网络五子棋v2.0——UDP客户端')
imgs = [PhotoImage(file = 'BlackStone.gif'), PhotoImage(file='WhiteStone.gif')]
turn = 0
Myturn = -1
map = [[' '] * 15 for y in range(15)]
# print(map)
cv = Canvas(root, bg = 'green', width = 610, heigth = 610)
drawQiPan()
cv.bind('
创建UDP SOCKET
s =socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
port = 8000
host = 'localhost'
post = 'join|'
sendMessage(pos)
startNewThread() # 启动线程接收客户端消息
receiveMessage()
root.mainloop()
退出函数
def callexit(event):
pos = 'exit|'
sendMessage(pos)
os._exit(0)
走棋函数
def callback(event):
global turn
global Myturn
if Myturn == -1:
Myturn = turn
else:
if Myturn != turn:
showinfo(title = '提示', message='还没轮到自己走棋')
return
x = (event.x) // 40
y = (event.y) // 40
print('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 = 1
else:
turn = 0
画棋盘
def drawQiPan():
for i in range(15):
cv.create_line(20, 20+40*i, 580, 20+40*i, width = 2)
for i in range(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)
# 判断X=Y轴上是否形成五子连珠
for i in range(11):
for j in range(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 True
# 判断X=-Y轴上是否形成五子连珠
for i in range(4, 15):
for j in range(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 True
# 判断Y轴上是否形成五子连珠
for i in range(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-3]==a and map[i][j-4]==a:
print('Y轴上形成五子连珠!')
return True
# 判断X轴上是否形成五子连珠
for i in range(11):
for j in range(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 True
return False
接收消息
处理接收消息data
通信协议具体实现
def receiveMessage(): # 接收消息函数!
global s
while True:
data = s.recv(1024).decode('utf-8')
a = data.split('|') # 分割数据!
if not data:
print('server has exited!')
break
elif a[0] == 'exit':
print('对方退出!')
label1['text'] = '对方退出,游戏结束!'
elif a[0] == 'over':
print('对方赢信息!')
label1['text'] = data.split('|')[0]
showinfo(title='提示', message=data.split('|')[1])
elif a[0] == 'move':
print('receive:', 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 sendMessage(pos):
global s
s.sendto(pos.encode(), (host, port))
启动线程接收服务器端的消息
def startNewThread():
thread = threading.Thread(target=receiveMessage, args = ())
thread.setDaemon(True)
thread.start()
料理码王
原创文章 294获赞 15访问量 1万+
关注
私信
展开阅读全文