【python A* pygame 格式化 自定义起点、终点、障碍】
- pip install pygame
test.py(chatgpt版本)
- 空格键:运行 A* 算法。
Ctrl+C
键:清空路径。Ctrl+S
键:保存当前地图到map.json
文件。Ctrl+L
键:从map.json
文件加载地图。
import pygame
import json
from queue import PriorityQueue
from tkinter import messagebox, Tk# Initialize pygame
pygame.init()# Constants
WIDTH, HEIGHT = 800, 800
ROWS, COLS = 40, 40
CELL_SIZE = WIDTH // COLS
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
GREY = (200, 200, 200)# Pygame setup
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("A* Pathfinding Visualization")class Spot:def __init__(self, row, col):self.row = rowself.col = colself.x = row * CELL_SIZEself.y = col * CELL_SIZEself.color = WHITEself.neighbors = []def is_closed(self):return self.color == REDdef is_open(self):return self.color == YELLOWdef is_barrier(self):return self.color == BLACKdef is_start(self):return self.color == BLUEdef is_end(self):return self.color == GREENdef reset(self):self.color = WHITEdef make_start(self):self.color = BLUEdef make_closed(self):self.color = REDdef make_open(self):self.color = YELLOWdef make_barrier(self):self.color = BLACKdef make_end(self):self.color = GREENdef make_path(self):if not self.is_start() and not self.is_end():self.color = GREYdef draw(self, win):pygame.draw.rect(win, self.color, (self.x, self.y, CELL_SIZE, CELL_SIZE))def update_neighbors(self, grid):self.neighbors = []if (self.row < ROWS - 1 and not grid[self.row + 1][self.col].is_barrier()): # Downself.neighbors.append(grid[self.row + 1][self.col])if self.row > 0 and not grid[self.row - 1][self.col].is_barrier(): # Upself.neighbors.append(grid[self.row - 1][self.col])if (self.col < COLS - 1 and not grid[self.row][self.col + 1].is_barrier()): # Rightself.neighbors.append(grid[self.row][self.col + 1])if self.col > 0 and not grid[self.row][self.col - 1].is_barrier(): # Leftself.neighbors.append(grid[self.row][self.col - 1])def __lt__(self, other):return False# Utility functions
def h(p1, p2):x1, y1 = p1x2, y2 = p2return abs(x1 - x2) + abs(y1 - y2)def reconstruct_path(came_from, current, draw):while current in came_from:current = came_from[current]current.make_path()draw()def make_grid():return [[Spot(i, j) for j in range(COLS)] for i in range(ROWS)]def draw_grid_line(win):for i in range(ROWS):pygame.draw.line(win, GREY, (0, i * CELL_SIZE), (WIDTH, i * CELL_SIZE))for j in range(COLS):pygame.draw.line(win, GREY, (j * CELL_SIZE, 0), (j * CELL_SIZE, HEIGHT))def draw(win, grid):win.fill(WHITE)for row in grid:for spot in row:spot.draw(win)draw_grid_line(win)pygame.display.update()def get_clicked_pos(pos):y, x = posrow = y // CELL_SIZEcol = x // CELL_SIZEif 0 <= row < ROWS and 0 <= col < COLS:return row, colreturn None, Nonedef clear_grid(grid):for row in grid:for spot in row:if not (spot.is_start() or spot.is_end() or spot.is_barrier()):spot.reset()def save_grid(grid, filename="map.json"):data = {"start": None, "end": None, "barriers": []}for row in grid:for spot in row:if spot.is_start():data["start"] = (spot.row, spot.col)elif spot.is_end():data["end"] = (spot.row, spot.col)elif spot.is_barrier():data["barriers"].append((spot.row, spot.col))try:with open(filename, "w", encoding="utf-8") as f:json.dump(data, f, indent=4, ensure_ascii=False)Tk().withdraw()messagebox.showinfo("Save Successful", "The grid has been saved successfully.")print("Save Successful", "The grid has been saved successfully.")except Exception as e:Tk().withdraw()messagebox.showerror("Save Error", f"Error saving grid: {e}")print(f"Error saving grid: {e}")def load_grid(grid, filename="map.json"):try:with open(filename, "r", encoding='utf-8') as f:data = json.load(f)for row in grid:for spot in row:spot.reset()if data["start"]:start_row, start_col = data["start"]grid[start_row][start_col].make_start()if data["end"]:end_row, end_col = data["end"]grid[end_row][end_col].make_end()for barrier in data["barriers"]:barrier_row, barrier_col = barriergrid[barrier_row][barrier_col].make_barrier()Tk().withdraw()messagebox.showinfo("Load Successful", "The grid has been loaded successfully.")print('Load Successful", "The grid has been loaded successfully.')except (FileNotFoundError, KeyError, json.JSONDecodeError):Tk().withdraw()messagebox.showerror("Load Error", "Error loading grid: Invalid or missing map file.")print("Error loading grid: Invalid or missing map file.")# A* Algorithm
def a_star(draw, grid, start, end):if not start or not end or start == end:print("Error: Invalid start or end node.")return Falsecount = 0open_set = PriorityQueue()open_set.put((0, count, start))came_from = {}g_score = {spot: float("inf") for row in grid for spot in row}g_score[start] = 0f_score = {spot: float("inf") for row in grid for spot in row}f_score[start] = h((start.row, start.col), (end.row, end.col))open_set_hash = {start}while not open_set.empty():for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()current = open_set.get()[2]open_set_hash.remove(current)if current == end:current.make_end()reconstruct_path(came_from, end, draw)return Truefor neighbor in current.neighbors:temp_g_score = g_score[current] + 1if temp_g_score < g_score[neighbor]:came_from[neighbor] = currentg_score[neighbor] = temp_g_scoref_score[neighbor] = temp_g_score + h((neighbor.row, neighbor.col), (end.row, end.col))if neighbor not in open_set_hash:count += 1open_set.put((f_score[neighbor], count, neighbor))open_set_hash.add(neighbor)neighbor.make_open()draw()if current != start:current.make_closed()return False# Main function
def main(win):grid = make_grid()start = Noneend = Nonerunning = Truewhile running:draw(win, grid)for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseif pygame.mouse.get_pressed()[0]: # Left mouse buttonpos = pygame.mouse.get_pos()row, col = get_clicked_pos(pos)if row is not None and col is not None:spot = grid[row][col]if not start and spot != end:start = spotstart.make_start()elif not end and spot != start:end = spotend.make_end()elif spot != start and spot != end:spot.make_barrier()elif pygame.mouse.get_pressed()[2]: # Right mouse buttonpos = pygame.mouse.get_pos()row, col = get_clicked_pos(pos)if row is not None and col is not None:spot = grid[row][col]spot.reset()if spot == start:start = Noneelif spot == end:end = Noneif event.type == pygame.KEYDOWN:print(f"KEYDOWN")if event.key == pygame.K_SPACE and start and end:clear_grid(grid)for row in grid:for spot in row:spot.update_neighbors(grid)a_star(lambda: draw(win, grid), grid, start, end)if event.key == pygame.K_c:print("press ctrl+c")clear_grid(grid)if event.key == pygame.K_s:print("press ctrl+s")save_grid(grid)if event.key == pygame.K_l:print("press ctrl+l")load_grid(grid)pygame.quit()main(WIN)
相关文章:

【python A* pygame 格式化 自定义起点、终点、障碍】
- pip install pygame test.py(chatgpt版本) 空格键:运行 A* 算法。CtrlC 键:清空路径。CtrlS 键:保存当前地图到 map.json 文件。CtrlL 键:从 map.json 文件加载地图。 import pygame import json from queue import PriorityQ…...
12_Redis发布订阅
1.Redis发布订阅介绍 1.1 基本概念 Redis的发布订阅(Pub/Sub)是一种消息通信模式,允许消息的发布者(Publisher)将消息发布到一个或多个频道(Channel),订阅者(Subscriber)通过订阅这些频道来接收消息。 发布者(Publisher):发送消息的一方,使用PUBLISH命令将消息…...

归并排序:数据排序的高效之道
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…...

【redis初阶】浅谈分布式系统
目录 一、常见概念 1.1 基本概念 2.2 评价指标(Metric) 二、架构演进 2.1 单机架构 2.2 应用数据分离架构 2.3 应用服务集群架构 2.4 读写分离/主从分离架构 2.5 引入缓存 ⸺ 冷热分离架构 2.6 数据库分库分表 2.7 业务拆分 ⸺ 引入微服务 redis学习&…...

CatLog的使用
一 CatLog的简介 1.1 作用 CAT(Central Application Tracking) 是基于 Java 开发的实时应用监控平台,为美团点评提供了全面的实时监控告警服务。 1.2 组成部分 1.2.1 Transaction 1.Transaction 适合记录跨越系统边界的程序访问行为&a…...
头歌python实验:网络安全应用实践-恶意流量检测
第1关:re 库的使用 本关任务:编写一个能正则匹配出 ip 地址的小程序。 re 的主要功能函数 常用的功能函数包括: compile、search、match、split、findall(finditer)、sub(subn)。 re.search 函数 re.search 扫描整个字符串并返回第一个成功的匹配。 函数语法: re…...

大模型WebUI:Gradio全解11——Chatbots:融合大模型的多模态聊天机器人(2)
大模型WebUI:Gradio全解11——Chatbots:融合大模型的聊天机器人(2) 前言本篇摘要11. Chatbot:融合大模型的多模态聊天机器人11.2 使用流行的LLM库和API11.2.1 Llama Index11.2.2 LangChain11.2.3 OpenAI1. 基本用法2. …...

如何用 Python 实现简单的 AI 模型?
💖 欢迎来到我的博客! 非常高兴能在这里与您相遇。在这里,您不仅能获得有趣的技术分享,还能感受到轻松愉快的氛围。无论您是编程新手,还是资深开发者,都能在这里找到属于您的知识宝藏,学习和成长…...

单片机-直流电机实验
1、ULN2003芯片介绍 ULN2003, 该芯片是一个单片高电压、高电流的达林顿晶体管阵列集成电路。不仅可以用来 驱动直流电机,还可用来驱动五线四相步进电机。支持驱动大功率电器 因为 ULN2003 的输出是集电极开路,ULN2003 要输出高电平࿰…...
python【数据结构】
1. 列表 Python 中列表是可变的,这是它区别于字符串和元组的最重要的特点;即,列表可以修改,而字符串和元组不能。 以下是 Python 中列表的方法: 方法描述list.append(x)把一个元素添加到列表的结尾,相当…...

详解Sonar与Jenkins 的集成使用!
本文阅读前提 本文假设读者熟悉Jenkins和SonarQube的基础操作。 核心实现功能 Jenkins中运行的job来调用SonarScanner,最后可实现测试结果与SonarQube中同步查看。 Jenkins中安装Sonar相关插件 配置Sonarqube Dashboard>Manage Jenkins>Systems 指定son…...

《笔记》青蛙跳台阶——斐波那契数列
斐波那契数列 斐波那契数列(Fibonacci Sequence)是一个经典的数学数列,其特点是每一项都是前两项的和。数列的前两项通常定义为 0 和 1(或 1 和 1),后续每一项都是前两项的和。 斐波那契数列的定义 斐波那…...

SpringBoot3动态切换数据源
背景 随着公司业务战略的发展,相关的软件服务也逐步的向多元化转变,之前是单纯的拿项目,赚人工钱,现在开始向产品化\服务化转变。最近雷袭又接到一项新的挑战:了解SAAS模型,考虑怎么将公司的产品转换成多租…...

OSPF - 特殊区域
OSPF路由器需要同时维护域内路由、域间路由、外部路由信息数据库。当网络规模不断扩大时,LSDB规模也不断增长。如果某区域不需要为其他区域提供流量中转服务,那么该区域内的路由器就没有必要维护本区域外的链路状态数据库。 OSPF通过划分区域可以减少网…...
Linux 系统下磁盘相关指令:df、du、fdisk、lsblk
文章目录 I df、du、fdisk、lsblk指令df命令用于显示文件系统的磁盘空间使用情况du命令用于估算目录或文件的磁盘空间使用情况fdisk命令用于对磁盘进行分区操作lsblk指令查看设备信息II 应用du估算目录或文件的磁盘空间使用情况lsblk查看服务器上查看硬盘个数III 知识扩展磁盘阵…...
基于单片机的肺功能MVV简单测算
肺功能MVV一般是指肺部每分钟的最大通气量。 MVV本身是最大值的英文缩写,在临床上,肺功能MVV表示肺部每分钟最大通气量,用以衡量气道的通畅度,以及肺部和胸廓的弹性、呼吸肌的力量。 肺部每分钟的最大通气量的参考值男性与女性之…...

如何用Python编程实现自动整理XML发票文件
传统手工整理发票耗时费力且易出错,而 XML 格式发票因其结构化、标准化的特点,为实现发票的自动化整理与保存提供了可能。本文将详细探讨用python来编程实现对 XML 格式的发票进行自动整理。 一、XML 格式发票的特点 结构化数据:XML 格式发票…...

腾讯云AI代码助手编程挑战赛-百事一点通
作品简介 百事通问答是一款功能强大的智能问答工具。它依托海量知识储备,无论你是想了解生活窍门、学习难点,还是工作中的专业疑惑,只需输入问题,就能瞬间获得精准解答,以简洁易懂的方式呈现,随时随地为你…...
Spring学习笔记1
目录 1 什么是spring2 spring的优势3 IOC的概念和作用3.1 无参数构造函数的实例化方式3.2 使用工厂中的普通方法实例化对象 4 Bean4.1 Bean相关概念4.2 Bean对象的作用范围 5 DI5.1 构造函数注入5.2 set方法注入5.3 复杂类型数据注入5.4 基于注解的IOC5.4.1 包扫描5.4.2 Compon…...
LeetCode 2185. Counting Words With a Given Prefix
🔗 https://leetcode.com/problems/counting-words-with-a-given-prefix 题目 给一个字符串数组,返回其中前缀为 pref 的个数 思路 模拟 代码 class Solution { public:int prefixCount(vector<string>& words, string pref) {int count…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...

push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...

企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...
TCP/IP 网络编程 | 服务端 客户端的封装
设计模式 文章目录 设计模式一、socket.h 接口(interface)二、socket.cpp 实现(implementation)三、server.cpp 使用封装(main 函数)四、client.cpp 使用封装(main 函数)五、退出方法…...
Windows 下端口占用排查与释放全攻略
Windows 下端口占用排查与释放全攻略 在开发和运维过程中,经常会遇到端口被占用的问题(如 8080、3306 等常用端口)。本文将详细介绍如何通过命令行和图形化界面快速定位并释放被占用的端口,帮助你高效解决此类问题。 一、准…...

Linux操作系统共享Windows操作系统的文件
目录 一、共享文件 二、挂载 一、共享文件 点击虚拟机选项-设置 点击选项,设置文件夹共享为总是启用,点击添加,可添加需要共享的文件夹 查询是否共享成功 ls /mnt/hgfs 如果显示Download(这是我共享的文件夹)&…...