本文共 6115 字,大约阅读时间需要 20 分钟。
了解游戏的规则是我们首先需要做的事情,如果不知晓规则,那么我们肯定寸步难行。
游戏规则:在这篇博客中我们只实现了较为简单的规则,不考虑规则6以及禁手的相关规定(个人能力有限,如果有愿意研究的朋友,我们可以一起研究研究 /抱拳)。
设计思路: 1、首先我们需要使用到界面,我们先分析界面上需要实现什么画面,也就是我们要进行这个五子棋游戏要看到什么。要看到:棋盘,棋子(棋子要分颜色,黑色和白色),这些是进行游戏的必需看到的。 2、外表做好以后我们需要去思考内部代码的填充,思考: ①棋子如何落到指定的位置, ②如何实现交替落子,实现颜色交替变换,并且做好记录方便计算棋子排布情况。 ③如何计算四个方位上的同色棋子达到获胜的数量。 首先把窗口调出来,实现代码:from tkinter import *#导入窗口第三方库root = Tk() #创建窗口root.title("憨憨制作的五子棋") #窗口名字w1 = Canvas(root, width=600,height=600,background='lightcyan')#在窗口中央创建一个画布,root是窗口,宽度600,高度600,背景色为lightcyanw1.pack() #布局方式,全局需要统一。mainloop()五子棋棋盘是由15条横线15条竖线组成的。 画出棋盘:
for i in range(0, 15): w1.create_line(i * 40 + 20, 20, i * 40 + 20, 580) w1.create_line(20, i * 40 + 20, 580, i * 40 + 20)w1.create_oval(135, 135, 145, 145,fill='black')w1.create_oval(135, 455, 145, 465,fill='black')w1.create_oval(465, 135, 455, 145,fill='black')w1.create_oval(455, 455, 465, 465,fill='black')w1.create_oval(295, 295, 305, 305,fill='black')
窗口的左上角坐标为(0,0),通过调试,我们得出起始位置为(20,20)较为合适,多次调试进行对比,我选择线间距为40比较不错。当然线宽,圆的大小,棋盘线的间距这些都是可以进行调整的,大家可以慢慢试探(h_h)。棋盘中的五个黑点需要我们通过计算得出位置。
create_line(起点,终点):画直线 create_oval(x1,y1,x2,y2,fill=‘颜色’)这个是画一个内切圆,矩形左上角(x1,y1),右下角(x2,y2)fill为填充色,我们可以从网上找到turtle颜色库,顺便帮大家找了一个,自行选择自己喜欢的颜色。效果图:
棋盘做好了,我们开始设计落子,这里需要交替进行颜色的改变,那我们就需要去通过一个判断方法来进行改变棋子的颜色。我想了两种:①一种是用字符标记当前鼠标上棋子的颜色,改变为另一种。②另一种是用计数的方式来进行改变。除此之外我们要规定已经放了棋子的位置不能再放棋子,也就是在落子前先判断当前位置是否有棋子。num=0 #计算棋盘上有几个棋子,用来判断下一颗棋子颜色A=np.full((15,15),0 ) #储存位置已有棋子的矩阵B=np.full((15,15),'') #用来记录每个位置棋子的颜色def callback(event): #输入的是点击事件,event.x和event.y是鼠标点击事件的位置 global num ,A #全局变量可以全局使用 for j in range (0,15): #双重循环定位点击位置最近的网格线交点(i,j),保证棋子落在线的交点处。 for i in range (0,15): if (event.x - 20 - 40 * i) ** 2 + (event.y - 20 - 40 * j) ** 2 <= 2 * 20 ** 2: break if (event.x - 20 - 40 * i) ** 2 + (event.y - 20 - 40 * j) ** 2 <= 2*20 ** 2: break if num % 2 == 0 and A[i][j] != 1:#判断现在这颗棋子的颜色。 w1.create_oval(40*i+5, 40*j+5, 40*i+35, 40*j+35,fill='black') A[i][j] = 1 B[i][j] = 'b' num += 1 if num % 2 != 0 and A[i][j] != 1 : w1.create_oval(40*i+5, 40*j+5, 40*i+35, 40*j+35,fill='white') A[i][j] = 1 B[i][j] = 'w' num += 1
落子以后需要计算是否五子连珠,每个棋子的计算方向有八个形成四条线,那么就是从落子处算先向一端算,直到遇到另一种颜色的棋子,反向查询遇到另一个颜色棋处出停止,当达到五颗棋子时即代表一方获胜,否则循环下一条线。当四条线结束未达到胜利条件,即可继续落子。
f = [[-1, 0], [-1, 1], [0, 1], [1, 1]] #四条线其中一个方向的坐标变化规律 for z in range(0, 4): #循环方向 a, b = f[z][0], f[z][1] count1, count2 = 0, 0 x, y = i, j while B[x][y] == B[i][j]:#当颜色相同即可进行计算 count1 += 1 if x + a > 0 and y + b > 0 and x + a < 15 and y + b < 15 and B[x + a][y + b] == B[i][j]:#保证不超出矩阵的边界,否则会报错 [x, y] = np.array([x, y]) + np.array([a, b]) else: x, y = i, j break while B[x][y] == B[i][j]:#从落子处反向计算同色棋子个数。 count2 += 1 if x - a < 15 and y - b < 15 and x - a > 0 and y - b > 0 and B[x - a][y - b] == B[i][j]: [x, y] = np.array([x, y]) - np.array([a, b]) else: break if count1 + count2 == 6: #计算了两次落子处 if B[i][j] == 'b': tkinter.messagebox.showinfo('提示', '黑棋获胜') else: tkinter.messagebox.showinfo('提示', '白棋获胜')
点击事件,每次点击以后都需要进行一次落子和游戏结束判断。调用函数进行落子,判断是否结束游戏。
w1.bind("
设置退出按钮:
u=Button(root,text="退出",width=10,height=1,command=quit,font=('楷体',15))u.pack()
完整代码:
from tkinter import *import tkinter.messagebox # 弹窗库import numpy as nproot = Tk() #创建窗口root.title("憨憨制作的五子棋") #窗口名字w1 = Canvas(root, width=600,height=600,background='lightcyan')w1.pack()for i in range(0, 15): w1.create_line(i * 40 + 20, 20, i * 40 + 20, 580) w1.create_line(20, i * 40 + 20, 580, i * 40 + 20)w1.create_oval(135, 135, 145, 145,fill='black')w1.create_oval(135, 455, 145, 465,fill='black')w1.create_oval(465, 135, 455, 145,fill='black')w1.create_oval(455, 455, 465, 465,fill='black')w1.create_oval(295, 295, 305, 305,fill='black')num=0A=np.full((15,15),0)B=np.full((15,15),'')def callback(event): global num ,A for j in range (0,15): for i in range (0,15): if (event.x - 20 - 40 * i) ** 2 + (event.y - 20 - 40 * j) ** 2 <= 2 * 20 ** 2: break if (event.x - 20 - 40 * i) ** 2 + (event.y - 20 - 40 * j) ** 2 <= 2*20 ** 2: break if num % 2 == 0 and A[i][j] != 1: w1.create_oval(40*i+5, 40*j+5, 40*i+35, 40*j+35,fill='black') A[i][j] = 1 B[i][j] = 'b' num += 1 if num % 2 != 0 and A[i][j] != 1 : w1.create_oval(40*i+5, 40*j+5, 40*i+35, 40*j+35,fill='white') A[i][j] = 1. B[i][j] = 'w' num += 1 f = [[-1, 0], [-1, 1], [0, 1], [1, 1]] for z in range(0, 4): a, b = f[z][0], f[z][1] count1, count2 = 0, 0 x, y = i, j while B[x][y] == B[i][j]: count1 += 1 if x + a > 0 and y + b > 0 and x + a < 15 and y + b < 15 and B[x + a][y + b] == B[i][j]: [x, y] = np.array([x, y]) + np.array([a, b]) else: x, y = i, j break while B[x][y] == B[i][j]: count2 += 1 if x - a < 15 and y - b < 15 and x - a > 0 and y - b > 0 and B[x - a][y - b] == B[i][j]: [x, y] = np.array([x, y]) - np.array([a, b]) else: break if count1 + count2 == 6: if B[i][j] == 'b': tkinter.messagebox.showinfo('提示', '黑棋获胜') else: tkinter.messagebox.showinfo('提示', '白棋获胜')w1.bind("
技术不精,但是喜欢做点小研究,从学习中找到玩耍的快乐,愿意和大家一起学习玩耍。文章较为粗糙, 还望包涵。
转载地址:http://hvtzi.baihongyu.com/