不会弄啥,一个20多年前学计算机的大叔。
这是一个7乘7的六边形蜂巢棋盘,默认应该有随机的障碍物,然后初始猫在中心点,正常是做一个你点击格子,增加障碍物,猫行走的策略是最快离开棋盘。每局你有10次机会点击。看能不能堵住猫。
很老的游戏了,最近捅咕python玩。
做了一个半成品,代码都是某言给的。
目前没有优化,边查边学边做。可能对于高手几分钟就能完成的。
很多代码都是无用的冗余的。
放上来给初学者做个参考,毕竟是一个能跑起来的东西了。
目前只能手动设置障碍物,然后计算猫到每个点的距离。最简单的BFS。
也可以设置猫的位置,然后重新计算。
坐标系参考了本站的一位大佬,把坐标系改一下 很好玩。
但是由于这个坐标系不是正常的xy,我在改变的时候没有用变量。棋盘如果不是7乘7的会错。
可能以后会优化一下代码吧
也可能过几天我就忘记这些代码都什么意思了,
但我这一刻是快乐的 哈
import tkinter as tk
import math
from collections import deque
import numpy as np
# 计算六边形的顶点坐标
def calculate_hexagon_vertices(x, y, size):
# 六边形中心为(x, y),size 为从中心到顶点的距离(半径)
# 从30度(π/6弧度)开始计算正六边形的顶点坐标
vertices = []
for i in range(6):
# 角度从 π/6 开始,每次增加 π/3
angle = math.pi / 6 + i * (math.pi / 3)
# 使用极坐标到直角坐标的转换
x_vertex = x + size * math.cos(angle)
y_vertex = y + size * math.sin(angle) # 注意这里用正号,因为我们从中心开始向上绘制
vertices.append((x_vertex, y_vertex))
return vertices
# Tkinter应用类
class HexBoardTkApp(tk.Tk):
liebiao=[]
def __init__(self, rows, cols, hex_size):
super().__init__()
self.title("Hexagonal Board in Tkinter")
self.geometry("800x800+0+0")
self.canvas = tk.Canvas(self, bg='white')
self.canvas.pack(fill=tk.BOTH, expand=True)
self.hex_size = hex_size
self.rows = rows
self.cols = cols
self.hex_vars = {} # 用于存储每个复选框的变量
self.text_ids = [] #存储每次显示距离的id
self.selected_index = None # 用于跟踪选中的圆形区域
self.buttons = {} # 存储圆形区域的ID和索引
# 绘制六边形棋盘和复选框
self.draw_hex_board(rows, cols, hex_size)
self.start_x = 4
self.start_y = 3
self.start_z = -1
self.mao=24 #初始化猫的序号24
# 创建一个按钮
self.button0 = tk.Button(self, text="测试第一版 输出liebiao", command=self.button_clicked)
self.button0.pack(side=tk.LEFT, padx=10, pady=10)
self.button1 = tk.Button(self, text="可用用于最基本的计算路程了", command=self.get_values_from_vars)
self.button1.pack(side=tk.LEFT, padx=10, pady=10)
self.button2 = tk.Button(self, text="目前无用了", command=self.delete_text)
self.button2.pack(side=tk.LEFT, padx=10, pady=10)
def delete_text(self):
for text_id in self.text_ids:
#print(f"text_id: {text_id} :")
self.canvas.delete(text_id) # 删除所有保存的文本项
self.text_ids.clear() # 清空文本项ID列表,准备添加新文本
def get_values_from_vars(self):
self.delete_text() #清除上次显示的距离
for data in HexBoardTkApp.liebiao: #判断是否在图形里选中
if data[7] ==1 :
data[9]=1
else :
data[9]=0
queue=deque([(self.start_x, self.start_y,self.start_z, 0)])
for data in HexBoardTkApp.liebiao:
if data[1] ==self.start_x and data[2]==self.start_y and data[3]==self.start_z:
print(f"starxyz({self.start_x},{self.start_y},{self.start_z})")
data[9]=1
break
while queue :
curr_x,curr_y,curr_z,dist=queue.popleft()
for nx,ny,nz in self.get_linju(curr_x,curr_y,curr_z):
for data in HexBoardTkApp.liebiao:
if data[1] ==nx and data[2]==ny and data[3]==nz and data[9]==0:
###print(f"xyz_{nx}_{ny}_{nz} :",str(data[9]))
new_dist=dist+1
xxx=data[11]
yyy=data[12]
text=str(new_dist)
text_id =self.canvas.create_text(xxx, yyy+30, text=text, fill='black', font=("Arial", 10))
self.text_ids.append(text_id) # 保存文本ID
queue.append((nx,ny,nz, new_dist))
data[9]=1
break
def get_linju(self,x,y,z):
linju=[]
for dx,dy,dz in[(+1,+1,0),(+1,0,-1),(0,-1,-1),(-1,-1,0),(-1,0,+1),(0,+1,+1)]:
nx,ny,nz=x+dx ,y+dy ,z+dz
for data in HexBoardTkApp.liebiao:
if data[1] ==nx and data[2]==ny and data[3]==nz and data[9]==0:
linju.append((nx,ny,nz))
return linju
def button_clicked(self):
# 按钮被点击时执行的函数
print("按钮被点击了!")
for item in HexBoardTkApp.liebiao:
print(item)
def draw_hex_board(self, rows, cols, hex_size):
# 初始化偏移量
x_offset = self.hex_size * 3 / 2 +50
y_offset = self.hex_size * math.sqrt(3) / 2 +160
index=0
# 遍历棋盘上的每个六边形
for row in range(rows):
for col in range(cols):
# 计算六边形的中心位置
if row % 2 == 0:
x = x_offset + col * hex_size * 3 / 2
else:
x = x_offset + (col + 0.5) * hex_size * 3 / 2 -75.5
y = y_offset + row * (hex_size * 3 / 2 - 7.5) # 这里修改为了3/2倍,因为六边形的高是边长的3/2*sqrt(3)
# 计算六边形顶点坐标
vertices = calculate_hexagon_vertices(x, y, hex_size-5)
# 绘制六边形
hex_tag = f"hex_{row}_{col}" # 为每个六边形创建一个唯一的标签
self.canvas.create_polygon(vertices, fill='#adaf66', outline='black', tags=hex_tag)
if row ==3 and col ==3 :
self.canvas.create_polygon(vertices, fill='red', outline='black', tags=hex_tag)
yy=abs(row - 6)
if yy >=0 :
xx=col
if yy >= 2:
xx=col +1
if yy >=4:
xx=col +2
if yy >= 6 :
xx=col +3
zz=yy-xx
index = col + abs(row - 6) *7
ii=index
text = f"({xx}, {yy},{zz}),{index}"
self.canvas.create_text(x, y+12, text=text, fill='black', font=("Arial", 10), tag=hex_tag)
# 创建复选框变量
var = tk.IntVar(value=0)
self.hex_vars[(row, col)] = var
# 在六边形中心创建复选框
checkbutton = tk.Checkbutton(self.canvas, text='', variable=var, onvalue=1, offvalue=0,
indicatoron=True, borderwidth=0, highlightthickness=0, bg='#adaf76',
command=lambda ii=index,xxx=x,yyy=y,siz=hex_size,t=text,r=row, c=col: self.on_checkbutton_click(r, c,t,siz,xxx,yyy,ii))
checkbutton_id = self.canvas.create_window(x, y - 10, window=checkbutton, anchor='c')
if index != 24 :
self.buttons[index] = self.canvas.create_oval(x+15, y-20, x +15+ 15, y-20 + 15, tags=f"button_{index}", fill='#adaf76')
else :
self.buttons[index] = self.canvas.create_oval(x+15, y-20, x +15+ 15, y-20 + 15, tags=f"button_{index}", fill='red')
# 绑定点击事件
self.canvas.tag_bind(f"button_{index}", "<Button-1>", lambda event, index=index: self.on_button_click1(index))
self.canvas.tag_raise(f"button_{index}")
meizushuju=[index,xx,yy,zz,'cow,col,var:',row,col,1 if row==3 and col==3 else 0,'Y/N bianli:',0,'xy坐标:',x,y,hex_size]
HexBoardTkApp.liebiao.append(meizushuju)
# (可选)在六边形中心绘制文本(如果需要的话)
# self.canvas.create_text(hex_center_x, hex_center_y, text=f"({row}, {col})", fill='black', font=("Arial", 12), tag=f"hex_{row}_{col}")
def on_button_click1(self, index):
# 如果之前已经选中了一个按钮,则取消其选中状态
print(f"Index clicked: {index}")
#print(f"Buttons dictionary: {self.buttons}")
if self.selected_index is not None and self.selected_index in self.buttons:
self.canvas.itemconfig(self.buttons[self.selected_index], fill='#adaf76')
else :
self.canvas.itemconfig(self.buttons[24], fill='#adaf76')
# 设置新的按钮为选中状态
self.selected_index = index
self.canvas.itemconfig(self.buttons[index], fill='red') # 假设选中状态为蓝色
self.canvas.tag_raise(f"button_{index}")
oldmao=self.mao
for data in HexBoardTkApp.liebiao: #设置新猫
if data[0] ==oldmao :#设置旧猫
a = calculate_hexagon_vertices(data[11], data[12], data[13]-5)
# 绘制六边形
self.canvas.create_polygon(a, fill='#adaf66', outline='black')
text = f"({data[1]}, {data[2]},{data[3]}),{data[0]}"
self.canvas.create_text(data[11], data[12]+12, text=text, fill='black', font=("Arial", 10))
self.canvas.itemconfig(self.buttons[oldmao], fill='#adaf76')
self.canvas.tag_raise(f"button_{oldmao}")
if data[0] ==24 :
data[7]=0
if data[0] ==index :
self.start_x = data[1]
self.start_y = data[2]
self.start_z = data[3]
a = calculate_hexagon_vertices(data[11], data[12], data[13]-5)
# 绘制六边形
self.canvas.create_polygon(a, fill='red', outline='black')
text = f"({data[1]}, {data[2]},{data[3]}),{data[0]}"
self.canvas.create_text(data[11], data[12]+12, text=text, fill='black', font=("Arial", 10))
self.mao=index
def on_checkbutton_click(self, row, col,text,siz,xxx,yyy,ii):
if ii==self.mao :
print("此处是猫,你想干嘛!")
else:
var = self.hex_vars[(row, col)]
if var.get() == 1:
# 计算六边形顶点坐标
a = calculate_hexagon_vertices(xxx, yyy, siz-5)
# 绘制六边形
self.canvas.create_polygon(a, fill='#75614e', outline='black')
self.canvas.create_text(xxx, yyy+12, text=text, fill='black', font=("Arial", 10))
print(f"虚拟坐标: {text} 被选取。",f"row,col 坐标为 ({row}, {col})",f"XY轴坐标为 ({xxx}, {yyy})",f"index为: ({ii})")
for data in HexBoardTkApp.liebiao:
if data[5] ==row and data[6]==col:
data[7]=1
data[9]=1
break
else:
a = calculate_hexagon_vertices(xxx, yyy, siz-5)
# 绘制六边形
self.canvas.create_polygon(a, fill='#adaf66', outline='black')
self.canvas.create_text(xxx, yyy+12, text=text, fill='black', font=("Arial", 10))
print(f"虚拟坐标: {text} 被取消。",f"row,col 坐标为 ({row}, {col})" )
self.canvas.itemconfig(self.buttons[ii], fill='#adaf76')
self.canvas.tag_raise(f"button_{ii}")
for data in HexBoardTkApp.liebiao:
if data[5] ==row and data[6]==col:
data[7]=0
data[9]=0
break
# 运行应用
if __name__ == "__main__":
app = HexBoardTkApp(7, 7, 50) # 7行7列的棋盘,每个六边形边长为50
app.mainloop()