⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 path.h

📁 gamecode 很不错的小游戏源代码
💻 H
字号:
//*********************************************************
//寻路处理
//作者:雷雨、曾铮
//时间:2004年6月
//说明:给出较好的选择,让角色可以正常的行走。
//*********************************************************

#ifndef path_h_
#define path_h_

#include "stdafx.h"
#include "time.h"
#include "stdlib.h"

#include "myclasses/mymaps.h"
#include "CZDemo.h"

#define GODOWN 0
#define GOLEFT 1
#define GOUP 2
#define GORIGHT 3

#define Direction int

#define VALUE 15		//权值:初始的分叉扣的值。

extern MyMaps maps;		

int DecValue = 12;		//每次减少的权值。
						//计算:每次减少DecValue,当减至<=1时不再减少;当各个不为0的方向上
						//的值相等时,调用BanlanceValue()恢复回VALUE。

//useful struct:
class Station
{
public:
	Station* next;
	int x;
	int y;
	int north;	//从0到value的一个值,下同。
	int south;
	int west;
	int east;
	Station(int x,int y,int north,int south,int west,int east)
	{
		this->x = x;
		this->y = y;
		this->north = north;
		this->south = south;
		this->west = west;
		this->east = east;
		next = NULL;
	}
};

//每个玩家有一个权值列表,记录分叉口的x,y和该点各个方向上的权值。
class RoadValue
{
public:
	Station* head;
	Station* tail;
	RoadValue()
	{
		head = new Station(0,0,0,0,0,0);
		tail = head->next;
	}
	~RoadValue()
	{
		Station* suc = head;
		while(suc != NULL)
		{
			head = head->next;
			delete suc;
			suc = head;
		}
		//head = NULL;
		//tail = NULL;
	}
	Station* IfNodeExist(int x,int y)
	{
		//节点x,y是否存在。存在返回该节点指针,否则返回null。
		Station* suc = head->next;
		while(suc != NULL)
		{
			if(suc->x == x && suc->y == y)
			{
				return suc;
			}
			suc = suc->next;
		}
		return NULL;
	}
	Station* AddNode(int x,int y,int north,int south,int west,int east)
	{
		//无x,y节点时添加节点。
		tail = new Station(x,y,north,south,west,east);
		Station* suc = tail;
		tail = tail->next;
		return suc;
	}
	void BanlanceValue(Station* suc)
	{
		//若权值相等且不为0时恢复为value。
		int instead = 0;
		if(suc->north != 0)
			instead = suc->north;
		else if(suc->south != 0)
			instead = suc->south;
		else if(suc->west != 0)
			instead = suc->west;
		else if(suc->east != 0)
			instead = suc->east;


		if(suc->north != 0 && suc->north != instead)
			return;
		if(suc->south != 0 && suc->south == instead)
			return;
		if(suc->west != 0 && suc->west == instead)
			return;
		if(suc->east != 0 && suc->east == instead)
			return;


		if(suc->north != 0)
			suc->north = VALUE;
		if(suc->south != 0)
			suc->south = VALUE;
		if(suc->west != 0)
			suc->west = VALUE;
		if(suc->east != 0)
			suc->east = VALUE;
		return;
	}

	Direction CountRandomWays(Station* theNode,Direction originDir)
	{
		//被JudgeWhichWay调用。
		//返回一据value和decvalue得到的随机方向。
		//调用BanlanceValue平衡权值。
		int n = 0;
		int s = 0;
		int w = 0;
		int e = 0;
		if(originDir != GODOWN)
			n = theNode->north;
		if(originDir != GOUP)
			s = theNode->south;
		if(originDir != GORIGHT)
			w = theNode->west;
		if(originDir != GOLEFT)
			e = theNode->east;

		int all = n + s + w + e;

		int i = rand() % all;
		if(i <= 0)
			i = i + 1;

		//决定返回那个方向。
		if(i <= n)
		{
			for(int j = 0;j < DecValue;j++)
			{
				if(theNode->north > 1)
					theNode->north--;
			}
			this->BanlanceValue(theNode);
			return GOUP;
		}
		else if(i <= n + s)
		{
			for(int j = 0;j < DecValue;j++)
			{
				if(theNode->south > 1)
					theNode->south--;
			}
			this->BanlanceValue(theNode);
			return GODOWN;
		}
		else if(i <= n + s + w)
		{
			for(int j = 0;j < DecValue;j++)
			{
				if(theNode->west > 1)
					theNode->west--;
			}
			this->BanlanceValue(theNode);
			return GOLEFT;
		}
		else
		{
			for(int j = 0;j < DecValue;j++)
			{
				if(theNode->east > 1)
					theNode->east--;
			}
			this->BanlanceValue(theNode);
			return GORIGHT;
		}
	}
};

//需要的道路判断函数。
bool IsRoad(const int& x,const int& y);

//提供的接口函数。
Direction GetNextDirection(const int& x,const int& y,const Direction& dir);

//test
//Direction GetWays(int newX,int newY,Direction dir);

//内调函数。
Direction JudgeWhichWay(const int& x,const int& y,const bool& north,const bool& south,
						const bool& west,const bool& east,const Direction& originDir);


//每人有一个RoadValue类型的权值列表。
RoadValue* roadValue = new RoadValue();


bool IsRoad(const int& x,const int& y)
{
	//在这里可能需要x和y的边界检测。
	return maps.GetAccess(x,y);
}

int GetNextDirection(const int& x,const int& y,const int& oriDir)
{
	bool up = false;
	bool down = false;
	bool left = false;
	bool right = false;
	Direction oppDir;

	//计算该点有几各可达方向。
	int roads = 0;
	if(IsRoad(x,y - 1))
	{
		up = true;
		roads++;
	}
	if(IsRoad(x,y + 1))
	{
		down = true;
		roads++;
	}
	if(IsRoad(x - 1,y))
	{
		left = true;
		roads++;
	}
	if(IsRoad(x + 1,y))
	{
		right = true;
		roads++;
	}

	//oppdir为原方向(oridir)的反方向。
	switch(oriDir)
	{
	case GOUP:
		oppDir = GODOWN;
		break;
	case GODOWN:
		oppDir = GOUP;
		break;
	case GOLEFT:
		oppDir = GORIGHT;
		break;
	case GORIGHT:
		oppDir = GOLEFT;
		break;
	}

	switch(roads)
	{
	case 0:
		//不可能为0,如是,则为死路,无任何方向可达。
		break;
	case 1:
		//前方无路时,返回相反方向。
		return oriDir;
	case 2:
		//前方只有1条路时,返回该方向。
		if(up == true && oriDir != GODOWN)
			return GOUP;
		else if(down == true && oriDir != GOUP)
			return GODOWN;
		else if(left == true && oriDir != GORIGHT)
			return GOLEFT;
		else if(right == true && oriDir != GOLEFT)
			return GORIGHT;
		else
			break;
	case 3:
	case 4:
		//前方有叉路时,调用JugeWhichWay()返回随机路。
		return JudgeWhichWay(x,y,up,down,left,right,oriDir);
		break;
	}
	return oriDir;	//不可能到此,如是,则为死路。
}

Direction JudgeWhichWay(const int& x,const int& y,const bool& north,const bool& south,
						const bool& west,const bool& east,const Direction& originDir)
{
	//如果是分叉路(3条路(包括))以上,则调用此用于随机选择。
	Station* suc = roadValue->IfNodeExist(x,y);
	Direction dir;
	int n = 0;
	int s = 0;
	int w = 0;
	int e = 0;

	//为0时,该方向不可达。
	//为value时,可达,且权值为value。
	if(north == true)
		n = VALUE;
	if(south == true)
		s = VALUE;
	if(west == true)
		w = VALUE;
	if(east == true)
		e = VALUE;


	if(suc == NULL)	//无该路的记录,则添加。
	{
		suc = roadValue->AddNode(x,y,n,s,w,e);	//初始化权值为value或0。
		dir = roadValue->CountRandomWays(suc,originDir);
	}
	else	//有,则选择返回。
	{
		dir = roadValue->CountRandomWays(suc,originDir);
	}
	return dir;
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -