一步一步写算法(之寻路)

原文:一步一步写算法(之寻路)

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

    寻路是游戏设计中需要使用到一种功能,那么我们怎么样以一个点作为起始点,快速地寻找到目标点呢?其实寻路的方法不难。一种简单有效的方法就是回溯法。如果我们从一个点出发,那么这个点周围肯定有若干条路,只要有一条路存在,我们就一直走下去,直到发现没有路走为止;要是发现路走不下去了怎么办,那就只好回头了,我们只能从剩下的选项中继续选择一条路,继续尝试。如果很不幸,所有的尝试都结束了,还是没有发现目标节点,那只能说明,我们真的无路可走。

    a)首先,我们用矩阵表示地图:其中1表示路,0表示没有路,2表示终点,起始地点为(1,0)

#define MAX_NUMBER_LENGTH 6

static int gPath[MAX_NUMBER_LENGTH][MAX_NUMBER_LENGTH] = {
	{0 , 0, 0, 0, 1, 1},
	{1,  1, 0, 0, 1, 0},
	{0 , 1, 1, 1, 1, 0},
	{0 , 0, 1, 0, 1, 2},
	{0 , 0, 1, 0, 1, 0},
	{0 , 0, 1, 1, 1, 0}
};

static int gValue[MAX_NUMBER_LENGTH][MAX_NUMBER_LENGTH] = {0}; /* 记录已走过的路 */

    b)其实,我们编写一个判断函数,判断当前节点是否合法

int check_pos_valid(int x, int y)
{
	/* 节点是否出边界 */
	if(x < 0 || x>= MAX_NUMBER_LENGTH || y < 0 || y >= MAX_NUMBER_LENGTH)
		return 0;

	/* 当前节点是否存在路 */
	if(0 == gPath[x][y])
		return 0;

	/* 当前节点是否已经走过 */
	if('#' == gValue[x][y])
		return 0;

	return 1;
}

    c)接着,我们编写一个递归的寻找算法即可

int find_path(int x, int y)
{
	if(check_pos_valid(x,y))
	{
		if(2 == gPath[x][y]){
			gValue[x][y] = '#';
			return 1;
		}

		gValue[x][y] = '#';
		if(find_path(x, y-1))
			return 1;

		if(find_path(x-1, y))
			return 1;

		if(find_path(x, y+1))
			return 1;

		if(find_path(x+1, y))
			return 1;
		gValue[x][y] = 0;
		return 0;
	}

	return 0;
}

    d)为了验证我们的算法是否正确,可以编写一个打印函数

void print_path()
{
	int outer;
	int inner;

	for(outer = 0; outer < MAX_NUMBER_LENGTH; outer++){
		for(inner = 0; inner < MAX_NUMBER_LENGTH; inner++){
			printf("%c ", gValue[outer][inner]);
		}
		printf("\n");
	}
}

    e)上面c中所描述的算法只是寻找一条路,那么如果想遍历所有的道路,算法应该怎么修改呢?

void find_path(int x, int y)
{
	if(check_pos_valid(x,y))
	{
		if(2 == gPath[x][y]){
			gValue[x][y] = '#';
			print_path();
			gValue[x][y] = 0;
			return ;
		}

		gValue[x][y] = '#';
		find_path(x, y-1);
		find_path(x-1, y);
		find_path(x, y+1);
		find_path(x+1, y);
		gValue[x][y] = 0;
	}
}

思考题:

    上面的题目介绍了寻路的方法,介绍了如何遍历所有的可能路径。当然你可以从这所有的寻找路径中寻找出一条最短的路径。但是朋友们可以思考一下,有没有一种方法,可以一下子寻找到最优的路径呢?

时间: 2024-09-26 13:14:03

一步一步写算法(之寻路)的相关文章

一步一步写算法(之 算法总结)

原文:一步一步写算法(之 算法总结) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]       自10月初编写算法系列的博客以来,陆陆续续以来写了几十篇.按照计划,还有三个部分的内容没有介绍,主要是(Dijkstra算法.二叉平衡树.红黑树).这部分会在后面的博客补充完整.这里主要是做一个总结,有兴趣的朋友可以好好看看,欢迎大家提出宝贵意见.       (1) 排序算法     快速排序           合并排序     堆排序

一步一步写算法(之 A*算法)

原文:一步一步写算法(之 A*算法) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     在前面的博客当中,其实我们已经讨论过寻路的算法.不过,当时的示例图中,可选的路径是唯一的.我们挑选一个算法,就是说要把这个唯一的路径选出来,怎么选呢?当时我们就是采用穷尽递归的算法.然而,今天的情形有点不太一样了.在什么地方呢?那就是今天的路径有n条,这条路径都可以达到目的地,然而我们在挑选的过程中有一个要求,那就是挑选的路径距离最短?有没有什么

一步一步写算法(之二叉树深度遍历)

原文:一步一步写算法(之二叉树深度遍历) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     深度遍历是软件开发中经常遇到的遍历方法.常用的遍历方法主要有下面三种:(1)前序遍历:(2)中序遍历:(3)后序遍历.按照递归的方法,这三种遍历的方法其实都不困难,前序遍历就是根-左-右,中序遍历就是左-根-右,后续遍历就是左-右-根.代码实现起来也不复杂.     1)前序遍历 void preorder_traverse(TREE_NOD

一步一步写算法(之克鲁斯卡尔算法 下)

原文:一步一步写算法(之克鲁斯卡尔算法 下) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     前面在讨论克鲁斯卡尔的算法的时候,我们分析了算法的基本过程.基本数据结构和算法中需要解决的三个问题(排序.判断.合并).今天,我们继续完成剩下部分的内容.合并函数中,我们调用了两个基本函数,find_tree_by_index和delete_mini_tree_from_group,下面给出详细的计算过程. MINI_GENERATE_T

一步一步写算法(之线性结构的处理)

原文:一步一步写算法(之线性结构的处理) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     我们知道,在内存中的空间都是连续的.也就是说,0x00000001下面的地址必然是0x00000002.所以,空间上是不会出现地址的突变的.那什么数据结构类型是连续内部空间呢,其实就是数组,当然也可以是堆.数组有很多优势,它可以在一段连续空间内保存相同类型的数据,并且对这些数据进行管理.所以从这个意义上说,掌握了数组才能说明你数据结构入门了.

一步一步写算法(之排序二叉树线索化)

原文:一步一步写算法(之排序二叉树线索化) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     前面我们谈到了排序二叉树,还没有熟悉的同学可以看一下这个,二叉树基本操作.二叉树插入.二叉树删除1.删除2.删除3.但是排序二叉树也不是没有缺点,比如说,如果我们想在排序二叉树中删除一段数据的节点怎么办呢?按照现在的结构,我们只能一个一个数据查找验证,首先看看在不在排序二叉树中,如果在那么删除:如果没有这个数据,那么继续查找.那么有没有方法

一步一步写算法(之字符串查找 中篇)

原文:一步一步写算法(之字符串查找 中篇) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     昨天我们编写了简单的字符查找函数.虽然比较简单,但是也算能用.然而,经过我们仔细分析研究一下,这么一个简单的函数还是有改进的空间的.在什么地方改进呢?大家可以慢慢往下看.     下面的代码是优化前的代码,现在再贴一次,这样分析起来也方便些: char* strstr(const char* str, char* data) { int i

一步一步写算法(之非递归排序)

原文:一步一步写算法(之非递归排序) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]        在上面一篇博客当中,我们发现普通查找和排序查找的性能差别很大.作为一个100万的数据,如果使用普通的查找方法,那么每一个数据查找平均下来就要几十万次,那么二分法的查找呢,20多次就可以搞定.这中间的差别是非常明显的.既然排序有这么好的效果,那么这篇博客中,我们就对排序算做一个总结.     按照我个人的理解,排序可以分为两种:一种是非递归排

一步一步写算法(之大数计算)

原文:一步一步写算法(之大数计算) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     我们知道在x86的32位cpu上面,int表示32位,如果核算成整数的话,大约是40多亿.同样,如果在64位cpu上面,能表示的最大整数就是64位二进制,表示的数值要大得多.那么在32位如果想表示大整数怎么办呢?那只能靠我们自己想办法了.     首先我们回顾一下我们手算整数的加减.乘除法是怎么做到的:     (1)记住9*9之间的乘法口诀