一、简介

两点之间寻找最短路径,要考虑到存在障碍物遮挡和斜线移动的情况。

二、具体说明

说明可以参考下面的链接,对A*算法实现的描述。

三、具体实现

1、实现功能

2、寻路具体流程

3、关于F值

f = g + h

g表示当前移动到下一个点的消耗,平移为1,斜移动为 sqrt((x1-x2)**2 +(y1-y2)**2);

h表示当前移动到终点的消耗,不考虑斜移,不考虑障碍物

具体原理请查看下面的参考链接。

完整实现:

# -*- coding: utf-8 -*-

import os,sys,random,math

#地图设置

gameMapWidth = 10

gameMapHeight = 10

gameMap = []

#地图障碍物

obstacleCount = 5

#块状态

ITEM_STAT_NORMAL = 0 #空点

ITEM_STAT_OBSTACLE = 1 #障碍物

ITEM_STAT_START = 2 #起点

ITEM_STAT_END = 3 #终点

#起点和终点

spNum = -1

epNum = -1

#每块的属性

class Item:

def __init__(self,x,y,status):

self.x = x

self.y = y

self.status = status

self.mf = -1

self.mg = -1

self.mh = -1

self.mParent = None

self.isPath = 0

#初始化地图

def initMap():

for wc in xrange(gameMapWidth):

for hc in xrange(gameMapHeight):

gameMap.append(Item(wc,hc,ITEM_STAT_NORMAL))

#插入障碍物

for oc in xrange(obstacleCount):

choose = random.randint(gameMapWidth,gameMapWidth*gameMapHeight - 1)

gameMap[choose].status = ITEM_STAT_OBSTACLE

global spNum

global epNum

#选取起点和终点

while (spNum == -1):

choose = random.randint(0,gameMapWidth*gameMapHeight - 1)

if gameMap[choose].status == 0:

spNum = choose

gameMap[spNum].status = ITEM_STAT_START

while (epNum == -1):

choose = random.randint(0,gameMapWidth*gameMapHeight - 1)

if gameMap[choose].status == 0:

epNum = choose

gameMap[epNum].status = ITEM_STAT_END

#输出地图信息

def printMap():

for itemc in xrange(len(gameMap)):

if gameMap[itemc].status == ITEM_STAT_START:

print "START",

elif gameMap[itemc].status == ITEM_STAT_END:

print "END ",

elif gameMap[itemc].isPath == 1:

print "path ",

else:

print "%d " %(gameMap[itemc].status),

if (itemc + 1) % gameMapHeight == 0:

print "\n"

#寻路

def findPath():

global spNum

global epNum

#开启列表

openPointList = []

#关闭列表

closePointList = []

#开启列表插入起始点

openPointList.append(gameMap[spNum])

while (len(openPointList) > 0):

#寻找开启列表中最小预算值的点

minFPoint = findPointWithMinF(openPointList)

#从开启列表移除,添加到关闭列表

openPointList.remove(minFPoint)

closePointList.append(minFPoint)

#找到当前点周围点

surroundList = findSurroundPoint(minFPoint,closePointList)

#开始寻路

for sp in surroundList:

#存在在开启列表,说明上一块查找时并不是最优路径,考虑此次移动是否是最优路径

if sp in openPointList:

newPathG = CalcG(sp, minFPoint) #计算新路径下的G值

if newPathG < sp.mg:

sp.mg = newPathG

sp.mf = sp.mg + sp.mh

sp.mParent = minFPoint

else:

sp.mParent = minFPoint #当前查找到点指向上一个节点

CalcF(sp, gameMap[epNum])

openPointList.append(sp)

if gameMap[epNum] in openPointList:

gameMap[epNum].mParent = minFPoint

break

curp = gameMap[epNum]

while True:

curp.isPath = 1

curp = curp.mParent

if curp == None:

break

print "\n"

printMap()

def CalcG(point, minp):

return math.sqrt((point.x - point.mParent.x)**2 + (point.y - point.mParent.y)**2) + minp.mg

#计算每个点的F值

def CalcF(point,endp):

h = abs(endp.x - point.x) + abs(endp.y - point.y)

g = 0

if point.mParent == None:

g = 0

else:

g = point.mParent.mg + math.sqrt((point.x - point.mParent.x)**2 + (point.y - point.mParent.y)**2)

point.mg = g

point.mh = h

point.mf = g + h

return

#不能是障碍块,不包含在关闭列表中

def notObstacleAndClose(point,closePointList):

if point not in closePointList and point.status != ITEM_STAT_OBSTACLE:

return True

return False

#查找周围块

def findSurroundPoint(point,closePointList):

surroundList = []

up = None

down = None

left = None

right = None

leftUp = None

rightUp = None

leftDown = None

rightDown = None

#上面的点存在

if point.x > 0:

up = gameMap[gameMapHeight*(point.x - 1) + point.y]

if notObstacleAndClose(up,closePointList):

surroundList.append(up)

#下面的点存在

if point.x < gameMapWidth - 1:

down = gameMap[gameMapHeight*(point.x + 1)+ point.y]

if notObstacleAndClose(down,closePointList):

surroundList.append(down)

#左边的点存在

if point.y > 0:

left = gameMap[gameMapHeight*(point.x) + point.y - 1]

if notObstacleAndClose(left, closePointList):

surroundList.append(left)

#右边的点存在

if point.y < gameMapHeight - 1:

right = gameMap[gameMapHeight*(point.x) + point.y + 1]

if notObstacleAndClose(right,closePointList):

surroundList.append(right)

#斜方向的点还需考虑对应正方向不是障碍物

#左上角的点存在

if point.x > 0 and point.y > 0:

leftUp = gameMap[gameMapHeight*(point.x - 1) + point.y - 1]

if notObstacleAndClose(leftUp,closePointList) and left.status != ITEM_STAT_OBSTACLE and up.status != ITEM_STAT_OBSTACLE:

surroundList.append(leftUp)

#右上角的点存在

if point.x > 0 and point.y < gameMapHeight - 1:

rightUp = gameMap[gameMapHeight*(point.x-1) + point.y + 1]

if notObstacleAndClose(rightUp,closePointList) and right.status != ITEM_STAT_OBSTACLE and up.status != ITEM_STAT_OBSTACLE:

surroundList.append(rightUp)

#左下角的点存在

if point.x < gameMapWidth - 1 and point.y > 0:

leftDown = gameMap[gameMapHeight*(point.x+1) + point.y - 1]

if notObstacleAndClose(leftDown,closePointList) and left.status != ITEM_STAT_OBSTACLE and down.status != ITEM_STAT_OBSTACLE:

surroundList.append(leftDown)

#右下角的点存在

if point.x < gameMapWidth - 1 and point.y < gameMapHeight - 1:

rightDown = gameMap[gameMapHeight*(point.x+1) + point.y + 1]

if notObstacleAndClose(rightDown,closePointList) and right.status != ITEM_STAT_OBSTACLE and down.status != ITEM_STAT_OBSTACLE:

surroundList.append(rightDown)

return surroundList

#查找list中最小的f值

def findPointWithMinF(openPointList):

f = 0xffffff

temp = None

for pc in openPointList:

if pc.mf < f:

temp = pc

f = pc.mf

return temp

def main():

initMap() ##初始化地图

printMap() ##输出初始化地图信息

findPath() ##查找最优路径

#入口

main()

参考:

https://www.gamedev.net/articles/programming/artificial-intelligence/a-pathfinding-for-beginners-r2003/

https://blog.csdn.net/qq_33747722/article/details/78436919

python游戏寻路_python模拟实现A*寻路算法相关推荐

  1. python 游戏开发_Python游戏开发入门

    spContent=--玩游戏的最高境界是什么? --当然是设计一款属于自己的游戏! --设计游戏不是目的,从游戏看道理,从道理看人生,人生何尝不是属于自己的游戏? --"弹指之间·享受创新 ...

  2. python 游戏扫雷_Python游戏:扫雷

    原标题:Python游戏:扫雷 本文代码基于 python3.6 和 pygame1.9.4. 这次,我们来模仿做一个 XP 上的扫雷,感觉 XP 上的样式比 win7 上的好看多了. 原谅我手残,扫 ...

  3. python kmeans聚类_python机器学习之k-means聚类算法(1)

    k-means算法是一种无监督的机器学习算法,虽然是机器学习,但它简单易于实现.本篇采用python语言,自主编程实现k-menas算法,当然python用专门的库函数来实现该算法,但本次主要使用该算 ...

  4. python设计抽奖游戏 球_Python模拟轮盘抽奖游戏

    题目如下: 模拟轮盘抽奖游戏 轮盘分为三部分: 一等奖, 二等奖和三等奖; 轮盘转的时候是随机的, 模拟本次活动1000人参加, 模拟游戏时需要准备各等级奖品的个数. #方法1: import ran ...

  5. python游戏后端_Python实现生命游戏

    1. 生命游戏是什么 生命游戏是英国数学家约翰·何顿·康威在1970年发明的细胞自动机.它包括一个二维矩形世界,这个世界中的每个方格居住着一个活着的或死了的细胞.一个细胞在下一个时刻生死取决于相邻八个 ...

  6. python刷新页面_Python模拟浏览器爬取天猫信息

    由于工作需要,需要提取到天猫400个指定商品页面中指定的信息,于是有了这个爬虫.这是一个使用 selenium 爬取天猫商品信息的爬虫,虽然功能单一,但是也算是 selenium 爬虫的基本用法了. ...

  7. python动态验证码_Python 模拟生成动态产生验证码图片的方法

    模拟动态产生验证码图片 模拟生成验证码,首先要做的是生成随机的字母,然后对字母进行模糊处理.这里介绍一下 Python 提供的 Pillow 模块. Pillow PIL:Python Image L ...

  8. python http请求_python模拟http请求

    #!coding:utf-8 相信这句大家都懂的,不解释 #导入需要的python模块httplib,用来模拟提交http请求,详细的用法可见python帮助手册 importhttplib#导入需要 ...

  9. python 区块链_Python 模拟简单区块链

    另外还要说明一下,暑假指导老师让我们做一些关于区块链的应用.这里只是涉及极其简单的模拟,主要是记录这些天自己学习的知识. 什么是区块链? 下面简单说一下区块链是什么,做个比喻,区块就像一个人,区块链好 ...

  10. python太阳代码_Python模拟太阳

    作者 | Charles,cv方向在读研究生.[Charles 的皮卡丘]专注于分享有趣好玩的Python小项目(AI.爬虫等等). 来源 |微信公众号" Charles 的皮卡丘" ...

最新文章

  1. kingadmin页面开发
  2. java线程顺序输出_多线程按顺序输出ABC
  3. npm更新模块并同步到package.json中
  4. python面向对象的三个基本特征 含义和作用简介_面向对象语言的三个基本特征各自特点及优势...
  5. JSP include指令和include动作的区别
  6. OPENSSL X509证书验证
  7. 关于echarts的疑问
  8. 如何更好地优化大数据分析
  9. CheckBoxPreference组件
  10. 【HUSTOJ】1054: 字符图形10-字母三角
  11. 用python写邮件和附件自动生成发送系统
  12. 一个微信投票小程序防止刷票的想法
  13. 重启Oracle数据库的操作步骤
  14. 微信小程序学习(三):在微信开发者工具中,使用WeUI前端美化框架,微信小程序
  15. mysql 获取农历年份_iOS 获取公历、农历日期的年月日
  16. 九度OJ 1177:查找 (字符串操作)
  17. python红楼梦词频统计_Python 红楼梦的字频与词频统计
  18. 基于J2EE架构的在线考试系统-Java(报告+源码+PPT
  19. 徐盛:软件测试新趋势从超人时代到智慧测试时代
  20. 嵌入式学习笔记--misc

热门文章

  1. Firefox 火狐下自动刷新的插件 ReloadEvery
  2. iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 3306 -j DNAT --to-destinatio
  3. bingo卡片js代码_Excel Bingo卡随机数代码
  4. 多线程基础之四:Linux提供的原子锁类型atomic_t
  5. 彻底理解样本方差为何除以n-1
  6. plsql报错:Not logged on
  7. 双远心镜头原理及选型方法(二)
  8. dxf制作kml_kml到dxf
  9. Addressing Failure Prediction by Learning Model Confidence
  10. 用python程序计算勾股数,用Python程序计算勾股数