博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
A* 算法理解与实现
阅读量:5107 次
发布时间:2019-06-13

本文共 5167 字,大约阅读时间需要 17 分钟。

F=G(已花费)+H(将花费);
 
G:直线花费10点。斜着走花费14点。
 
A* 算法的核心是,确定F花费最少的节点,并将节点记录下来。
1建立节点信息类,用以处理节点。
2确定初始节点 
 
Node
root =
new
Node
(start);
3利用BFS思想,确定可以拓展的节点
4.在确定可拓展节点前,拓展队列中最小花费的节点,作为将要拓展节点的父节点。(父节点唯一)
5.在可扩展节点处,实例新的节点信息,确定父节点,并计算当前节点的F、G、H值。(计算与终点的预估值H)(G为已花费)
核心在于F值的大小会影响优先级。
6,当节点坐标与终点坐标重合时,即找到目标,通过循环,将此线路的父节点压入栈中。
7.通过读取栈中的值,可以确定路线。
 
public
class
Node
{
   
//坐标
   
public
int
X, Y;
   
//消耗
   
public
int
F, G, H;
   
//父节点
   
public
Node
Parent;
   
//计算H值
   
public
void
CalculateH(
Vector2
end) {
       
this
.H = (
int
)(10 * (
Mathf
.Abs(end.x - X) +
Mathf
.Abs(end.y - Y)));
    }
   
public
void
CalculateF() {
       
this
.F =
this
.G +
this
.H;
    }
   
public
Node(
int
x,
int
y,
Node
parent=
null
) {
       
this
.X = x;
       
this
.Y = y;
       
this
.Parent = parent;
    }
   
public
Node(
Vector2
point,
Node
parent =
null
)
    {
       
this
.X =(
int
)point.x;
       
this
.Y = (
int
)point.y;
       
this
.Parent = parent;
    }
 
}
 
#region
Segment
   
public
static
Stack
<
Vector2
> path =
new
Stack
<
Vector2
>();
   
Vector2
start;
   
Vector2
end;
   
public
const
int
RowCount = 7;
   
public
const
int
ColCount = 9;
   
byte
[,] mapData =
new
byte
[RowCount, ColCount];
   
Transform
player;
   
Vector3
moveDir;
   
Vector3
targer;
   
#endregion
 
   
#region
Mothed
   
private
void
Start()
    {
       
//LoadMapData();
       
//CreateMap();
       
//GetStartEnd();
       
//BFS();
       
//player = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;
       
//player.transform.position = GetPosition(start);
       
//targer = GetPosition(path.Peek());
    }
 
   
public
void
Update()
    {
        moveDir = (targer - player.position).normalized;
        player.Translate(moveDir*
Time
.deltaTime);
       
if
(
Vector3
.Distance(player.transform.position,targer)<0.1f)
        {
            path.Pop();
           
if
(path.Count==0)
            {
               
this
.enabled =
false
;
            }
           
else
            {
            targer = GetPosition(path.Peek());
            }
        }
    }
 
   
//获取游戏数据
   
private
void
LoadMapData()
    {
       
string
path =
Application
.dataPath +
"/Map/map.txt"
;
       
StreamReader
sr =
new
StreamReader
(path);
       
string
result = sr.ReadToEnd();
       
string
[] data = result.Split(
new
string
[] {
"\r\n"
}, System.
StringSplitOptions
.None);
       
for
(
int
i = 0; i < RowCount; i++)
        {
           
for
(
int
j = 0; j < ColCount; j++)
            {
                mapData[i, j] =
byte
.Parse(data[i][j].ToString());
            }
        }
    }
 
   
//生成地图数据
   
public
void
CreateMap()
    {
       
GameObject
Roads =
new
GameObject
(
"Roads"
);
       
GameObject
red =
Resources
.Load(
"red"
,
typeof
(
GameObject
))
as
GameObject
;
       
GameObject
blue =
Resources
.Load(
"blue"
,
typeof
(
GameObject
))
as
GameObject
;
       
GameObject
yellow =
Resources
.Load(
"yellow"
,
typeof
(
GameObject
))
as
GameObject
;
       
for
(
int
i = 0; i < RowCount; i++)
        {
           
for
(
int
j = 0; j < ColCount; j++)
            {
               
GameObject
road =
null
;
               
switch
(mapData[i, j])
                {
                   
case
0:
                        road = Instantiate(red)
as
GameObject
;
                       
break
;
                   
case
1:
                        road =
GameObject
.CreatePrimitive(
PrimitiveType
.Cube);
                       
break
;
                   
case
2:
                        road = Instantiate(blue)
as
GameObject
;
                       
break
;
                   
case
9:
                        road = Instantiate(yellow)
as
GameObject
;
                       
break
;
                   
default
:
                        road =
GameObject
.CreatePrimitive(
PrimitiveType
.Cube);
                       
break
;
                }
                road.transform.SetParent(Roads.transform);
                road.transform.position = GetPosition(i, j);
                road.transform.localScale =
Vector3
.one * 0.8f;
                road.name = i.ToString() +
"_"
+ j.ToString();
            }
        }
    }
 
   
Vector3
GetPosition(
int
x,
int
y)
    {
       
int
pos_x = -RowCount / 3 + y;
       
int
pos_y = ColCount / 3 + x;
       
return
new
Vector3
(pos_x, 0, pos_y);
    }
   
Vector3
GetPosition(
Vector2
pos)
    {
       
int
pos_x = -RowCount / 3 + (
int
)pos.y;
       
int
pos_y = ColCount / 3 + (
int
)pos.x;
       
return
new
Vector3
(pos_x, 1, pos_y);
    }
   
void
GetStartEnd()
    {
       
for
(
int
i = 0; i < mapData.GetLength(0); i++)
        {
           
for
(
int
j = 0; j < mapData.GetLength(1); j++)
            {
               
if
(mapData[i, j] == 0)
                {
                    start.x = i;
                    start.y = j;
                }
               
else
if
(mapData[i, j] == 9)
                {
                    end.x = i;
                    end.y = j;
                   
Debug
.Log(
new
Vector2
(i, j));
                }
            }
        }
    }
 
   
List
<
Node
> list =
new
List
<
Node
>();
   
List
<
Node
> visited =
new
List
<
Node
>();
   
private
Vector2
[] dirs =
new
Vector2
[] {
Vector2
.up,
Vector2
.down,
Vector2
.left,
Vector2
.right,
new
Vector2
(1, 1),
new
Vector2
(-1, 1),
new
Vector2
(1, -1),
new
Vector2
(-1, -1) };
 
   
void
BFS()
    {
       
Node
root =
new
Node
(start);
        list.Add(root);
       
while
(list.Count > 0)
        {
           
//f值排序
            list.Sort(Comparer);
           
Node
node = list[0];
            list.Remove(node);
//移除
            visited.Add(node);
//添加访问节点
           
for
(
int
i = 0; i < dirs.Length; i++)
            {
               
Vector2
point;
                point.x = node.X + dirs[i].x;
                point.y = node.Y + dirs[i].y;
               
if
(IsOk(point))
                {
                   
Node
n =
new
Node
(point, node);
                    n.G = i > 3 ? node.G + 14 : node.G + 10;
                    n.CalculateH(end);
                    n.CalculateF();
                    list.Add(n);
                   
if
(point == end)
                    {
                       
Debug
.Log(
"find"
);
                       
Node
p = n;
                       
while
(p !=
null
)
                        {
                           
Debug
.Log(p.X +
"\t"
+ p.Y);
                            path.Push(
new
Vector2
(p.X,p.Y));
                            p = p.Parent;
                        }
                       
return
;
                    }
                }
            }
        }
    }
 
   
private
int
Comparer(
Node
x,
Node
y)
    {
       
if
(x.F == y.F)
        {
           
return
0;
//表示不交互位置
        }
       
else
if
(x.F > y.F)
        {
           
return
1;
//表示交互位置
        }
       
else
        {
           
return
-1;
//表示不交换位置
        }
    }
 
   
public
bool
IsOk(
Vector2
point)
    {
       
if
(point.x <= 0 || point.x >= mapData.GetLength(0) || point.y <= 0 || point.y >= mapData.GetLength(1))
        {
           
return
false
;
        }
       
if
(mapData[(
int
)point.x, (
int
)point.y] == 2)
        {
           
return
false
;
        }
       
for
(
int
i = 0; i < visited.Count; i++)
        {
           
if
(visited[i].X == point.x && visited[i].Y == point.y)
            {
               
return
false
;
            }
        }
       
for
(
int
i = 0; i < list.Count; i++)
        {
           
if
(list[i].X == point.x && list[i].Y == point.y)
            {
               
return
false
;
            }
        }
       
return
true
;
    }
   
#endregion

转载于:https://www.cnblogs.com/NoXing/p/5894364.html

你可能感兴趣的文章
pickle模块的基本使用
查看>>
leetcode 347. Top K Frequent Elements
查看>>
Python list 增加/插入元素的说明
查看>>
代码如何实现多线程
查看>>
Neo4j学习(3)--JavaAPI
查看>>
批量创建用户名
查看>>
Flask初识,第二篇
查看>>
Volley用法
查看>>
python unittest模块
查看>>
线段树和下移操作解决HDOJ 1698
查看>>
js 实现端口列表话
查看>>
java和js中不定项参数调用方法
查看>>
LIBSVM的使用方法
查看>>
Vxworks的一些基本概念
查看>>
转:vim 文件格式
查看>>
TsinghuaX: 00740043X C++语言程序设计基础 第二章提纲
查看>>
Arch最小化安装LXDE桌面环境
查看>>
第二期冲刺会议3
查看>>
JQuery案例:暖心小广告
查看>>
面向对象精要-构造函数和原型对象
查看>>