这次做的项目是五子棋,用python3的tkinter实现。
这次的做出来的还是比较简单的。
先上代码:这是一个URL。(Mywuziqi.py)
现在开始分析代码:
①首先先创建五子棋的窗口:
from tkinter import *
top = Tk()
top.title("五子棋") #给标题
top.geometry("510x525") #确定窗口大小
top.mainloop()
②画出五子棋的棋谱:
用Canvas函数来创建画布(Canvas 为 tkinter 提供了绘图功能)
canvas = Canvas(top, width=500, height=500)
canvas.pack(expand=YES, fill=BOTH)
在这里说下Canvas函数画布的XY坐标图是这样的:
然后画出棋谱:
for num in range(1, 17):
canvas.create_line(num*30, 30,
num*30, 480,
width=2)
for num in range(1, 17):
canvas.create_line(30, num*30,
480, num*30,
width=2)
canvas.create_line()注意这五个参数的意思,在这里我特意空行写出这样的格式,方便理解:
canvas.create_line(num*30, 30, #前两个参数是起始坐标
num*30, 480, #第三个和第四个参数是终点坐标
width=2) #width=2是创建的线条的宽度
也就是说,利用for函数创建出横竖16条线条,这样就创建出五子棋的棋谱了。如图:
③创建完棋谱后就是要下棋了,用鼠标左键下棋:
给鼠标左键添加监控:
canvas.bind("",paint)#每次点击鼠标左键(事件),触发paint函数
canvas.bind( )就是监听函数了,
paint函数是什么?就是确定棋子位置和显示棋子的函数,因为你要点击后出现棋子,就要确定你的点击坐标,函数如下:
color_number = 1
chess = [[0 for i in range(size+1)] for i in range(size+1)]
def paint(event):
#让棋子下在棋盘点上
global color_number
if event.x % 30 > 15 :
event.x = event.x//30 + 1
else:
event.x = event.x // 30
if event.y % 30 > 15:
event.y = event.y // 30 + 1
else:
event.y = event.y//30
#边缘检测
if event.x > size:
event.x = size
if event.y > size:
event.y = size
if event.x < 1:
event.x = 1
if event.y < 1:
event.y = 1
#确定下棋坐标
x1, y1 = (event.x*30 - 15), (event.y*30 - 15)
x2, y2 = (event.x*30 + 15), (event.y*30 + 15)
#画出棋子
if chess[event.x][event.y] == 0:
if color_number == 1:
canvas.create_oval(x1, y1, x2, y2, fill="black",tags = "oval")
chess[event.x][event.y] = 1
color_number = 0
elif color_number == 0:
canvas.create_oval(x1, y1, x2, y2, fill="white",tags = "oval")
chess[event.x][event.y] = 2
color_number = 1
对于每次鼠标左键点击(事件),canvas.bind()都会得到点击坐标(event),为了让棋子下在十字中间,我们需要对点击坐标进行修改,对X和Y求余数,如果大于15(30的一半,为什么是30,因为30是你创建的线与线之间的长度),就除于30后+1,小于15就直接除于30。然后将得到的event.x和event.y进行边缘检测,注意不要超出棋谱范围。
用canvas.create_oval( ) 创建椭圆,创建圆形需要用到起始坐标和终点坐标。
看这个图,确定起始坐标在中点的左上角,也就是X-15,Y-15,右下角则是X+15,Y+15。
黑白棋轮留下,我们用color_number 来显示,color_number = 1时下黑色棋子,color_number = 0下白色棋子。
为了让棋子不重复覆盖(点击原来的地方就会替换原来的棋子,这是不行的),我们创建一个全为0的二维数组。在点击的坐标后设置为相应的1和2(1代表黑子,2代表白子),只有该坐标为0的时候才能下棋子,这样就能不重复了。
现在棋子已经可以下了,接下来是判断是否成功五子连珠了
④判断五子连珠:
只要在当前下的点往八个方向进行搜索,判断八方有没有五子连珠就行了。
import tkinter.messagebox
def wininfo(): #提示窗口
global stop
tkinter.messagebox.showinfo("", "Game over")
stop = 1
def gameover(xx, yy):
count = 0
for i in range(xx + 1, 17): #向右搜索
if chess[i][yy] == chess[xx][yy]:
count += 1
else:
break
for i in range(xx, 0, -1): #向左搜索
if chess[i][yy] == chess[xx][yy]:
count += 1
else:
break
if count == 5:
wininfo()
count = 0
for i in range(yy + 1, 17): #向下搜索
if chess[xx][i] == chess[xx][yy]:
count += 1
else:
break
for i in range(yy, 0, -1): #向上搜索
if chess[xx][i] == chess[xx][yy]:
count += 1
else:
break
if count == 5:
wininfo()
count = 0
for i, j in zip(range(xx+1, 17), range(yy+1, 17)): #向右下搜索
if chess[i][j] == chess[xx][yy]:
count += 1
else:
break
for i, j in zip(range(xx, 0, -1), range(yy, 0, -1)):#向左上搜索
if chess[i][j] == chess[xx][yy]:
count += 1
else:
break
if count == 5:
wininfo()
count = 0
for i, j in zip(range(xx - 1, 0, -1), range(yy + 1, 17)): #向左下搜索
if chess[i][j] == chess[xx][yy]:
count += 1
else:
break
for i, j in zip(range(xx, 17), range(yy, 0, -1)): #向右上搜索
if chess[i][j] == chess[xx][yy]:
count += 1
else:
break
if count == 5:
wininfo()
count = 0
这样就基本完成五子棋项目了。
做到这里,这个五子棋基本是完成了,但是这个项目还有很多可以加功能的:
1.添加机器下棋功能,让人机互动起来(不论是暴力搜索还是人工智能,先做出来再说)
2.重新开始按钮,而不用重新打开游戏那么麻烦
3.添加网络功能,实现网络对战。
希望各位能做到以上功能,我也会努力做出上面的功能,望有朝一日更新此篇,最后欢迎各位看官看过之后留言交流点评和指导
本次项目参考资料:https://zhuanlan.zhihu.com/p/28364376