python开发一款有局域网对战功能的中国象棋游戏

您所在的位置:网站首页 写作新闻消息范文 python开发一款有局域网对战功能的中国象棋游戏

python开发一款有局域网对战功能的中国象棋游戏

#python开发一款有局域网对战功能的中国象棋游戏| 来源: 网络整理| 查看: 265

目标:

1.对战功能的中国象棋游戏2.UDP局域网对战功能3.有聊天框便于交流4.有若干按钮,悔棋或退出游戏等。

2.游戏逻辑分析:

棋盘是个9*10(90个交叉点)的布局,红黑子各为16个。

9*10的二维列表表示棋盘,有棋子的交点对应的元素为棋子图像,没有棋子的交点所对应的元素设置为-1,用此二维列表表示当前棋盘的棋局。

 

将或帅只能在各自的九宫格内垂直或水平移动。

士只能在九宫格对角线位置移动。

象只能在自己一侧移动,可以每次沿着对角线移动两点,但在移动过程中不能穿越障碍(象腿)

马可以随便移动,每次沿着水平或垂直方向移动一点,然后再沿对角线移动一次,但在移动过程中不能穿越障碍(马腿)

车可以任何位置水平或垂直移动到无阻碍的点

炮可以任何位置水平或垂直移动,但吃子时必须跳过一个棋子来吃掉。

兵每次只能移动一点,过河后,便增加了向左右移动的能力,兵卒不允许向后移动。

3.胜负逻辑

自己的帅被吃掉、发出认输请求、超出时间算失败。

 

 

首先代码实现移动棋子功能试验:

from tkinter import * def callback(): #棋子移动函数测试 cv.move(rt1, 150, 150) # 图形对象、x偏移量、y坐标偏移量 root = Tk() root.title('移动帅棋子') cv = Canvas(root, bg='white', width=260, height=220) img1 = PhotoImage(file='红帅.png') cv.create_rectangle(40, 40, 190, 190, outline='red', fill='green') # 左上坐标40,40,右下190,190,后色边缘,绿色北京 rt1 = cv.create_image((40, 40), image=img1) # 40,40坐标插入图片 cv.pack() # 显示画布对象 button1 = Button(root, text='移动棋子', command=callback, fg='red') # 按钮设置 button1.pack() root.mainloop()

再测试棋子被吃掉的方法:

def callback(): # 棋子移动函数测试 cv.move(rt1, 150, 150) # 图形对象、x偏移量、y坐标偏移量 def callback2(): # 测试删除棋子图片 cv.delete(rt1) root = Tk() root.title('移动帅棋子') cv = Canvas(root, bg='white', width=260, height=220) img1 = PhotoImage(file='红帅.png') cv.create_rectangle(40, 40, 190, 190, outline='red', fill='green') # 左上坐标40,40,右下190,190,后色边缘,绿色北京 rt1 = cv.create_image((40, 40), image=img1) # 40,40坐标插入图片 cv.pack() # 显示画布对象 button1 = Button(root, text='移动棋子', command=callback, fg='red') # 按钮设置 button1.pack() button2 = Button(root, text='删除棋子', command=callback2, fg='red') # 按钮设置 button2.pack() root.mainloop()

 

显示棋盘图像:

from tkinter import * root = Tk() root.title('棋盘') img1 = PhotoImage(file='棋盘.png') cv = Canvas(root, bg='white', width=720, height=800) # 720*800的画布 p1 = cv.create_image((0, 0), image=img1) # 从左上角0,0对齐 cv.coords(p1, (360, 400)) # cv的中心点坐标 cv.pack() root.mainloop()

 

画出棋子:

from tkinter import * from tkinter.messagebox import * root = Tk() root.title('中国象棋') img1 = PhotoImage(file='棋盘.png') cv = Canvas(root, bg='white', width=720, height=800) # 720*800的画布 p1 = cv.create_image((0, 0), image=img1) # 从左上角0,0对齐 cv.coords(p1, (360, 400)) # cv的中心点坐标 chessname = ['黑车', '黑马', '黑象', '黑仕', '黑将', '黑仕', '黑象', '黑马', '黑车', '黑卒', '黑炮', '红车', '红马', '红相', '红仕', '红帅', '红仕', '红相', '红马', '红车', '红兵', '红炮'] imgs = [PhotoImage(file=chessname[i] + '.png') for i in range(0, 22)] chessmap = [[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] for y in range(10)] # 棋盘初始符号 dict_ChessName = {} LocalPlayer = '红' # 记录自己是红方还是黑方 first = True # 区分第一次还是第二次选中棋子 IsMyTurn=True rect1 = 0 rect2 = 0 firstChessid = 0 for i in range(0, 9): img = imgs[i] id = cv.create_image((60 + 76 * i, 54), image=img) # 76*76格子的棋盘,id独有 chessmap[i][0] = id dict_ChessName[id] = chessname[i] for i in range(0, 5): img = imgs[9] # 卒子图像 id = cv.create_image((60 + 76 * 2 * i, 54 + 3 * 76), image=img) chessmap[i * 2][3] = id dict_ChessName[id] = '黑卒' img = imgs[10] # 黑炮 id = cv.create_image((60 + 76 * 7, 54 + 2 * 76), image=img) chessmap[7][2] = id dict_ChessName[id] = '黑炮' id = cv.create_image((60 + 76 * 1, 54 + 2 * 76), image=img) chessmap[1][2] = id dict_ChessName[id] = '黑炮' for i in range(0, 9): img = imgs[i + 11] id = cv.create_image((60 + 76 * i, 54 + 9 * 76), image=img) # 76*76格子的棋盘,id独有 chessmap[i][9] = id dict_ChessName[id] = chessname[i + 11] for i in range(0, 5): img = imgs[20] # 红兵图像 id = cv.create_image((60 + 76 * 2 * i, 54 + 6 * 76), image=img) chessmap[i * 2][6] = id dict_ChessName[id] = '红兵' img = imgs[21] # 红炮 id = cv.create_image((60 + 76 * 7, 54 + 7 * 76), image=img) chessmap[7][7] = id dict_ChessName[id] = '红炮' id = cv.create_image((60 + 76 * 1, 54 + 7 * 76), image=img) chessmap[1][7] = id dict_ChessName[id] = '红炮' cv.pack() root.mainloop()

 

实现代码:

# -*- coding: utf-8 -*- # @Time : 2020/12/6 13:53 # @Author : Zhenghui Lyu # @FileName: qizi.py # @Email : [email protected] # @Software: PyCharm # @Blog :https://www.cnblogs.com/ZhenghuiLyu from tkinter import * from tkinter.messagebox import * # def callback(event): # 走棋 # global LocalPlayer # global chessmap # global rect1, rect2 # global firstChessid, secondChessid # global x1, x2, y1, y2 # global first # x = (event.x - 14) // 76 # y = (event.y - 14) // 76 # print('点击处:', x, y, '玩家', LocalPlayer) # if first: # x1 = x # y1 = y # firstChessid = chessmap[x1][y1] # if not (chessmap[x1][y1] == -1): # 位置不为空 # player = dict_ChessName[firstChessid][0] # 获取棋子颜色 # if player != LocalPlayer: # print('单击对方棋子了!') # return # print('第一次单击', firstChessid) # first = False # rect1 = cv.create_rectangle(60 + 77 * x - 40, 54 + y * 76 - 38, 60 + 76 * x + 80 - 40, # 54 + y * 76 + 80 - 38, outline='red') # else: # x2 = x # y2 = y # secondChessid = chessmap[x2][y2] # if not (chessmap[x2][y2] == -1): # 位置不为空 # player = dict_ChessName[firstChessid][0] # 获取棋子颜色 # if player == LocalPlayer: # firstChessid = chessmap[x2][y2] # print('第二次单击', firstChessid) # cv.delete(rect1) # x1 = x # y1 = y # rect1 = cv.create_rectangle(60 + 76 * x - 40, 54 + y * 76 - 38, 60 + 76 * x + 80 - 40, # 54 + y * 76 + 80 - 38, outline='red') # print('第二次单击', firstChessid) # return # else: # rect2 = cv.create_rectangle(60 + 76 * x - 40, 54 + y * 76 - 38, 60 + 76 * x + 80 - 40, # 54 + y * 76 + 80 - 38, outline='yellow') # print('kkk', firstChessid) # if chessmap[x2][y2] == ' ' or chessmap[x2][y2] == -1: # print('目标位置没有棋子,移动棋子', firstChessid, x2, y2, x1, y1) # if IsAblePut(firstChessid, x2, y2, x1, y1): # print('可以移动棋子', x1, y1) # cv.move(firstChessid, 76 * (x2 - x1), 76 * (y2 - y1)) # chessmap[x1][y1] = -1 # chessmap[x2][y2] = firstChessid # cv.delete(rect1) # cv.delete(rect2) # else: # print('错误走棋,不符合走棋规则') # showinfo(title='提示', message='不符合走棋规则') # return # else: # if not (chessmap[x2][y2] == -1) and IsAblePut(firstChessid, x2, y2, x1, y1): # first = True # print('可以吃子', x1, y1) # cv.move(firstChessid, 76 * (x2 - x1), 76 * (y2 - y1)) # chessmap[x1][y1] = -1 # chessmap[x2][y2] = firstChessid # cv.delete(secondChessid) # cv.delete(rect1) # cv.delete(rect2) # if dict_ChessName[secondChessid][1] == '将': # showinfo(title='提示', message='红方你赢了') # return # if dict_ChessName[secondChessid][1] == '帅': # showinfo(title='提示', message='黑方你赢了') # return # SetMyTrun(False) # else: # print('不能吃子') # label1['text'] = '不能吃子' # cv.delete(rect2) def callback(event): # 走棋picBoard_MouseClick global LocalPlayer global chessmap global rect1, rect2 # 选中框图像id global firstChessid, secondChessid global x1, x2, y1, y2 global first print("clicked at", event.x, event.y, LocalPlayer) x = (event.x - 14) // 76 # 换算棋盘坐标 y = (event.y - 14) // 76 print("clicked at", x, y, LocalPlayer) # if (IsMyTurn == False): # return; if (first): # 第1次单击棋子 x1 = x; y1 = y; firstChessid = chessmap[x1][y1] if not (chessmap[x1][y1] == -1): player = dict_ChessName[firstChessid][0] if (player != LocalPlayer): print("单击成对方棋子了!"); return print("第1次单击", firstChessid) first = False; rect1 = cv.create_rectangle(60 + 76 * x - 40, 54 + y * 76 - 38, 60 + 76 * x + 80 - 40, 54 + y * 76 + 80 - 38, outline="red") # 画选中标记框 else: # 第2次单击 x2 = x; y2 = y; secondChessid = chessmap[x2][y2] # 目标处如果是自己的棋子,则换上次选择的棋子 if not (chessmap[x2][y2] == -1): player = dict_ChessName[secondChessid][0] if (player == LocalPlayer): # 如果是自己的棋子,则换上次选择的棋子 firstChessid = chessmap[x2][y2] print("第2次单击", firstChessid) cv.delete(rect1); # 取消上次选择的棋子标记框 x1 = x; y1 = y; # 设置选择的棋子颜色 rect1 = cv.create_rectangle(60 + 76 * x - 40, 54 + y * 76 - 38, 60 + 76 * x + 80 - 40, 54 + y * 76 + 80 - 38, outline="red") # 画选中标记框 print("第2次单击", firstChessid) return; else: # 在落子目标处画框 rect2 = cv.create_rectangle(60 + 76 * x - 40, 54 + y * 76 - 38, 60 + 76 * x + 80 - 40, 54 + y * 76 + 80 - 38, outline="yellow") # 目标处画框; # 目标处没棋子,移动棋子 print("kkkkk", firstChessid) if (chessmap[x2][y2] == " " or chessmap[x2][y2] == -1): # 目标处没棋子,移动棋子 print("目标处没棋子,移动棋子", firstChessid, x2, y2, x1, y1) if (IsAblePut(firstChessid, x2, y2, x1, y1)): # 判断是否可以走棋 print("can移动棋子", x1, y1) cv.move(firstChessid, 76 * (x2 - x1), 76 * (y2 - y1)); # ****************************************** # 在map取掉原CurSelect棋子 chessmap[x1][y1] = -1; chessmap[x2][y2] = firstChessid cv.delete(rect1); cv.delete(rect2); # send # send("move" + "|" + idx.ToString() + "|" + (10 - x2).ToString() + "|" # + Convert.ToString(11 - y2) + "|" + StepList[StepList.Count - 1]); # CurSelect = 0; first = True; SetMyTurn(False); # 该对方了 # toolStripStatusLabel1.Text = ""; else: # 错误走棋 print("不符合走棋规则"); showinfo(title="提示", message="不符合走棋规则") return; else: # 目标处有棋子,可以吃子 if (not (chessmap[x2][y2] == -1) and IsAblePut(firstChessid, x2, y2, x1, y1)): # 可以吃子 first = True; print("can吃子", x1, y1) cv.move(firstChessid, 76 * (x2 - x1), 76 * (y2 - y1)); # ****************************************** # 在map取掉原CurSelect棋子 chessmap[x1][y1] = -1; chessmap[x2][y2] = firstChessid cv.delete(secondChessid); cv.delete(rect1); cv.delete(rect2); if (dict_ChessName[secondChessid][1] == "将"): # "将" showinfo(title="提示", message="红方你赢了") return; if (dict_ChessName[secondChessid][1] == "帅"): # "帅" showinfo(title="提示", message="黑方你赢了") return; # send SetMyTurn(False); # 该对方了 # toolStripStatusLabel1.Text = ""; else: # 不能吃子 print("不能吃子"); def SetMyTurn(flag): global LocalPlayer IsMyTurn = flag if LocalPlayer == '红': LocalPlayer = '黑' label1['text'] = '轮到黑方走' else: LocalPlayer = '红' label1['text'] = '轮到红方走' def IsAblePut(id, x, y, oldx, oldy): # 判断能走走棋,返回逻辑值 """oldx,oldy为原坐标,x,y为移动后新坐标,""" qi_name = dict_ChessName[id][1] # 字符串的第二个字符,得到棋子类型,如“将” if qi_name == '将' or qi_name == '帅': # 帅棋走法约束 if (x - oldx) * (y - oldy) != 0: # 斜着走 return False if abs(x - oldx) > 1 or abs(y - oldy) > 1: # 走多个格子 return False if x < 3 or x > 5 or (3 1 or abs(y - oldy) > 1: # 走多个格子 return False if x < 3 or x > 5 or (3 = 5 and qi_name == '象': return False i, j = 0, 0 if x - oldx == 2: i = x - 1 if x - oldx == -2: i = x + 1 if y - oldy == 2: j = y - 1 if y - oldy == -2: j = y + 1 if chessmap[i][j] != -1: return False return True if qi_name == '马': if abs(x - oldx) * abs(y - oldy) == '马': return False if x - oldx == 2: if chessmap[x - 1][oldy] != -1: # 蹩马腿 return False if x - oldx == -2: if chessmap[x + 1][oldy] != -1: # 蹩马腿 return False if y - oldy == 2: if chessmap[oldx][y - 1] != -1: # 蹩马腿 return False if y - oldy == -2: if chessmap[oldx][y + 1] != -1: # 蹩马腿 return False return True if qi_name == '车': if (x - oldx) * (y - oldy) != 0: return False if x != oldx: if oldx > x: t = x x = oldx oldx = t for i in range(oldx, x + 1): if i != x and i != oldx: if chessmap[i][y] != -1: return False if y != oldy: if oldy > y: t = y y = oldy oldy = t for i in range(oldy, y + 1): if i != y and i != oldy: if chessmap[x][i] != -1: return False return True if qi_name == '炮': swapflagx = False swapflagy = False if (x - oldx) * (y - oldy) != 0: return False c = 0 if x != oldx: if oldx > x: t = x x = oldx oldx = t swapflagx = True for i in range(oldx, x + 1): if i != x and i != oldx: if chessmap[i][y] != -1: c += 1 if y != oldy: if oldy > y: t = y y = oldy oldy = t swapflagy = True for i in range(oldy, y + 1): if i != y and i != oldy: if chessmap[x][i] != -1: c += 1 if c > 1: return False if c == 0: if swapflagx: t = x x = oldx oldx = t if swapflagy: t = y y = oldy oldy = t if chessmap[x][y] != -1: return False if c == 1: if swapflagx: t = x x = oldx oldx = t if swapflagy: t = y y = oldy oldy = t if chessmap[x][y] == -1: return False return True if qi_name == '卒' or qi_name == '兵': if (x - oldx) * (y - oldy) != 0: # 斜着走 return False if abs(x - oldx) > 1 or abs(y - oldy) > 1: # 走多个格子 return False if y >= 5 and x - oldx != 0 and qi_name == '兵': return False if y < 5 and x - oldx != 0 and qi_name == '卒': return False if y - oldy > 0 and qi_name == '兵': return False if y - oldy < 0 and qi_name == '卒': return False return True return True root = Tk() root.title('中国象棋') img1 = PhotoImage(file='棋盘.png') cv = Canvas(root, bg='white', width=720, height=800) # 720*800的画布 p1 = cv.create_image((0, 0), image=img1) # 从左上角0,0对齐 cv.coords(p1, (360, 400)) # cv的中心点坐标 chessname = ['黑车', '黑马', '黑象', '黑仕', '黑将', '黑仕', '黑象', '黑马', '黑车', '黑卒', '黑炮', '红车', '红马', '红相', '红仕', '红帅', '红仕', '红相', '红马', '红车', '红兵', '红炮'] imgs = [PhotoImage(file=chessname[i] + '.png') for i in range(0, 22)] chessmap = [[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] for y in range(10)] # 棋盘初始符号 dict_ChessName = {} LocalPlayer = '红' # 记录自己是红方还是黑方 first = True # 区分第一次还是第二次选中棋子 IsMyTurn=True rect1 = 0 rect2 = 0 # 棋子被选中时的框线 firstChessid = 0 secondChessid = 0 for i in range(0, 9): img = imgs[i] id = cv.create_image((60 + 76 * i, 54), image=img) # 76*76格子的棋盘,id独有 chessmap[i][0] = id dict_ChessName[id] = chessname[i] for i in range(0, 5): img = imgs[9] # 卒子图像 id = cv.create_image((60 + 76 * 2 * i, 54 + 3 * 76), image=img) chessmap[i * 2][3] = id dict_ChessName[id] = '黑卒' img = imgs[10] # 黑炮 id = cv.create_image((60 + 76 * 7, 54 + 2 * 76), image=img) chessmap[7][2] = id dict_ChessName[id] = '黑炮' id = cv.create_image((60 + 76 * 1, 54 + 2 * 76), image=img) chessmap[1][2] = id dict_ChessName[id] = '黑炮' for i in range(0, 9): img = imgs[i + 11] id = cv.create_image((60 + 76 * i, 54 + 9 * 76), image=img) # 76*76格子的棋盘,id独有 chessmap[i][9] = id dict_ChessName[id] = chessname[i + 11] for i in range(0, 5): img = imgs[20] # 红兵图像 id = cv.create_image((60 + 76 * 2 * i, 54 + 6 * 76), image=img) chessmap[i * 2][6] = id dict_ChessName[id] = '红兵' img = imgs[21] # 红炮 id = cv.create_image((60 + 76 * 7, 54 + 7 * 76), image=img) chessmap[7][7] = id dict_ChessName[id] = '红炮' id = cv.create_image((60 + 76 * 1, 54 + 7 * 76), image=img) chessmap[1][7] = id dict_ChessName[id] = '红炮' # print(dict_ChessName) cv.bind('', callback) label1 = Label(root, fg='red', bg='white', text='红方先走') # 显示先手标签 label1['text'] = '红方先走1' label1.pack() cv.pack() root.mainloop()

 

给象棋程序网络对战功能。

1.发送消息功能UDP

2.接收并根据消息内容画出棋盘情况

3.下棋并切换玩家直到一方胜利或者退出



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3