一个游戏半成品代码,关键字六边形、蜂巢、两点间最短距离、BFS简单应用。

不会弄啥,一个20多年前学计算机的大叔。

这是一个7乘7的六边形蜂巢棋盘,默认应该有随机的障碍物,然后初始猫在中心点,正常是做一个你点击格子,增加障碍物,猫行走的策略是最快离开棋盘。每局你有10次机会点击。看能不能堵住猫。

很老的游戏了,最近捅咕python玩。

做了一个半成品,代码都是某言给的。

目前没有优化,边查边学边做。可能对于高手几分钟就能完成的。

很多代码都是无用的冗余的。

放上来给初学者做个参考,毕竟是一个能跑起来的东西了。

目前只能手动设置障碍物,然后计算猫到每个点的距离。最简单的BFS。

也可以设置猫的位置,然后重新计算。

坐标系参考了本站的一位大佬,把坐标系改一下 很好玩。

蜂窝地图研究_蜂窝路径算法-CSDN博客

但是由于这个坐标系不是正常的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()
    
 

  • 21
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值