在18×18方阵中轮流在空白处放置黑白子,直到有一方形成横、竖、斜方向五连星获胜。
借鉴五子棋游戏编程思路,网上有许多,不一一赘述。直接看代码。
from tkinter import *
import tkinter.messagebox
import numpy as np
# 检查鼠标点击是否落在方格中,如果是,返回有效坐标
def limit(event):
global mark
if mark == 0:
for y in range(0, 18):
for x in range(0, 18):
if (event.x - 40 - 40 * x) ** 2 + (event.y - 40 - 40 * y) ** 2 <= 200:
return [x, y]
return [-1, 0]
# 从limit函数中获得鼠标点击的坐标,在该坐标处无放置棋子时,黑白轮流落子
def chess(event):
global num, mark
i, j = limit(event)
if i != -1: # 鼠标点击有效
if A[i][j] != 1:
A[i][j], B[i][j] = 1, 1 + num % 2
fill = 'black' if num % 2 == 0 else 'white'
w.create_oval(40 * i + 30, 40 * j + 30, 40 * i + 50, 40 * j + 50, fill=fill)
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]
count, x, y = 1, i, j
# 统计连线棋子数量,分别从当前棋子向连线的两个方向进行统计,中间不能间断
while 1:
if 0 <= x + a < 18 and 0 <= y + b < 18 and B[x + a][y + b] == B[i][j]:
[x, y] = np.array([x, y]) + np.array([a, b])
count += 1
else:
x, y = i, j
break
while 1:
if 18 > x - a >= 0 and 18 > y - b >= 0 and B[x - a][y - b] == B[i][j]:
[x, y] = np.array([x, y]) - np.array([a, b])
count += 1
else:
break
if count >= 5:
mark = 1
if B[i][j] == 1:
tkinter.messagebox.showinfo('提示', '黑棋获胜')
else:
tkinter.messagebox.showinfo('提示', '白棋获胜')
# 重新开始
def again():
global num, mark
w.delete("all")
num, mark = 0, 0
for i in range(18):
for j in range(18):
A[i][j], B[i][j] = 0, 0 # 清零
for k in range(0, 19): # 重新画线
w.create_line(k * 40 + 20, 20, k * 40 + 20, 740)
w.create_line(20, k * 40 + 20, 740, k * 40 + 20)
if __name__ == "__main__":
root = Tk() # 创建窗口
root.title("填子游戏") # 窗口名字
w = Canvas(root, width=760, height=760, background='grey')
w.pack() # 在窗口中央创建一个画布
for n in range(0, 19): # 重新画线
w.create_line(n * 40 + 20, 20, n * 40 + 20, 740)
w.create_line(20, n * 40 + 20, 740, n * 40 + 20)
num, mark = 0, 0
A, B = np.zeros((18, 18)), np.zeros((18, 18))
w.bind(", chess)
w.pack()
button = Button(root, text="重新开始", width=10, height=1, command=again, font=('楷体', 15)).pack()
mainloop()