A*算法 cocos2dx 8数码

入门讲解(下面是一篇英文入门,最经典,需要好好看)

http://www.policyalmanac.org/games/aStarTutorial.htm

网上的各种文章 只能参考,不可尽信(本文代码不是很好,可以参看学习,也可能错误,所以自己实践检验,Debug一步步看)


本文地址:http://blog.csdn.net/qq_26437925/article/details/52049011


输入 m n 每个位置的值

1 不可走

0 可走

2 起点

3 终点

样例输入

4 4
0 0 1 0
2 1 0 3
0 0 1 0
1 0 0 0


6 5
0 0 0 0 0
0 0 1 0 0
2 0 1 0 3
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0


可采用freopen("in.txt", "r", stdin); 进行文本输入,因为自己写的,所以自己定义了结果,主要是学习Astar 算法流程


#include <cstdio>
#include <cmath>
#include <iostream>
#include <vector>
#include <queue>
#include <map>
#include <list>
#include <iterator>
using namespace std;

const int INF = 0x7fffffff;
const int N = 100;

int m, n;

int po[N][N];

int stai, staj;
int endi, endj;

int dir[4][2] =
{
	{ 0, 1 },   // East
	{ 1, 0 },   // South
	{ 0, -1 },  // West
	{ -1, 0 },  // North
};

bool isRightPos(int i, int j)
{
	if (i >= 0 && i < m && j >= 0 && j < n)
		return true;
	return false;
}

int fa[N][N];//父节点
int f[N][N];//f值
int g[N][N];//g值
int h[N][N];//h值
bool canReach[N][N];//是否是可以走

int distance(int x1, int y1, int x2, int y2)
{
	return (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2);
}

map<int, int> rs;// 存储路径,包括起点和终点

void astar()
{
	map<int, int> open;//open表
	map<int, int> close;//close表
	open.clear();
	close.clear();

	open[stai*m + staj] = 0;
	
	while (!open.empty()) 
	{
		// 取得open表的最小值
		map<int, int>::iterator it = open.begin();
		map<int, int>::iterator openMin;
		int minx, miny, minf = INF;
		while (it != open.end())
		{
			if (it->second < minf)
			{
				minf = it->second;
				minx = it->first / m;
				miny = it->first % m;
				openMin = it;
			}
			it++;
		}
		
		// 到达终点 处理结果
		if (minx == endi && miny == endj)
		{
			int fx= endi;
			int fy = endj;
			rs[endi*m + endj] = 1;
			int tmpx = endi, tmpy = endj;
			while ( (tmpx != stai) || (tmpy!= staj))
			{
				fx = fa[tmpx][tmpy] / m;
				fy = fa[tmpx][tmpy] % m ;
				tmpx = fx;
				tmpy = fy;
				//printf("%d %d\n", endi, endj);
				rs[tmpx*m + tmpy] = 1;
			}
			break;
		}

		// 遍历每个节点
		for (int i = 0; i < 4; i++)
		{
			int nx = minx + dir[i][0];
			int ny = miny + dir[i][1];

			// 节点不合理 或者 在close表中 不做处理
			if (!isRightPos(nx, ny) || !canReach[nx][ny] || close[nx*m + ny] != 0)
				continue;
			else{
				g[nx][ny] = distance(nx, ny, minx, miny);
				f[nx][ny] = g[nx][ny] + h[nx][ny];

				// 在open表中 需要比较f值
				if (open[nx*m + ny] != 0)
				{
					if (f[nx][ny] < open[nx*m + ny])
					{
						open[nx*m + ny] = f[nx][ny];
					}
				}else{ //直接加入到open表中
					fa[nx][ny] = minx * m + miny;
					open[nx*m + ny] = f[nx][ny];
				}
			}

		}

		close[minx*m + miny] = 1; //节点加入到close表中,并从open表中清除
		open.erase(openMin);
		//open[minx*m + miny] = 0;
	}// while
}

int main()
{
	freopen("in.txt", "r", stdin);
	int i, j;
	while (scanf("%d%d", &m, &n) != EOF)
	{
		for (i = 0; i < m; i++)
		{
			for (j = 0; j < n; j++)
			{
				scanf("%d", &po[i][j]);
				if (po[i][j] == 2)
				{
					stai = i;
					staj = j;
				}
				if (po[i][j] == 3)
				{
					endi = i;
					endj = j;
				}
				canReach[i][j] = true;
				if (po[i][j] == 1)
					canReach[i][j] = false;

			}
		}
<span style="white-space:pre">		</span>// h值可以先求出来,g值在atar算法过程中求解
		for (i = 0; i < m; i++)
		{
			for (j = 0; j < n; j++)
			{
				h[i][j] = distance(i, j, endi, endj);
			}
		}


		astar();

		char Symbol[5][3] = { "□", "▓", "▽", "☆", "◎" };
		for (i = 0; i < m; i++)
		{
			for (j = 0; j < n; j++)
			{
				if (rs[i*m + j] == 1)
				{

					if (i == stai && j == staj)//起点
						printf("%s", Symbol[2]);
					else if (i == endi && j == endj)//终点
						printf("%s", Symbol[3]);
					else
						printf("%s", Symbol[4]);//路径
				}
				else
				{
					if (po[i][j] == 1)
						printf("%s", Symbol[1]); //障碍
					else
						printf("%s", Symbol[0]);//可走
				}
			}
			printf("\n");
		}
		rs.clear();
	}
	return (0);
}


结果输出如上图所示


----------------------------------------------------------------------------------------------

cocos2dx 8数码小程序

https://github.com/doctording/cocos2dx_8digital


如下图,点击之后可以实现自动拼图


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值