这个程序的作用是,任意加载一幅图像,程序将自动识别路线,设置一个目标,Agent会自动让开障碍物,采用A*,Agent之间有碰撞检测功能。不会发生重叠。此技术可以实现汽车的自动导航,以及火星登陆车的自动导航
作者:小白 小蔡 小唐 (按拼音排列)
例如:载入这副图像
程序将自动识别这副迷宫,白色为可通路,黑色为障碍,然后设置一个机器人,机器人将能自动导航
又如:载入一幅火星表面图
相关程序如下
CActor.h
-----------------------------------------------------------
#pragma once
#include "stdafx.h"
#include "CParam.h"
#include "CMap.h"
#include "CConMap.h"
#include "utils.h"
//-----------------Hash---------------------------------
//hash散列函数
inline size_t myHash_value(const Pos& pos)
{
return size_t(100*pos.x+pos.y);
}
//hash比较仿函数
struct Myless
{
bool operator()(const Pos& p1,const Pos& p2)const
{
return myHash_value(p1)<myHash_value(p2);
}
};
//自定义hash类
template<class _Kty>
class MyHash
{
public:
enum
{ // parameters for hash table
bucket_size = 2, // 0 < bucket_size
min_buckets = 8}; // min_buckets = 2 ^^ N, 0 < N
size_t operator()(const _Kty& _Keyval) const
{ // hash _Keyval to size_t value
return ((size_t)myHash_value(_Keyval));
}
bool operator()(const _Kty& _Keyval1, const _Kty& _Keyval2) const
{ // test if _Keyval1 ordered before _Keyval2
return myHash_value(_Keyval1)<myHash_value(_Keyval2);
}
};
//--------------------------------------------------------
//用于open表比较的仿函数(优先级队列)
struct NodeCmp
{
bool operator()(AStarNode* node1,AStarNode* node2)
{
return node1->f_Cost > node2->f_Cost;
}
};
//搜索者类
class CActor
{
public:
int ID; //唯一标识符
bool m_IsSearch; //标志是否正在寻路
Pos m_NowPos; //当前位置
Pos m_TargetPos; //目的地
//构造函数
CActor(int id, const Pos& startPos,CMap* pMap):ID(id),m_NowPos(startPos),
m_TargetPos(startPos),m_Map(pMap),m_IsSearch(false) {}
~CActor(); //析构函数
void run(); //寻路执行函数
void setTarget(const Pos& target);
private:
CMap* m_Map; //地图指针(用于寻路)
deque<Pos> m_Path; //返回的路径
int m_StartTimeCount;//启动计数器
int m_WaitTimeCount; //被阻塞时的等待时间
Pos m_OldTargetPos; //正在执行的目的地
//搜索状态枚举(0-尝试绕过,1-等一会,2-找条新路,3-一直等待, 4-等待开始)
enum STATE {TryRound=0,WaitAwhile=1,TryAntoherPath=2,WaitAlong=3,WaitStart=4};
STATE m_State; //搜索状态
CConMap m_NodeCon; //A*节点容器(容纳open,closed表中节点)
priority_queue<AStarNode*,vector<AStarNode*>,NodeCmp> m_Open; //open表(存储节点指针)
AStarNode* astar(const Pos& startPos,const Pos& endPos,int MaxClosed); //AStar执行函数
void createPath(AStarNode* pNode,deque<Pos>& path); //生成路径
//构造节点
AStarNode* createNode(const Pos& pos,const Pos& targetPos,char flag,int g,AStarNode* parentNode);
void expandNode(AStarNode* node,const Pos& targetPos); //扩展节点
//对当前扩展的节点进行处理
void dealNode(const Pos& pos,const Pos& targetPos,int g,AStarNode* parentNode);
bool judgeAccess(const Pos& pos); //判断该点是否可走
};
CConMap.h
------------------------------------------------------------------------------------------
#pragma once
#include "stdafx.h"
#include "CParam.h"
#include "utils.h"
class CConMap
{
public:
typedef Pos POSITION;
typedef AStarNode NODE;
void createCon(const int& width, const int& height)
{
m_iWidth = width;
m_iHeight= height;
m_iCount = 0;
m_Con = new NODE [width*height];
}
void insert(std::pair<POSITION,NODE>& Elem);
NODE* find(const POSITION& pos);
int size() {return m_iCount;}
void clear()
{
m_iCount = 0;
delete[] m_Con;
}
bool empty(){return m_iCount == 0;}
private:
NODE* m_Con; //一个容器
int m_iCount; //容器的大小
int m_iWidth;
int m_iHeight;
};
CControl.h
--------------------------------------------------------------------------
#pragma once
#include "utils.h "
#include "stdafx.h"
#include "CSearch.h"
//#include "CDraw.h"
// CControl 类
// 主要进行读取键盘鼠标等输入操作
//
class CDraw;
class CSearch;
class CControl
{
public:
CControl(CSearch* search):m_Search(search), m_Pos(0,0),
m_MapPos(0,0),m_State(STATE::Wait),m_SelectID(-1),m_IsSearch(false) { } //构造函数
~CControl(){} //析造函数
RECT getDrawArea( ) const; //获取控制区域
void setDrawArea(int x,int y ,int w,int h); //设置控制区域
void setDrawArea(const RECT& _rect); //设置控制区域
void readMeasage(HWND hwnd,UINT msg, WPARAM wparam, LPARAM lparam); //读取消息
bool m_IsSearch; //显示寻路
friend class CDraw; //友元
private:
bool checkMousePos(int _x,int _y) ; //鼠标位置合法性检查,并转化为地图坐标方式
bool checkMousePos(const Pos& pos); //鼠标位置合法性检查,并转化为地图坐标方式
void transToMapPos(); //把鼠标坐标转化为地图坐标
RECT rect ; //控制区域,区域之外不捕获鼠标输入
Pos m_Pos; //鼠标坐标
Pos m_MapPos; //地图坐标
CSearch* m_Search; //保存search指针
enum STATE {Wait=0,ChangeMap=1,AddActor=2,SelectActor=3}; //状态枚举
STATE m_State; //当前状态
int m_SelectID; //被选中搜索者的ID, -1表示未选中
vector<CActor>::iterator m_SelectIter; //被选中的搜索者
};
CDraw.h
----------------------------------------------------------------------
#pragma once
#include "utils.h "
#include "stdafx.h"
#include "search.h"
#include "CParam.h"
#include "CControl.h"
#include "DirectFunction.h"
// DirectDraw 类
// 主要进行显示
//
class CDraw
{
public:
CDraw (HWND hwnd,CSearch* search,CControl* control); //构造函数
~ CDraw( ); //析构函数
void drawBlock() ; //绘制地图上的障碍物
RECT getDrawArea( ) const; //获取显示区域
void setDrawArea(int x,int y ,int w,int h); //显示区域的设定(地图)
void display ( ) ; //显示函数
void drawActor( ) ; //画搜索者
void drawAim ( ) ; //画出目的地
void displayOnScreen() ; //显示到屏幕上
void displayCoordinate( ) ; //显示坐标函数
void displayMessage(); //显示消息
void displayBackGround(BITMAP_FILE& map); //显示背景
private:
void drawRect (RECT rect,COLORREF color ); //绘制矩形
void drawRect (int x,int y ,int w,int h,COLORREF color=_RGB32BIT(0,0, 0, 0) ); //绘制矩形
void drawBoardLine(int x,int y ,int w,int h, int penWidth=1, int penStyle=PS_SOLID,COLORREF color=_RGB32BIT(0,0, 0, 0)) ; //画边线框
void createMapByBitMap(set<Pos>& blockCon);
int m_Wide ; // 地图宽
int m_Hight ; // 地图高
int m_BeginX ; // 开始点X
int m_BeginY ; // 开始点Y
int m_SpaceH ; // 高间距
int m_SpaceW ; // 宽间距
RECT rect ; //绘制区域(此处有点数据冗余但是使用较为方便)
RECT rw ; //窗口模式大小
BITMAP_FILE bitmap ; // 位图
BITMAP_FILE themap ; // 位图
LPDIRECTDRAW7 lpdd ; //Direct对象
LPDIRECTDRAWSURFACE7 lpddsprimary ; //主显示表面
LPDIRECTDRAWSURFACE7 lpddsback ; //后备
LPDIRECTDRAWPALETTE lpddpal ; // 指向调色板信息
LPDIRECTDRAWCLIPPER lpddclipper ; // 裁剪器
PALETTEENTRY palette[256] ; // 调色板
PALETTEENTRY save_palette[256]; // 保存调色板
DDSURFACEDESC2 ddsd ; // Direct信息结构
DDBLTFX ddbltfx; // 填充结构
DDSCAPS2 ddscaps; // 绘制表面信息结构
HRESULT ddrval ; // Direct调用返回结果
DWORD m_StartClockCount ; // 用来计时
HWND m_WindowHandle; // 全局函数句柄
char buffer[80];
CSearch* m_Search;
CControl* m_Control;
};
CMap.h
---------------------------------------------------------------
#pragma once
#include "stdafx.h"
#include "utils.h"
#include "CParam.h"
//地图类
class CMap
{
public:
CMap():m_Width(0),m_Height(0) {};
~CMap(); //析构函数
void loadMap(set<Pos>& blockCon,vector<Pos>& actorPos); //载入地图
void saveMap(); //保存地图
int width()const {return m_Width;} //返回地图宽度
int height()const {return m_Height;} //返回地图高度
bool isBlock(const Pos& pos)const {return m_Map[pos.y][pos.x]==m_Block;} //坐标pos是否为障碍物
bool isAccess(const Pos& pos)const {return m_Map[pos.y][pos.x]==m_Access;} //坐标pos是否为通路
bool isActor(const Pos& pos)const {return m_Map[pos.y][pos.x]==m_Actor;} //坐标pos是否有搜索者
void setBlock(const Pos& pos) {m_Map[pos.y][pos.x] = m_Block;} //修改节点为障碍物
void setAccess(const Pos& pos) {m_Map[pos.y][pos.x] = m_Access;} //修改节点为通路
void setActor(const Pos& pos) {m_Map[pos.y][pos.x] = m_Actor;} //在节点上添加物品
private:
char** m_Map; //地图信息 ('0'--障碍物,'1'--通路,'2'--有搜索者)
char m_Block; //障碍物字符
char m_Access; //通路字符
char m_Actor; //搜索者字符
int m_Width; //地图宽度
int m_Height; //地图高度
};
CParam.h
------------------------------------------------------------------------
#pragma once
#include "stdafx.h"
//参数类,用于载入配置信息
class CParam
{
public:
CParam(); //构造函数
static string loadMapName; //载入地图的文件名
static string saveMapName; //保存地图的文件名
//--------------------------------------------------
static int oneBiasCost; //斜走一步开销
static int oneNoBiasCost; //横竖走一步开销
static int waitTime; //被挡住时等待次数
static int permitDisdance; //允许的最优点到目的地的最大距离
static int tryRoundBlock; //尝试绕开的障碍物最大个数
static int tryStartTimes; //启动计数器的最大值
static int startConSize;
static int startProHCost;
static int RStepBegin; //红色的起始阀值
static int GStepBegin; //绿色的起始阀值
static int BStepBegin; //蓝色的起始阀值
static int RStepEnd; //红色的结束阀值
static int GStepEnd; //绿色的结束阀值
static int BStepEnd; //蓝色的结束阀值
//--------------------------------------------------
static int displayX ; //屏幕上显示的地图起点X
static int displayY ; //屏幕上显示的地图起点Y
static int displayWidth; //屏幕显示的地图宽度
static int displayHight; //屏幕显示的地图高度
//-------------------------------------------------
static bool bDisOppo; //是否显示反色
};
CSearch.h
________________________________________________________
#pragma once
#include "stdafx.h"
#include "utils.h"
#include "CMap.h"
#include "CActor.h"
class CDraw;
//搜索类,由用户使用
class CSearch
{
public:
typedef vector<CActor>::iterator VI;
CSearch(); //构造函数
void addActor(const Pos& startPos); //添加搜索者
void delActor(const VI actor); //删除搜索者
bool setTargetPos(const VI actor,const Pos& targetPos); //设置搜索者目标点
void changeMap(const Pos& pos); //修改地图
bool runOneTimes(); //执行搜索一次
friend class CDraw; //友元
friend class CControl;
private:
vector<CActor> m_ActorCon; //搜索者容器
CMap m_Map; //地图
set<Pos> m_BlockCon; //障碍物容器
bool locateActor(const Pos& pos,VI& select); //定位搜索者
};
DirectFunction.h
___________________________________________________________
#pragma once
#include "utils.h "
#include "stdafx.h"
#include "search.h"
//显示文字
int Draw_Text_GDI( LPDIRECTDRAWSURFACE7& lpdds,char *text, int x,int y, COLORREF color);
//画直线
void Draw_Line ( LPDIRECTDRAWSURFACE7& lpdds,int Ax,int Ay, int Bx,int By, int penWidth=1,int penStyle=PS_SOLID,COLORREF color=_RGB32BIT(0,0, 0, 0));
// 初始化内存为0 ,必须是引用
#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }
//切换图像
bool Flip_Bitmap(UCHAR *image, int bytes_per_line, int height);
//载入图像
bool Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename);
//卸载图像
bool Unload_Bitmap_File(BITMAP_FILE_PTR bitmap);
resource.h
______________________________________________________
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by 瓜西西AStar.rc
//
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
stdafx.h
_________________________________________________________
#pragma once
#define WIN32_LEAN_AND_MEAN
#define INITGUID
//---------该处添加所需库文件
#include <vector>
#include <queue>
#include <hash_map>
#include <set>
#include <string>
#include <fstream>
#include <iostream>
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <string>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include <fcntl.h>
#include <ddraw.h>
#include <io.h>
using namespace std;
utils.h
________________________________________________________________
#pragma once
#include "stdafx.h"
//----------------全局常量
const int SCREEN_WIDTH=800 ;
const int SCREEN_HEIGHT=600;
const int SCREEN_BPP =32;
//---------------全局变量
static int window_closed ; // 跟踪窗口是否销毁
static HINSTANCE hinstance_app ; //全局函数实例
static HWND main_windows_hwnd ; //全局窗口句柄
//---------------定义类型别名
typedef unsigned short USHORT;
typedef unsigned short WORD;
typedef unsigned char UCHAR;
typedef unsigned char BYTE;
//--------------------宏定义
#define WINDOW_CLASS_NAME "WINCLASS1"
#define BITMAP_ID 0x4D42 //位图格式标志
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
//图像颜色编码方式
#define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10)) // 16色位图 5. 5 .5 1位a
#define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))// 16色位图 5.6.5 绿色多一位
#define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24)) // 32色位图 8.8.8 8位a
//------------该处添加所需全局结构
//坐标结构
struct Pos
{
int x;
int y;
Pos():x(0),y(0){}
Pos(int _x,int _y):x(_x),y(_y) {}
bool operator==(const Pos& rhs) //相等判断
{
return (x==rhs.x && y==rhs.y);
}
friend bool operator <(const Pos& pos1,const Pos& pos2)
{
if(pos2.y > pos1.y)
return true;
if(pos1.y > pos2.y)
return false;
if(pos2.x > pos1.x)
return true;
return false;
}
};
//位图结构
typedef struct BITMAP_FILE_TAG
{
BITMAPFILEHEADER bitmapfileheader; //位图文件头信息
BITMAPINFOHEADER bitmapinfoheader; // 调色板信息
PALETTEENTRY palette[256]; // 储存调色板v
UCHAR *buffer; // 指向位图数据指针
} BITMAP_FILE, *BITMAP_FILE_PTR;
//A*节点结构
struct AStarNode
{
Pos pos; //坐标
int f_Cost; //总开销
int g_Cost; //实际开销
int h_Cost; //估价开销
char flag; //状态标志('o'--在open表中,'c'--在closed表中)
AStarNode* parent; //父节点
enum {INFINITY = 2147483646};
AStarNode(){g_Cost = INFINITY;}
AStarNode(const Pos& _pos, char _flag, AStarNode* _parent)
:pos(_pos),flag(_flag),parent(_parent) {}
//重载运算符
bool operator==(AStarNode& node) {return pos==node.pos;}
bool operator <(AStarNode& node) {return f_Cost < node.f_Cost;}
};
CActor.cpp
_____________________________________________________________
#include "CActor.h"
//析构函数
CActor::~CActor()
{
while(!m_Open.empty()) //清空open
m_Open.pop();
//m_NodeCon.clear(); //清空节点容器
}
//寻路执行函数(执行一步)
void CActor::run()
{
Pos aim;
while (1)
{
if(m_Path.empty() || !(m_OldTargetPos == m_TargetPos)) //执行队列为空或目标地改变时
{
m_Path.clear();
m_WaitTimeCount = 0;
m_OldTargetPos = m_TargetPos;
AStarNode* node = astar(m_NowPos,m_TargetPos,200000); //调用Astar
if(node->h_Cost < CParam::permitDisdance)
{
m_Path.clear();
m_OldTargetPos = m_TargetPos;
createPath(node,m_Path); //生成执行队列
m_NodeCon.clear(); //清空节点容器
}
else
{
if (m_NodeCon.size() > CParam::startConSize && node->h_Cost < CParam::startProHCost)
{
if (m_StartTimeCount++ > CParam::tryStartTimes)
{
createPath(node,m_Path); //生成执行队列
m_NodeCon.clear(); //清空节点容器
break;
}
else
{
m_NodeCon.clear(); //清空节点容器
m_State = STATE::WaitStart;
break;
}
}//end if (m_NodeCon.size() > 200 && m_Open.empty() && node->h_Cost < 50)
m_State = STATE::WaitStart;
m_NodeCon.clear(); //清空节点容器
break;
}//end if(node->h_Cost < CParam::permitDisdance)
} //if(m_Path.empty() || !(m_OldTargetPos == m_TargetPos)) //执行队列为空或目标地改变时
if (m_Path.empty())
{
break;
}
if (m_State != STATE::WaitAlong)
{
m_State = STATE::TryRound;
}
aim = m_Path.front();
//如果能够继续下一步
if (m_Map->isAccess(aim))
{
//执行下一步
m_State = STATE::TryAntoherPath;
m_Path.pop_front();
m_Map->setActor(aim);
m_Map->setAccess(m_NowPos);
m_WaitTimeCount = 0;
m_NowPos = aim;
break;
}
//尝试绕开
if(m_State==STATE::TryRound)
{
bool success = false;
for(unsigned int i=1;i < m_Path.size() && i <= CParam::tryRoundBlock;i++)
{
if(m_Map->isAccess(m_Path[i]))
{
AStarNode* node = astar(m_NowPos,m_Path[i],10);
if(node->pos == m_Path[i])
{
success = true;
deque<Pos> path;
createPath(node,path); //生成绕开路径
m_NodeCon.clear(); //清空节点容器
m_Path.erase(m_Path.begin(),m_Path.begin()+i);//删除障碍物路径
path.pop_back();
m_Path.insert(m_Path.begin(),path.begin(),path.end()); //插入绕开路径
break;
}
m_NodeCon.clear();
break;
}
}
if(success==true)
continue;
m_State = STATE::WaitAwhile;
}
//等待一会
if(m_State == STATE::WaitAwhile)
{
if(m_WaitTimeCount++ <= CParam::waitTime)
break;
m_State = STATE::TryAntoherPath;
m_WaitTimeCount = 0;
}
//搜索新路径
if(m_State == STATE::TryAntoherPath)
{
AStarNode* node = astar(m_NowPos,m_TargetPos,200000);
if(node->h_Cost < CParam::permitDisdance)
{
m_Path.clear();
m_OldTargetPos = m_TargetPos;
createPath(node,m_Path); //生成新路径
m_State = STATE::TryRound;
m_NodeCon.clear(); //清空节点容器
continue;
}
m_NodeCon.clear(); //清空节点容器
m_State = STATE::WaitAlong;
}
//一直等待
if(m_State == STATE::WaitAlong)
break;
}
if (m_Path.empty()&&m_State != STATE::WaitStart)
{
m_IsSearch = false;
return;
}
}
//生成路径
void CActor::createPath(AStarNode* pNode,deque<Pos>& path)
{
while(pNode->parent!=NULL)
{
path.push_front(pNode->pos);
pNode = pNode->parent;
}
}
//AStar执行函数(起点,终点,closed表上限)
AStarNode* CActor::astar(const Pos& startPos,const Pos& endPos,int closedMax)
{
AStarNode* pNode;
AStarNode* bestNode; //最优节点
int closedCount = 0; //closed表元素个数计数器
m_NodeCon.createCon (m_Map->width(),m_Map->height());
//把出发点入节点容器
bestNode = createNode(startPos,endPos,'o',0,NULL);
m_Open.push(bestNode); //出发节点入open表
while(1)
{
//超过closed表上限或open表为空
if(closedCount > closedMax || m_Open.empty())
{
while(!m_Open.empty()) //清空open
m_Open.pop();
return bestNode;
}
pNode = m_Open.top(); //取出f值最小的节点,放入closed表
pNode->flag = 'c';
closedCount++; //closed计数器加1
m_Open.pop();
if(pNode->h_Cost < bestNode->h_Cost)
{
bestNode = pNode; //记录最优节点
}
if(pNode->pos == endPos) //已到目标点
{
while(!m_Open.empty()) //清空open
m_Open.pop();
return bestNode;
}
expandNode(pNode,endPos); //扩展该节点
}
}
//构造节点(返回节点容器中该节点地址)
AStarNode* CActor::createNode(const Pos& pos,const Pos& targetPos,char flag,int g,AStarNode* parentNode)
{
AStarNode newNode(pos,'o',parentNode);
newNode.g_Cost = g;
newNode.h_Cost = CParam::oneNoBiasCost*(abs(pos.x-targetPos.x) + abs(pos.y-targetPos.y)); //
newNode.f_Cost = g + newNode.h_Cost;
m_NodeCon.insert(pair<Pos,AStarNode>(pos,newNode));
return m_NodeCon.find(pos);
}
//扩展节点(按8叉方式)
void CActor::expandNode(AStarNode* node,const Pos& targetPos)
{
int _x = node->pos.x; //该节点坐标
int _y = node->pos.y;
int _g = node->g_Cost;
Pos pos;
int gCost;
//左上
pos.x = _x-1;
pos.y = _y-1;
if(judgeAccess(pos)==true)
{
gCost = _g + CParam::oneBiasCost;
dealNode(pos,targetPos,gCost,node);
}
//上
pos.x = _x;
pos.y = _y-1;
if(judgeAccess(pos)==true)
{
gCost = _g + CParam::oneNoBiasCost;
dealNode(pos,targetPos,gCost,node);
}
//右上
pos.x = _x+1;
pos.y = _y-1;
if(judgeAccess(pos)==true)
{
gCost = _g + CParam::oneBiasCost;
dealNode(pos,targetPos,gCost,node);
}
//左
pos.x = _x-1;
pos.y = _y;
if(judgeAccess(pos)==true)
{
gCost = _g + CParam::oneNoBiasCost;
dealNode(pos,targetPos,gCost,node);
}
//右
pos.x = _x+1;
pos.y = _y;
if(judgeAccess(pos)==true)
{
gCost = _g + CParam::oneNoBiasCost;
dealNode(pos,targetPos,gCost,node);
}
//左下
pos.x = _x-1;
pos.y = _y+1;
if(judgeAccess(pos)==true)
{
gCost = _g + CParam::oneBiasCost;
dealNode(pos,targetPos,gCost,node);
}
//下
pos.x = _x;
pos.y = _y+1;
if(judgeAccess(pos)==true)
{
gCost = _g + CParam::oneNoBiasCost;
dealNode(pos,targetPos,gCost,node);
}
//右下
pos.x = _x+1;
pos.y = _y+1;
if(judgeAccess(pos)==true)
{
gCost = _g + CParam::oneBiasCost;
dealNode(pos,targetPos,gCost,node);
}
}
//对当前扩展的节点进行处理
void CActor::dealNode(const Pos& pos,const Pos& targetPos,int g,AStarNode* parentNode)
{
AStarNode* iter;
iter = m_NodeCon.find(pos); //在节点容器中查找
AStarNode* node;
if(iter != NULL)
{
node = iter;
if(node->g_Cost > g)
{
node->g_Cost = g;
node->parent = parentNode;
if(node->flag=='c')
{
node->flag = 'o';
m_Open.push(node); //在closed表中就放入open
}
}
return;
}
//不在节点容器中就构造新节点
node = createNode(pos,targetPos,'o',g,parentNode);
m_Open.push(node);
return;
}
//判断该点是否可走
bool CActor::judgeAccess(const Pos& pos)
{
if(pos.x<0 || pos.x>=m_Map->width())
return false;
if(pos.y<0 || pos.y>=m_Map->height())
return false;
return m_Map->isAccess(pos);
}
void CActor::setTarget(const Pos& target)
{
m_StartTimeCount = 0;
m_WaitTimeCount = 0;
m_TargetPos = target;
}
CConMap.cpp
______________________________________
#include "CConMap.h"
//插入函数
void CConMap::insert(std::pair<POSITION,NODE>& Elem)
{
++m_iCount;
m_Con[Elem.first.x + Elem.first.y*m_iWidth] = Elem.second;
}
//查找函数
CConMap::NODE* CConMap::find(const POSITION& pos)
{
if ( pos.x >= 0 && pos.x < m_iWidth && pos.y >= 0 && pos.y < m_iHeight)
if (m_Con[pos.x + pos.y*m_iWidth].g_Cost == AStarNode::INFINITY)
{
return NULL;
}
else
{
return &m_Con[pos.x + pos.y*m_iWidth];
}
else
return NULL;
}
CControl.cpp
_____________________________________________
#include "CControl.h"
void CControl::readMeasage(HWND hwnd,UINT msg, WPARAM wparam, LPARAM lparam)
{
if (KEYDOWN(VK_ESCAPE))
{
PostMessage(hwnd,WM_CLOSE,0,0);
}
switch(msg)
{
case WM_MOUSEMOVE:
{
m_Pos.x=LOWORD(lparam)+4;
m_Pos.y=HIWORD(lparam)+20;
} break;
case WM_LBUTTONDOWN:
{
if(checkMousePos(m_Pos)==false)
break;
switch(m_State)
{
case STATE::AddActor: //添加搜索者
if(m_Search->m_Map.isAccess(m_MapPos))
m_Search->addActor(m_MapPos);
break;
case STATE::ChangeMap: //修改地图
m_Search->changeMap(m_MapPos);
break;
case STATE::SelectActor: //设置搜索者目的地
m_Search->setTargetPos(m_SelectIter,m_MapPos);
if(!m_Search->m_Map.isActor(m_MapPos))
break;
default: //定位搜索者
if(m_Search->locateActor(m_MapPos,m_SelectIter)==true)
{
m_SelectID = m_SelectIter->ID;
m_State = STATE::SelectActor;
}
}
}break;
case WM_RBUTTONDOWN:
{
m_State = STATE::Wait;
}break;
case WM_CHAR:
{
switch(wparam)
{
case 'a':
case 'A'://按A键添加搜索者
m_State = STATE::AddActor;
break;
case 'c':
case 'C'://按C键修改地图
m_State = STATE::ChangeMap;
break;
case 'd':
case 'D'://按D键删除搜索者
if(m_State==STATE::SelectActor)
{
m_Search->delActor(m_SelectIter);
m_State = STATE::Wait;
m_SelectID = -1;
}
break;
case 'o':
case 'O'://按o键显示反色
CParam::bDisOppo = !CParam::bDisOppo;
break;
case 's':
case 'S'://按S键保存地图
m_Search->m_Map.saveMap();
break;
case 'z':
case 'Z'://单步执行
m_Search->runOneTimes();
break;
case 'x':
case 'X'://连续执行(再按次取消)
m_IsSearch = !m_IsSearch;
break;
case 'h':
case 'H':
MessageBox(hwnd, "作者:西南科技大学 白礼彬 蔡孝府 唐坤 ",
"关于作者", MB_OK );
default:
break;
}
}break;
default:
break;
}
}
//获取控制区域
RECT CControl::getDrawArea( ) const
{
return rect;
}
//设置控制区域
void CControl::setDrawArea(const RECT& _rect)
{
rect=_rect;
}
//设置控制区域
void CControl::setDrawArea(int x,int y ,int w,int h)
{
rect.left=x;
rect.top=y;
rect.right=w+rect.left;
rect.bottom=h+rect.top;
}
//鼠标位置合法性检查
bool CControl::checkMousePos(int _x,int _y)
{
if(_y>rect.bottom)
{ return false;}
if(_y<rect.top)
{ return false;}
if(_x<rect.right)
{ return false;}
if(_x>rect.right)
{ return false;}
transToMapPos();
return true;
}
//鼠标位置合法性检查
bool CControl::checkMousePos(const Pos& pos)
{
if( pos.y>rect.bottom )
{ return false;}
if( pos.y<rect.top )
{ return false;}
if( pos.x<rect.left )
{ return false;}
if( pos.x>rect.right )
{ return false;}
transToMapPos();
return true;
}
//把鼠标坐标转化为地图坐标
void CControl::transToMapPos()
{
int perXGridPixel = (rect.right-rect.left)/m_Search->m_Map.width();//每横格所占象素
int perYGridPixel = (rect.bottom-rect.top)/m_Search->m_Map.height();//每竖格所占象素
m_MapPos.x = (m_Pos.x-rect.left)/perXGridPixel;
m_MapPos.y = (m_Pos.y-rect.top)/perYGridPixel;
}
CDraw.cpp
_____________________________________________________
#include "CDraw.h"
//构造函数
CDraw::CDraw(HWND hwnd,CSearch* search,CControl* control):m_WindowHandle(hwnd),lpdd (NULL), lpddsprimary (NULL), lpddsback(NULL),
lpddpal(NULL), lpddclipper(NULL), m_StartClockCount (0),
m_BeginX(CParam::displayX),m_BeginY(CParam::displayY),m_Wide(CParam::displayWidth), m_Hight(CParam::displayHight),
m_Search(search),m_Control(control)
{
window_closed=1;
//创建Direct7接口对象并且对其进行测试
if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))
{ return ; }
//设置显示模式到全屏
if (FAILED(lpdd->SetCooperativeLevel(m_WindowHandle,
DDSCL_NORMAL //窗口模式但有问题
//DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT
)))
{ return ; }
// 创建主显示表面
DDRAW_INIT_STRUCT(ddsd) ; //清空内存
ddsd.dwFlags = DDSD_CAPS ; // 初始有效区域
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE ; // 申请主显示表面
if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))
{ exit(0) ;}
// 创建从显示表面
GetWindowRect(m_WindowHandle,&rw);
DDRAW_INIT_STRUCT(ddsd) ;
ddsd.dwFlags = DDSD_CAPS |DDSD_WIDTH | DDSD_HEIGHT ;
ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY ;
ddsd.dwHeight = rw.bottom-rw.top;
ddsd.dwWidth = rw.right-rw.left;
if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsback, NULL)))
{ exit(0) ;}
LPDIRECTDRAWCLIPPER clip=NULL;
if(FAILED(lpdd->CreateClipper(0, &clip, NULL)))
return ;
if(FAILED(clip->SetHWnd(0, m_WindowHandle)))
return ;
if(lpddsprimary->SetClipper(clip))
return ;
if(clip!=NULL)
clip->Release();
//direct显示区域
//SendMessage(m_WindowHandle,WM_SYSCOMMAND,SC_MINIMIZE,0);
//初始化地图
setDrawArea(m_BeginX,m_BeginY,m_Wide, m_Hight);
//载入地图
if (!Load_Bitmap_File( &bitmap,"bitmap24.bmp"))
{ return ;}
if (!Load_Bitmap_File( &themap,"bitmap24.bmp"))
{ return ;}
/*if (!Load_Bitmap_File( &themap,"map.bmp"))
{ return ;}*/
createMapByBitMap(m_Search->m_BlockCon);
//设置显示模式为800*600*24 SCREEN_WIDTH*SCREEN_HEIGHT* SCREEN_BPP
// if (FAILED(lpdd->SetDisplayMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0)))
// { return ; }
}
//析构函数
CDraw::~CDraw()
{
//卸载图片资源
Unload_Bitmap_File(&bitmap);
if (lpddsprimary) // 释放主显示表面
{
lpddsprimary->Release();
lpddsprimary = NULL;
}
if (lpddsback) // 释放主显示表面
{
lpddsback->Release();
lpddsback = NULL;
}
if (lpdd) // 释放direct接口
{
lpdd->Release();
lpdd = NULL;
}
}
//显示区域的设定(地图)
void CDraw::setDrawArea (int x,int y,int w,int h )
{
m_BeginX=x;
m_BeginY=y;
m_Wide =w;
m_Hight =h;
//初始化间距
m_SpaceW = m_Wide/( m_Search->m_Map.width() );
m_SpaceH = m_Hight/( m_Search->m_Map.height() );
//显示地图区域
rect.left = m_BeginX ;
rect.top = m_BeginY ;
rect.bottom = rect.top + m_Hight;
rect.right = rect.left + m_Wide;
//更新Ccontrol中显示区域
m_Control->rect=rect;
}
//获取显示区域
RECT CDraw::getDrawArea( ) const
{
return rect;
}
//显示函数
void CDraw::display()
{
if( window_closed==0)
{ return ;}
if(CParam::bDisOppo==true)
{
displayBackGround(themap);
}
else
{
displayBackGround(bitmap);
}
drawActor( );
displayCoordinate( );
displayMessage();
drawAim();
displayOnScreen();
}
//显示到屏幕上
void CDraw::displayOnScreen()
{
//纵线
Draw_Line( lpddsback, rect.left ,rect.top ,rect.left ,rect.bottom );
Draw_Line( lpddsback, rect.left+m_Search->m_Map.width()*m_SpaceW ,rect.top ,
rect.left+m_Search->m_Map.width()*m_SpaceW ,rect.bottom );
//横线
Draw_Line( lpddsback, rect.left ,rect.top+m_Search->m_Map.height()*m_SpaceH,rect.right ,rect.top+m_Search->m_Map.height()*m_SpaceH );
Draw_Line( lpddsback, rect.left,rect.top ,rect.right ,rect.top );
/*
//纵线
for(int n=m_Search->m_Map.width() ; n>0 ;n--)
{
Draw_Line( lpddsback, rect.left+m_SpaceW*n ,rect.top ,rect.left+m_SpaceW*n ,rect.bottom );
}
//横线
for(int n=m_Search->m_Map.height(); n>0 ;n--)
{
Draw_Line( lpddsback, rect.left ,rect.top+m_SpaceH*n , rect.right ,rect.top+m_SpaceH*n );
}
*/
/*
if(FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT) ))
{ return ;}
DDRAW_INIT_STRUCT(ddbltfx);
if (FAILED(lpddsback->Blt(&rw,lpddsprimary ,NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx)))
{ return ;}
DDRAW_INIT_STRUCT(ddbltfx);
ddbltfx.dwFillColor =_RGB32BIT(0,0, 0, 0); //将全屏归0
if (FAILED(lpddsback->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx)))
{ return ;}
*/
GetWindowRect(m_WindowHandle,&rw);
if (FAILED(lpddsprimary->Blt(&rw, lpddsback, NULL, DDBLT_WAIT,NULL)))
{ return ;}
DDBLTFX ddbltfx;
ddbltfx.dwSize =sizeof(ddbltfx);
ddbltfx.dwFillColor =0x0;
if (FAILED(lpddsback->Blt(NULL, NULL, NULL, DDBLT_COLORFILL , &ddbltfx)))
{ return ;}
}
//绘制地图上的障碍物
void CDraw::drawBlock()
{
if(m_Search->m_BlockCon.empty())
{ return ;}
DDRAW_INIT_STRUCT(ddbltfx);
ddbltfx.dwFillColor = _RGB32BIT(0,0, 0, 255);
if (FAILED(lpddsback->Blt(&rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx)))
{ return ;}
RECT rectTemp;
set<Pos>::iterator iter=m_Search->m_BlockCon.begin();
for( ;iter!=m_Search->m_BlockCon.end();iter++)
{
rectTemp.left = (*iter).x *m_SpaceW +rect.left;
rectTemp.top = (*iter).y*m_SpaceH +rect.top ;
rectTemp.right= rectTemp.left + m_SpaceW ;
rectTemp.bottom=rectTemp.top + m_SpaceH ;
drawRect(rectTemp,_RGB32BIT(0,128,0, 0)) ;
}
}
//显示消息
void CDraw::displayMessage()
{
Draw_Text_GDI(lpddsback,"H键----关于作者",600,50,RGB(255,0,0)) ;
Draw_Text_GDI(lpddsback,"Esc键----退出",600,100,RGB(255,0,0)) ;
Draw_Text_GDI(lpddsback,"A键----添加搜索者",600,125,RGB(255,0,0)) ;
Draw_Text_GDI(lpddsback,"C键----修改地图",600,150,RGB(255,0,0)) ;
Draw_Text_GDI(lpddsback,"D键----删除搜索者",600,175,RGB(255,0,0)) ;
Draw_Text_GDI(lpddsback,"X键----执行/取消 搜索连续",600,200,RGB(255,0,0)) ;
Draw_Text_GDI(lpddsback,"Z键----执行/取消 单步搜索",600,225,RGB(255,0,0)) ;
Draw_Text_GDI(lpddsback,"鼠标左键----选择定位",600,250,RGB(255,0,0)) ;
Draw_Text_GDI(lpddsback,"鼠标右键----取消操作",600,270,RGB(255,0,0)) ;
Draw_Text_GDI(lpddsback,"搜索者",620,300,RGB(0,255,0)) ;
Draw_Text_GDI(lpddsback,"目的地",620,320,RGB(255,220,0 )) ;
}
//显示鼠标位置
void CDraw::displayCoordinate()
{
sprintf(buffer,"坐标: %d", m_Control->m_Pos.x );
Draw_Text_GDI(lpddsback,buffer,700,100,RGB(255,0,0));
sprintf(buffer,"坐标: %d", m_Control->m_Pos.y );
Draw_Text_GDI(lpddsback,buffer,700,150,RGB(255,0,0));
}
//显示搜索者
void CDraw::drawActor( )
{
if(m_Search->m_ActorCon.empty())
{ return ;}
RECT rectTemp;
vector<CActor>::iterator iter =m_Search->m_ActorCon.begin();
for( ;iter!=m_Search->m_ActorCon.end();iter++)
{
rectTemp.left = (*iter).m_NowPos.x * m_SpaceW +rect.left-3;
rectTemp.top = (*iter).m_NowPos.y * m_SpaceH +rect.top-3;
rectTemp.right= rectTemp.left + m_SpaceW+3 ;
rectTemp.bottom=rectTemp.top + m_SpaceH+3 ;
drawRect(rectTemp,_RGB32BIT(0,0,255 , 0));
//显示人标号(ID)
// sprintf(buffer,"%d", (*iter).ID );
// Draw_Text_GDI( lpddsback,buffer , rectTemp.left , rectTemp.top ,RGB(255,0,0));
//画边框
// if((*iter).ID ==m_Control->m_SelectID)
// {
// drawBoardLine( (*iter).m_NowPos.x*m_SpaceW +rect.left,(*iter).m_NowPos.y*m_SpaceH +rect.top ,
// m_SpaceW,m_SpaceH,3,PS_SOLID,RGB (255,100,255));
// }
}
}
//画出目的地
void CDraw::drawAim()
{
RECT rectTemp;
vector<CActor>::iterator iter =m_Search->m_ActorCon.begin();
for( ;iter!=m_Search->m_ActorCon.end();iter++)
{
if((*iter).m_TargetPos==(*iter).m_NowPos) //防止目的地与所在地重合
continue;
rectTemp.left = (*iter).m_TargetPos.x * m_SpaceW +rect.left -3;
rectTemp.top = (*iter).m_TargetPos.y * m_SpaceH +rect.top -3;
rectTemp.right= rectTemp.left + m_SpaceW +3 ;
rectTemp.bottom=rectTemp.top + m_SpaceH +3;
drawRect(rectTemp,_RGB32BIT(0,255,220,0 ));
//显示人标号(ID)
/*sprintf(buffer,"%d", (*iter).ID );
Draw_Text_GDI( lpddsback,buffer , rectTemp.left , rectTemp.top ,RGB(255,0,0));
*/
}
}
//画边线框
void CDraw::drawBoardLine(int x,int y ,int w,int h, int penWidth,int penStyle,COLORREF color)
{
Draw_Line( lpddsback, x ,y ,x+w ,y ,penWidth ,penStyle ,color );
Draw_Line( lpddsback, x+w ,y ,x+w ,y+h ,penWidth ,penStyle ,color );
Draw_Line( lpddsback, x ,y+h ,x+w ,y+h ,penWidth ,penStyle ,color );
Draw_Line( lpddsback, x ,y ,x ,y+h ,penWidth ,penStyle , color ); //RGB (255,128,0)
}
//绘制矩形
void CDraw::drawRect(int x,int y ,int w,int h,COLORREF color )
{
RECT rectTemp;
rectTemp.left=x;
rectTemp.right=y;
rectTemp.bottom=x+w;
rectTemp.top=y+h;
DDRAW_INIT_STRUCT(ddbltfx);
ddbltfx.dwFillColor = color;
if (FAILED(lpddsback->Blt(&rectTemp, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx)))
{ return ;}
}
//绘制矩形
void CDraw::drawRect( RECT rectTemp,COLORREF color )
{
DDRAW_INIT_STRUCT(ddbltfx);
ddbltfx.dwFillColor = color;
if (FAILED(lpddsback->Blt(&rectTemp, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx)))
{ return ;}
}
//显示背景
void CDraw::displayBackGround(BITMAP_FILE& map)
{
lpddsback->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
DWORD *primary_buffer = (DWORD *)ddsd.lpSurface;
for (int index_y = 0; index_y < SCREEN_HEIGHT; index_y++)
{
for (int index_x = 0; index_x < SCREEN_WIDTH; index_x++)
{
UCHAR blue = (map.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 0]),
green = (map.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 1]),
red = (map.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 2]);
DWORD pixel = _RGB32BIT(0,red,green,blue);
primary_buffer[index_x + (index_y*ddsd.lPitch >> 2)] = pixel;
}
}
if (FAILED(lpddsback->Unlock(NULL)))
{ return ;}
}
void CDraw::createMapByBitMap(set<Pos>& blockCon)
{
int iWidth = m_Search->m_Map.width();
int iHeight= m_Search->m_Map.height();
Pos pos;
for (int index_y = 0; index_y < iHeight; index_y++)
{
for (int index_x = 0; index_x < iWidth; index_x++)
{
UCHAR blue = (bitmap.buffer[(index_y+50)*SCREEN_WIDTH*3 + (index_x+50)*3 + 0]),
green = (bitmap.buffer[(index_y+50)*SCREEN_WIDTH*3 + (index_x+50)*3 + 1]),
red = (bitmap.buffer[(index_y+50)*SCREEN_WIDTH*3 + (index_x+50)*3 + 2]);
pos.x = index_x;
pos.y = index_y;
//无障碍
if ( blue >= CParam::BStepBegin && blue <= CParam::BStepEnd
&& green >= CParam::GStepBegin && green<= CParam::GStepEnd
&& red >= CParam::RStepBegin && red <= CParam::RStepEnd)
{
themap.buffer[(index_y+50)*SCREEN_WIDTH*3 + (index_x+50)*3 + 0] = 255;
themap.buffer[(index_y+50)*SCREEN_WIDTH*3 + (index_x+50)*3 + 1] = 255;
themap.buffer[(index_y+50)*SCREEN_WIDTH*3 + (index_x+50)*3 + 2] = 255;
m_Search->m_Map.setAccess( pos );
}
//有障碍
else
{
themap.buffer[(index_y+50)*SCREEN_WIDTH*3 + (index_x+50)*3 + 0] = 0;
themap.buffer[(index_y+50)*SCREEN_WIDTH*3 + (index_x+50)*3 + 1] = 0;
themap.buffer[(index_y+50)*SCREEN_WIDTH*3 + (index_x+50)*3 + 2] = 0;
m_Search->m_Map.setBlock (pos);
//blockCon.insert(pos); //保存障碍物坐标
}
}
}//end of for
}
CMap.cpp
__________________________________________________
#include "stdafx.h"
#include "CParam.h"
#include "CMap.h"
//析构函数
CMap::~CMap()
{
if(m_Map)
{
for(int i=0;i<m_Height;i++)
delete[] m_Map[i]; //释放空间
delete[] m_Map;
}
}
//载入地图(初始化障碍物容器,搜索者坐标容器)
void CMap::loadMap(set<Pos>& blockCon,vector<Pos>& actorPos)
{
ifstream file(CParam::loadMapName.c_str());
actorPos.clear();
blockCon.clear();
if(!file)
exit(1);
char tmp[50];
file>>m_Width>>m_Height; //读入地图宽,高
file>>tmp>>m_Block; //读入障碍物字符
file>>tmp>>m_Access; //读入通路字符
file>>tmp>>m_Actor; //读入搜索者字符
//建立地图
m_Map = new char* [m_Height];
Pos pos;
for(int i=0;i<m_Height;i++)
{
m_Map[i] = new char[m_Width+1];
/*file>>m_Map[i];
for(int j=0;j<m_Width;j++)
{
pos.x = j;
pos.y = i;
if(isBlock(pos))
blockCon.insert(pos); //保存障碍物坐标
if(isActor(pos))
actorPos.push_back(pos); //保存搜索者坐标
}*/
}
}
//保存地图
void CMap::saveMap()
{
//ofstream debug("debug.txt");
//debug<<CParam::loadMapName<<endl;
//debug<<CParam::saveMapName<<endl;
//debug<<CParam::oneBiasCost;
//ofstream file(CParam::saveMapName); //??
ofstream file("savemap.map");
if(!file)
exit(1);
file<<m_Width<<" "<<m_Height<<endl; //导出地图宽,高
file<<"Block: "<<m_Block<<endl;
file<<"Block: "<<m_Access<<endl;
file<<"Block: "<<m_Actor<<endl<<endl;
//导出地图
for(int i=0;i<m_Height;i++)
{
file<<m_Map[i]<<endl;
}
}
CParam.cpp
______________________________________________
#include "CParam.h"
string CParam::loadMapName; //载入地图的文件名
string CParam::saveMapName; //保存地图的文件名
int CParam::oneBiasCost = 0;
int CParam::oneNoBiasCost = 0;
int CParam::waitTime = 0;
int CParam::permitDisdance = 0;
int CParam::tryRoundBlock = 0;
int CParam::tryStartTimes = 0;
int CParam::startConSize = 0;
int CParam::startProHCost = 0;
int CParam::RStepBegin = 0;
int CParam::GStepBegin = 0;
int CParam::BStepBegin = 0;
int CParam::RStepEnd = 0;
int CParam::GStepEnd = 0;
int CParam::BStepEnd = 0;
int CParam::displayHight =0;
int CParam::displayWidth =0;
int CParam::displayX =0;
int CParam::displayY =0;
bool CParam::bDisOppo = false;
char* paramFileName = "param.ini"; //配置文件名
//构造函数
CParam::CParam()
{
ifstream file(paramFileName);
if(!file)
exit(1);
//ofstream debug("debug.txt");
char tmp[30];
file>>tmp>>loadMapName;
file>>tmp>>saveMapName;
//debug<<CParam::saveMapName.c_str();
file>>tmp>>oneBiasCost;
file>>tmp>>oneNoBiasCost;
file>>tmp>>waitTime;
file>>tmp>>permitDisdance;
file>>tmp>>tryRoundBlock;
file>>tmp>>tryStartTimes;
file>>tmp>>startConSize;
file>>tmp>>startProHCost;
//读入RGB的阀值
file>>tmp>>RStepBegin;
file>>tmp>>GStepBegin;
file>>tmp>>BStepBegin;
file>>tmp>>RStepEnd;
file>>tmp>>GStepEnd;
file>>tmp>>BStepEnd;
file>>tmp>> displayX ; //读入屏幕上显示的地图起点X
file>>tmp>> displayY ; //读入屏幕上显示的地图起点Y
file>>tmp>> displayWidth ; //读入屏幕显示的地图宽度
file>>tmp>> displayHight ; //读入屏幕显示的地图高度
}
CSearch.cpp
__________________________________________________________
#include "CSearch.h"
//构造函数
CSearch::CSearch()
{
vector<Pos> actorPos;
m_Map.loadMap(m_BlockCon,actorPos); //载入地图
//初始化搜索者
for(int i=0;i<actorPos.size();i++)
{
addActor(actorPos[i]);
setTargetPos(m_ActorCon.begin()+i,Pos(80,80));
}
}
//添加搜索者
void CSearch::addActor(const Pos& startPos)
{
int ID;
if (m_ActorCon.empty())
ID = 0;
else
ID = m_ActorCon.back().ID + 1;
m_ActorCon.push_back(CActor(ID,startPos,&m_Map));
m_Map.setActor(startPos);
}
//删除搜索者
void CSearch::delActor(const VI actor)
{
m_Map.setAccess(actor->m_NowPos);
m_ActorCon.erase(actor);
}
//设置搜索者目标点
bool CSearch::setTargetPos(const VI actor,const Pos& targetPos)
{
if(m_Map.isAccess(targetPos)==false)
return false;
actor->setTarget(targetPos);
actor->m_IsSearch = true;
return true;
}
//修改地图
void CSearch::changeMap(const Pos& pos)
{
if(m_Map.isAccess(pos)==true)
{
m_Map.setBlock(pos); //把通路改为障碍物
m_BlockCon.insert(pos); //插入障碍物容器
return;
}
if(m_Map.isBlock(pos)==true)
{
m_Map.setAccess(pos); //把障碍物改为通路
m_BlockCon.erase(pos); //从障碍物容器中删除
return;
}
}
//执行一次搜索方法
bool CSearch::runOneTimes()
{
VI iter;
bool bRet = false;
for (iter = m_ActorCon.begin(); iter != m_ActorCon.end(); ++iter)
{
if(iter->m_IsSearch==true)
{
bRet = true;
iter->run();
}
}
//Sleep(10);
return bRet;
}
//定位搜索者并返回搜索者的迭代器
bool CSearch::locateActor(const Pos& pos,VI& selectIter)
{
VI iter;
for (iter = m_ActorCon.begin(); iter != m_ActorCon.end();++iter)
{
if (abs(iter->m_NowPos.x-pos.x) < 5 && abs(iter->m_NowPos.y-pos.y) < 5)
{
selectIter = iter;
return true;
}
}
return false; //未定位到
}
DirectFunction.cpp
_____________________________________________
#include "DirectFunction.h"
//显示文字
int Draw_Text_GDI( LPDIRECTDRAWSURFACE7& lpdds,char *text, int x,int y, COLORREF color)
{
HDC hdc;
if (FAILED(lpdds->GetDC(&hdc) ) )
{ return 0; }
SetTextColor(hdc,color);
SetBkMode(hdc, TRANSPARENT);
TextOut(hdc,x,y,text,strlen(text));
if(lpdds) //释放dc
{ lpdds->ReleaseDC(hdc); }
return(1);
}
//画直线
void Draw_Line ( LPDIRECTDRAWSURFACE7& lpdds,int Ax,int Ay, int Bx,int By, int penWidth ,int penStyle ,COLORREF color )
{
HDC hdc;
if (FAILED(lpdds->GetDC(&hdc) ) )
{ return ; }
HPEN hpen=CreatePen( penStyle,penWidth,color );
SelectObject(hdc, hpen);
MoveToEx(hdc,Ax,Ay,NULL);
LineTo(hdc,Bx,By);
DeleteObject( hpen);
if(lpdds) //释放dc
{ lpdds->ReleaseDC(hdc); }
}
/*
//载入图像
bool Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)
{
int file_handle; // 文件句柄
UCHAR *temp_buffer = NULL;
OFSTRUCT file_data; //文件数据信息
//一下一段代码读取文件信息
if ((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)
{ return(0);}
_lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));
if (bitmap->bitmapfileheader.bfType!=BITMAP_ID)
{
_lclose(file_handle);
return(0);
}
//一下一段代码读取位图信息
// 载入文件位图文件头
_lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));
// 位图数据
_lseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);
if (bitmap->bitmapinfoheader.biBitCount==8 || bitmap->bitmapinfoheader.biBitCount==16 ||
bitmap->bitmapinfoheader.biBitCount==24)
{
if (bitmap->buffer)
{ delete [](bitmap->buffer);}
if (!(bitmap->buffer = (UCHAR *)new UCHAR[bitmap->bitmapinfoheader.biSizeImage] ))
{
_lclose(file_handle);
return(0);
}
_lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);
}
else
{ return(0); }
_lclose(file_handle);
Flip_Bitmap(bitmap->buffer,
bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8),
bitmap->bitmapinfoheader.biHeight);
return(1);
}
//卸载图像
bool Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)
{
if (bitmap->buffer)
{
delete[]bitmap->buffer;
bitmap->buffer = NULL;
}
return(1);
}
//获取位图信息
bool Flip_Bitmap(UCHAR *image, int bytes_per_line, int height)
{
UCHAR *buffer;
int index; // looping index
if (!(buffer = (UCHAR *)new UCHAR[bytes_per_line*height] ) )
{ return(0);}
// 拷贝位图到工作区
memcpy(buffer,image,bytes_per_line*height);
for (index=0; index < height; index++)
{
memcpy(&image[((height-1) - index)*bytes_per_line],
&buffer[index*bytes_per_line], bytes_per_line);
}
delete []buffer;
return (1);
}
*/
bool Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)
{
int file_handle, // 文件句柄
index; //文件数据信息
UCHAR *temp_buffer = NULL; // used to convert 24 bit images to 16 bit
OFSTRUCT file_data; // the file data information
if ((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)
return(0);
_lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));
if (bitmap->bitmapfileheader.bfType!=BITMAP_ID)
{
_lclose(file_handle);
return(0);
}
//下一段代码读取位图信息
// 载入文件位图文件头
_lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));
if (bitmap->bitmapinfoheader.biBitCount == 8)
{
_lread(file_handle, &bitmap->palette,256*sizeof(PALETTEENTRY) );
for (index=0; index <256; index++)
{
int temp_color = bitmap->palette[index].peRed;
bitmap->palette[index].peRed = bitmap->palette[index].peBlue;
bitmap->palette[index].peBlue = temp_color;
bitmap->palette[index].peFlags = PC_NOCOLLAPSE;
}
}
_lseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);
if (bitmap->bitmapinfoheader.biBitCount==8 || bitmap->bitmapinfoheader.biBitCount==16 ||
bitmap->bitmapinfoheader.biBitCount==24)
{
// if (bitmap->buffer)
//{ delete [](bitmap->buffer);}
if (!(bitmap->buffer = new UCHAR[bitmap->bitmapinfoheader.biSizeImage] ))
{
_lclose(file_handle);
return(0);
}
_lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);
}
else
{ return(0); }
_lclose(file_handle);
Flip_Bitmap(bitmap->buffer,
bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8),
bitmap->bitmapinfoheader.biHeight);
return(1);
}
//卸载图像///
bool Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)
{
if (bitmap->buffer)
{
delete [](bitmap->buffer);
bitmap->buffer = NULL;
}
return(1);
}
//获取位图信息///
bool Flip_Bitmap( UCHAR *image, int bytes_per_line, int height)
{
UCHAR *buffer;
int index;
buffer = new UCHAR[bytes_per_line*height] ;
memcpy(buffer,image,bytes_per_line*height);
for (index=0; index < height; index++)
{
memcpy(&image[((height-1) - index)*bytes_per_line],&buffer[index*bytes_per_line], bytes_per_line);
}
delete []buffer;
return(1);
}
main.cpp
_________________________________________________
#pragma once
#include "CParam.h"
#include "CDraw.h"
#include "CControl.h"
#include "CSearch.h"
#include "resource.h"
bool bDisplay = true;
CParam param;
CSearch* pSearch = new CSearch();
CControl control(pSearch);
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
PAINTSTRUCT ps;
HDC hdc;
char buffer[80];
control.readMeasage ( hwnd, msg, wparam, lparam);
switch(msg)
{
case WM_CREATE:
{
return(0);
} break;
case WM_PAINT:
{
hdc = BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
return(0);
} break;
case WM_DESTROY:
{
bDisplay = false;
delete pSearch; //释放内存
PostQuitMessage(0);
return(0);
} break;
default:break;
}
return (DefWindowProc(hwnd, msg, wparam, lparam));
}
// 主函数
int WINAPI WinMain( HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)
{
WNDCLASSEX winclass; // this will hold the class we create
MSG msg; // generic message
HWND hwnd;
winclass.cbSize = sizeof(WNDCLASSEX);
winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance;
winclass.hIcon = LoadCursor(hinstance, "CICON" );
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = WINDOW_CLASS_NAME;
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
hinstance_app = hinstance; //保存全局实例
if (!RegisterClassEx(&winclass))
return(0);
if (!(hwnd = CreateWindowEx(NULL,
WINDOW_CLASS_NAME,
"瓜西西A*",
// WS_POPUP | WS_VISIBLE,
WS_OVERLAPPED |WS_VISIBLE| WS_SYSMENU ,
0,0,
SCREEN_WIDTH,SCREEN_HEIGHT,
NULL,
NULL,
hinstance,
NULL)))
return(0);
main_windows_hwnd = hwnd ;
CDraw draw(hwnd, pSearch,&control);
control.setDrawArea(draw.getDrawArea() );
while(TRUE)
{
if (PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
{
if(!GetMessage(&msg, NULL, 0, 0 )) return int(msg.wParam);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(control.m_IsSearch ==true)
{
if(!pSearch->runOneTimes())
{
Sleep(100);
}
}
if (bDisplay == true)
{
draw.display();
}
}
return(msg.wParam);
}
param.ini
______________________________________________
loadMapName: loadmap.map
saveMapName: savemap.map
oneBiasCost: 7
oneNoBiasCost: 5
waitTime: 5
permitDisdance: 150
tryRoundBlock: 5
tryStartTimes: 3
startConSize: 1000
startProHCost: 250
RStepBegin: 150
GStepBegin: 80
BStepBegin: 20
RStepBegin: 230
GStepBegin: 230
BStepBegin: 230
displayX: 50
displayY: 50
displayWidth: 500
displayHight: 500
loadmap.map
______________________________________________
500 500
Block: 0
Block: 1
Block: 2
2222222222222222222222222222222222222222111111111122222222222222222222222222222222222222221111111111
2222222222222222222222222222211111111111111111111122222222222222222222222222222222222222222111111111
2222200002211110000011111110000011111100000000111122222000022111100000111111100000111111000000001111
2220001100211100111001111100222001111001111110011122200011002111001110011111002220011110011111100111
2220111110011101111100111002222200110011111111011122201111100111011111001110022222001100111111110111
2220111111000111111110010022222220010111111111111122201111110001111111100100222222200101111111111111
2220111110010100101011000222222222010110000011111122201111100101001010110002222222220101100000111111
2222222200110101101011111222222222010100122001111122222222001101011010111112222222220101001220011111
2222222001110100100000111222222122010101222200111122222220011101001000001112222221220101012222001111
1111110011110110111111000222222211010112122220011111111100111101101111110002222222110101121222200111
1111100111110100111111010222222222010112222222011111111001111101001111110102222222220101122222220111
1111001111010011111110010022222220010011222220011111110011110100111111100100222222200100112222200111
1110011111011001111100111002222200111001222100111111100111110110011111001110022222001110012221001111
1110111111011100111001111100222001111100111001111111101111110111001110011111002220011111001110011111
1110000000011110000011111110000011111110000011111111100000000111100000111111100000111111100000111111
2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
0110000000000000000000000000000000000000000000111101100000000000000000000000000000000000000000000000
0111111111111110111111110111110111111111111110111101100000000000000000000000000000000000000000001111
0111111111111110111111110111110111111111111110111101100000000000000000000000000000000000000000001111
0110000000000110110110110110110000111000000110111101100000000000000000000000000000000000000000001111
0111111111110111110110111110111110111110110110111101100000000000000000000000000000000000000000001111
0111111111110111110110111110111110111110110110111101100000000000000000000000000000000000000000001111
0000000110000000000110000000001110000110110110111101100000000000000000000000000000000000000000001111
0111110110111110110110110111111111111110111110111101100000000000000000000000000000000000000000001111
0111110110111110110110110111111111111110111110111101100000000000000000000000000000000000000000001111
0110110110110110110110111110000000000000000110111101100000000000000000000000000000000000000000001111
0110110110110110110110111110110111110111110110111101100000000000000000000000000000000000000000001111
0110110110110110110110111110110111110111110110111101100000000000000000000000000000000000000000001111
0110110110110110110110110000110110110110110110111101100000000000000000000000000000000000000000001111
0110111110110110110110111111110110111110110110111101100000000000000000000000000000000000000000001111
0110111110110110110110111111110110111110110110111101100000000000000000000000000000000000000000001111
0110000000110110110110000000000110000000110110111100000000000000000000000000000000000000000000001111
0111111110110111110111111111111111110111110110111100100000000000000000000000000000000000000000001111
0111111110110111110111111111111111110111110110110001100000000000000000000000000000000000000000001111
0000000110110000000110000000000000110110000000000001100000000000000000000000000000000000000000001111
0111110110111111110110111110111110110111111110111101111101101111111101101111101111101101111111101111
0111110110111111110110111110111110110111111110111101111101101111111101101111101111101101111111101111
0110110000000001110110110000110110000000110110111101111101101111111101101111101111101101111111101111
0110111111111111110110110111110111111110110110111101111101101111111101101111101111101101111111101111
0110111111111111110110110111110111111110110110111101111101101111111101101111101111101101111111101111
0110000000000000000110110110000000000110000110111101111101101111111101101111101111101101111111101111
0110111111111111110111110110111111110111111110111101111101101111111101101111101111101101111111101111
0110111111111111110111110110111111110111111110111101111101101111111101101111101111101101111111101111
0110000110000000110000000110110000110000000110111101111101101111111101101111101111101101111111101111
0111111110111111111111111110111110111111111111111101111101101111111101101111101111101101111111101111
0111111110111111111111111110111110111111111111111101111101101111111101101111101111101101111111101111
0000000000000000000000000000000000000000000000111101111101101111111101101111101111101101111111101111
2222222222222222222222222222222222222222111111111101111101101111111101101111101111101101111111101111
2222222222222222222222222222222222222222211111111101111101101111111101101111101111101101111111101111
2222200002211110000011111110000011111100000000111101111101101111111101101111101111101101111111101111
2220001100211100111001111100222001111001111110011101111101101111111101101111101111101101111111101111
2220111110011101111100111002222200110011111111011101111101101111111101101111101111101101111111101111
2220111111000111111110010022222220010111111111111101111101101111111101101111101111101101111111101111
2220111110010100101011000222222222010110000011111101111101101111111101101111101111101101111111101111
2222222200110101101011111222222222010100122001111101111101101111111101101111101111101101111111111111
2222222001110100100000111222222122010101222200111101111101101111111111111111101111101111111111111111
1111110011110110111111000222222211010112122220011101111101101111111111111111111111111111111111111111
1111100111110100111111010222222222010112222222011101111101101111111111111111111111111111111111111111
1111001111010011111110010022222220010011222220011101111101101111111111111111111111111111111111111111
1110011111011001111100111002222200111001222100111101111101101111111111111111111111111111111111111111
1110111111011100111001111100222001111100111001111101111101101111111111111111111111111111111111111111
1110000000011110000011111110000011111110000011111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
0110000000000000000000000000000000000000000000111111111111111111111111111111111111111111111111111111
0111111111111110111111110111110111111111111110111111111111111111111111111111111111111111111111111111
0111111111111110111111110111110111111111111110111111111111111111111111111111111111111111111111111111
0110000000000110110110110110110000111000000110111111111111111111111111111111111111111111111111111111
0111111111110111110110111110111110111110110110111111111111111111111111111111111111111111111111111111
0111111111110111110110111110111110111110110110111111111111111111111111111111111111111111111111111111
0000000110000000000110000000001110000110110110111111111111111111111111111111111111111111111111111111
0111110110111110110110110111111111111110111110111111111111111111111111111111111111111111111111111111
0111110110111110110110110111111111111110111110111111111111111111111111111111111111111111111111111111
0110110110110110110110111110000000000000000110111111111111111111111111111111111111111111111111111111
0110110110110110110110111110110111110111110110111111111111111111111111111111111111111111111111111111
0110110110110110110110111110110111110111110110111111111111111111111111111111111111111111111111111111
0110110110110110110110110000110110110110110110111111111111111111111111111111111111111111111111111111
0110111110110110110110111111110110111110110110111111111111111111111111111111111111111111111111111111
0110111110110110110110111111110110111110110110111111111111111111111111111111111111111111111111111111
0110000000110110110110000000000110000000110110111111111111111111111111111111111111111111111111111111
0111111110110111110111111111111111110111110110111111111111111111111111111111111111111111111111111111
0111111110110111110111111111111111110111110110111111111111111111111111111111111111111111111111111111
0000000110110000000110000000000000110110000000001111111111111111111111111111111111111111111111111111
0111110110111111110110111110111110110111111110111111111111111111111111111111111111111111111111111111
0111110110111111110110111110111110110111111110111111111111111111111111111111111111111111111111111111
0110110000000001110110110000110110000000110110111111111111111111111111111111111111111111111111111111
0110111111111111110110110111110111111110110110111111111111111111111111111111111111111111111111111111
0110111111111111110110110111110111111110110110111111111111111111111111111111111111111111111111111111
0110000000000000000110110110000000000110000110111101111111101111111111111111111111111111111111111111
0110111111111111110111110110111111110111111110111101111111101111111111111111111111111111111111111111
0110111111111111110111110110111111110111111110111101111111101111111111111111111111111111111111111111
0110000110000000110000000110110000110000000110111101111111101111111111111111111111111111111111111111
0111111110111111111111111110111110111111111111111101111111101111111111111111111111111111111111111111
0111111110111111111111111110111110111111111111111101111111101111111111111111111111111111111111111111
0000000000000000000000000000000000000000000000111101111111101111111111111111111111111111111111111111