您的位置:首页 > 其它

A星算法(VC版源码)

2015-07-18 09:38 471 查看
源码不是我写的,如有侵权,请联系我,更改版权

使用方法:

对于空地左键单击后会产生障碍,对障碍左键单击会消除障碍,对于起点,两次左键盘单击会消除起点,如果不存在起点,单击右键会产生起点,如果存在起点不存在终点,单击右键会产生终点,如果既存在起点又存在终点,单击右键会消除终点,点击开始寻路回画出路径

效果图:





C++源码:

<pre name="code" class="cpp">#include ".\astart.h"
#include "List.cpp"
#include <math.h>
Astart::Astart(int a[37][64],int w,int l,int s,int e)
{
	for(int i=0; i<l; i++)
	{
		for(int j=0; j<w; j++)
		{
			map[i][j] = a[i][j];
		}
	}
	WIDTH = w;
	start = s;
	end = e;
	LENGTH = l;
	rect = new Rect[WIDTH*LENGTH];
	for(int i=0; i<WIDTH*LENGTH; i++)
	{
		rect[i].map_x = i%WIDTH;
		rect[i].map_y = i/WIDTH;
	}
	rect[start].g_value = 0;
	rect[start].pre = NULL;
}

Astart::~Astart(void)
{
}

//寻路算法核心
bool Astart::FindFastWay()
{
	//关闭集合为空
	if(close_list.IsEmpty())
	{
		//出发点下边的节点,此点必须在地图内,出发点下边还有路(不能是地图边界)
		if((start+WIDTH)/WIDTH < LENGTH && (start+WIDTH)/WIDTH >=0 && (start+WIDTH)%WIDTH >= 0 && (start+WIDTH)%WIDTH < WIDTH && start/WIDTH != LENGTH-1)
		{
			//此点不是障碍物
			if( map[(start+WIDTH)/WIDTH][(start+WIDTH)%WIDTH]!=1 )
			{
				//修改该节点的各个值
				rect[start+WIDTH].pre = &rect[start];
				rect[start+WIDTH].h_value = get_h_value(start+WIDTH);
				rect[start+WIDTH].g_value = get_g_value(start+WIDTH);

				//插入到开放节点
				open_list.Insert(open_list.Length(),start+WIDTH);
			}
		}
		//出发点上边的节点,此点必须在地图内,出发点上边还有路(不能是地图边界)
		if((start-WIDTH)/WIDTH < LENGTH && (start-WIDTH)/WIDTH >=0 && (start-WIDTH)%WIDTH >= 0 && (start-WIDTH)%WIDTH < WIDTH && (start/WIDTH) != 0)
		{
			//此点不是障碍物
			if( map[(start-WIDTH)/WIDTH][(start-WIDTH)%WIDTH]!=1)
			{
				//修改该节点的各个值
				rect[start-WIDTH].pre = &rect[start];
				rect[start-WIDTH].h_value = get_h_value(start-WIDTH);
				rect[start-WIDTH].g_value = get_g_value(start-WIDTH);

				//插入到开放节点
				open_list.Insert(open_list.Length(),start-WIDTH);
			}
		}
		//出发点右边的节点,此点必须在地图内,出发点右边还有路(不能是地图边界)
		if((start+1)/WIDTH < LENGTH && (start+1)/WIDTH >=0 && (start+1)%WIDTH >= 0 && (start+1)%WIDTH < WIDTH && start!= start/WIDTH * WIDTH + WIDTH-1)
		{
			//此点不是障碍物
			if( map[(start+1)/WIDTH][(start+1)%WIDTH]!=1)
			{
				//修改该节点的各个值
				rect[start+1].pre = &rect[start];
				rect[start+1].h_value = get_h_value(start+1);
				rect[start+1].g_value = get_g_value(start+1);

				//插入到开放节点
				open_list.Insert(open_list.Length(),start+1);
			}
		}
		//出发点左边的节点,此点必须在地图内,出发点左边还有路(不能是地图边界)
		if((start-1)/WIDTH < LENGTH && (start-1)/WIDTH >=0 && (start-1)%WIDTH >= 0 && (start-1)%WIDTH < WIDTH && start%WIDTH!=0)
		{
			//此点不是障碍物
			if( map[(start-1)/WIDTH][(start-1)%WIDTH]!=1)
			{
				//修改该节点的各个值
				rect[start-1].pre = &rect[start];
				rect[start-1].h_value = get_h_value(start-1);
				rect[start-1].g_value = get_g_value(start-1);

				//插入到开放节点
				open_list.Insert(open_list.Length(),start-1);
			}
		}

		//起始节点加入到关闭节点
		close_list.Insert(close_list.Length(),start);
	}

	//////////////////////////////////////////////////////////////////////////
	//循环遍历所有在开放列表的所有节点
	int i = 0;								//最小评估值在开放列表中的标号
	int rectMinEstimateValue = -1;			//最小评估值
	int stepRectID = 0;						//下一步选择的节点
	for(int z=1; z<=open_list.Length(); z++)
	{
		int rectID;							//节点代号
		int rectEstimateValue;				//节点的评估值
		open_list.Find(z, rectID);			//获得开放列表中的节点代号
		rectEstimateValue = rect[rectID].h_value +  rect[rectID].g_value;

		if(rectMinEstimateValue == -1)//第一个节点
		{
			rectMinEstimateValue = rectEstimateValue;
		}
		if(rectEstimateValue <= rectMinEstimateValue)//获得更小节点
		{
			i = z;
			rectMinEstimateValue = rectEstimateValue;
			stepRectID = rectID;
		}
	}
	//没有找到节点
	if(i==0)	return false;

	//从开放列表删除该节点,并插入到关闭列表里面
	int temp;
	open_list.Delete(i, temp);
	close_list.Insert(close_list.Length(),stepRectID);

	//最小评估值节点下边的节点,此点必须在地图内,该节点下边还有路(不能是地图边界)
	if((stepRectID+WIDTH)/WIDTH < LENGTH && (stepRectID+WIDTH)/WIDTH >=0 && (stepRectID+WIDTH)%WIDTH >= 0 && (stepRectID+WIDTH)%WIDTH < WIDTH && (stepRectID/WIDTH) != LENGTH-1)
	{
		//该节点是目标节点
		if(stepRectID+WIDTH == end)
		{
			rect[stepRectID+WIDTH].pre = &rect[stepRectID];
			return true;
		}
		//该节点不是障碍物
		if( map[(stepRectID+WIDTH)/WIDTH][(stepRectID+WIDTH)%WIDTH]!=1 )
		{
			//该节点不在关闭列表里面
			if(close_list.Search(stepRectID+WIDTH) == 0)
			{
				//该节点不在开放节点里面,就加入到开放节点里
				if(open_list.Search(stepRectID+WIDTH) == 0)
				{
					//修改该节点的值
					rect[stepRectID+WIDTH].pre = &rect[stepRectID];
					rect[stepRectID+WIDTH].h_value = get_h_value(stepRectID+WIDTH);
					rect[stepRectID+WIDTH].g_value = get_g_value(stepRectID+WIDTH);
					//加入到开放节点
					open_list.Insert(open_list.Length(),stepRectID+WIDTH);
				}
				else
				{
					//如果该节点已存在开放列表里面,并且,通过刚刚一路走过来的路要比以前的路更近,则更新该节点的值
					if(rect[stepRectID].g_value + 10 < rect[stepRectID+WIDTH].g_value)
					{
						//设置该节点的父节点
						rect[stepRectID+WIDTH].pre = &rect[stepRectID];

						//刷新实际到这里的值
						rect[stepRectID+WIDTH].g_value = get_g_value(stepRectID+WIDTH);
					}
				}
			}
		}
	}

	//最小评估值节点上边的节点,此点必须在地图内,该节点上边还有路(不能是地图边界)
	if((stepRectID-WIDTH)/WIDTH < LENGTH && (stepRectID-WIDTH)/WIDTH >=0 && (stepRectID-WIDTH)%WIDTH >= 0 && (stepRectID-WIDTH)%WIDTH < WIDTH && (stepRectID/WIDTH) != 0)
	{
		//该节点是目标节点
		if(stepRectID-WIDTH == end)
		{
			rect[stepRectID-WIDTH].pre = &rect[stepRectID];
			return true;
		}
		//该节点不是障碍物
		if( map[(stepRectID-WIDTH)/WIDTH][(stepRectID-WIDTH)%WIDTH]!=1)
		{
			//该节点不在关闭列表里面
			if(close_list.Search(stepRectID-WIDTH) == 0)
			{
				//该节点不在开放节点里面,就加入到开放节点里
				if(open_list.Search(stepRectID-WIDTH) == 0)
				{
					//修改该节点的值
					rect[stepRectID-WIDTH].pre = &rect[stepRectID];
					rect[stepRectID-WIDTH].h_value = get_h_value(stepRectID-WIDTH);
					rect[stepRectID-WIDTH].g_value = get_g_value(stepRectID-WIDTH);
					//加入到开放节点
					open_list.Insert(open_list.Length(),stepRectID-WIDTH);
				}
				else
				{
					//如果该节点已存在开放列表里面,并且,通过刚刚一路走过来的路要比以前的路更近,则更新该节点的值
					if(rect[stepRectID].g_value + 10 < rect[stepRectID-WIDTH].g_value)
					{
						//设置该节点的父节点
						rect[stepRectID-WIDTH].pre = &rect[stepRectID];

						//刷新实际到这里的值
						rect[stepRectID-WIDTH].g_value = get_g_value(stepRectID-WIDTH);
					}
				}
			}
		}
	}

	//最小评估值节点右边的节点,此点必须在地图内,该节点右边还有路(不能是地图边界)
	if((stepRectID+1)/WIDTH < LENGTH && (stepRectID+1)/WIDTH >=0 && (stepRectID+1)%WIDTH >= 0 && (stepRectID+1)%WIDTH < WIDTH && stepRectID!= stepRectID/WIDTH * WIDTH + WIDTH-1)
	{
		//该节点是目标节点
		if(stepRectID+1 == end)
		{
			rect[stepRectID+1].pre = &rect[stepRectID];
			return true;
		}
		//该节点不是障碍物
		if( map[(stepRectID+1)/WIDTH][(stepRectID+1)%WIDTH]!=1)
		{
			//该节点不在关闭列表里面
			if(close_list.Search(stepRectID+1) == 0)
			{
				//该节点不在开放节点里面,就加入到开放节点里
				if(open_list.Search(stepRectID+1) == 0)
				{
					//修改该节点的值
					rect[stepRectID+1].pre = &rect[stepRectID];
					rect[stepRectID+1].h_value = get_h_value(stepRectID+1);
					rect[stepRectID+1].g_value = get_g_value(stepRectID+1);
					//加入到开放节点
					open_list.Insert(open_list.Length(),stepRectID+1);
				}
				else
				{
					//如果该节点已存在开放列表里面,并且,通过刚刚一路走过来的路要比以前的路更近,则更新该节点的值
					if(rect[stepRectID].g_value + 10 < rect[stepRectID+1].g_value)
					{
						//设置该节点的父节点
						rect[stepRectID+1].pre = &rect[stepRectID];

						//刷新实际到这里的值
						rect[stepRectID+1].g_value = get_g_value(stepRectID+1);
					}
				}
			}
		}
	}

	//最小评估值节点左边的节点,此点必须在地图内,该节点左边还有路(不能是地图边界)
	if((stepRectID-1)/WIDTH < LENGTH && (stepRectID-1)/WIDTH >=0 && (stepRectID-1)%WIDTH >= 0 && (stepRectID-1)%WIDTH < WIDTH  && stepRectID%WIDTH!=0)
	{
		//该节点是目标节点
		if(stepRectID-1 == end)
		{
			rect[stepRectID-1].pre = &rect[stepRectID];
			return true;
		}
		//该节点不是障碍物
		if( map[(stepRectID-1)/WIDTH][(stepRectID-1)%WIDTH]!=1)
		{
			//该节点不在关闭列表里面
			if(close_list.Search(stepRectID-1) == 0)
			{
				//该节点不在开放节点里面,就加入到开放节点里
				if(open_list.Search(stepRectID-1) == 0)
				{
					//修改该节点的值
					rect[stepRectID-1].pre = &rect[stepRectID];
					rect[stepRectID-1].h_value = get_h_value(stepRectID-1);
					rect[stepRectID-1].g_value = get_g_value(stepRectID-1);
					//加入到开放节点
					open_list.Insert(open_list.Length(),stepRectID-1);
				}
				else
				{
					//如果该节点已存在开放列表里面,并且,通过刚刚一路走过来的路要比以前的路更近,则更新该节点的值
					if(rect[stepRectID].g_value + 10 < rect[stepRectID-1].g_value)
					{
						//设置该节点的父节点
						rect[stepRectID-1].pre = &rect[stepRectID];

						//刷新实际到这里的值
						rect[stepRectID-1].g_value = get_g_value(stepRectID-1);
					}
				}
			}
		}
	}

	//进行递归
	return FindFastWay();
}

//距离目标的评估值
int Astart::get_h_value(int i)
{
	return ((abs(end/WIDTH - i/WIDTH) + abs(end%WIDTH - i%WIDTH)) * 10);
}

//距离出发源的实际值
int Astart::get_g_value(int i)
{
	return (rect[i].pre->g_value + 10);
}

//获取路线结果
void Astart::GetResult()
{
	Rect *p = &rect[end];
	while(p != NULL)
	{
		value_list.Insert(value_list.Length(),*p);
		p = p->pre;
	}
}




#include "List.h"
#pragma once
class Rect
{
public:
	int map_x;
	int map_y;
	int h_value;
	int g_value;
	Rect *pre;
};

class Astart
{
public:
	Astart(int a[37][64],int w,int l,int s,int e);
	~Astart(void);
	bool Find();
	int get_h_value(int i);
	int get_g_value(int i);
	void GetResult();
	int map[37][64];
	Rect  *rect;
	List<Rect> value_list;
private:
	int WIDTH;
	int LENGTH;
	int start;
	int end;
	List<int> open_list;
	List<int> close_list;
};


#include "list.h"
template <class Type> List<Type>::~List()
{
	length = 0;
	delete pHead;
	pHead = NULL;
}
template <class Type> List<Type>::List()
{
	length = 0;
	pHead = NULL;
}
template <class Type> void List<Type>::Insert(int k, const Type & intnum)
{
	if(k==0)
	{
		if(length == 0)
		{
			pHead = new Node<Type>;
			pHead->contents = intnum;
			length++;
		}
		else
		{
			Node<Type> *p= new Node<Type>;
			p->contents = intnum;
			p->next=pHead;
			pHead=p;
			length++;
		}
	}
	else if(k==length)
	{
		Node<Type> *temp = pHead;
		for (int i=0;i<k-1;i++)
		{
			temp = temp->next;
		}
		Node<Type> *newNode = new Node<Type>;
		newNode->contents = intnum;
		newNode->next = NULL;
		temp->next = newNode;
		length++;
	}
	else
	{
		Node<Type> *temp = pHead;
		for (int i=0;i<k-1;i++)
		{
			temp = temp->next;
		}
		Node<Type> *newNode = new Node<Type>;
		newNode->contents = intnum;
		newNode->next = temp->next;
		temp->next = newNode;
		length++;
	}
}

template <class Type> void List<Type>::ShowListNode()
{
	if(length == 0)
	{
		cout<<"空表";
	}
	else
	{                                           
		Node<Type> *temp = pHead;
		for(int i=0;i<length;i++)
		{
			cout<<"节点"<<i+1<<": "<<temp->contents<<endl;
			if(i!=length-1)
			{
				temp = temp->next;
			}
		}
	}
}

template <class Type> void List<Type>::Delete(int k, Type & intnum)
{
	Node<Type> *temp = pHead;
	if(k==1 && k==length)
	{
		delete pHead;
		pHead = NULL;
	}
	else if(k==1)
	{
		pHead = pHead->next;
		delete temp;
	}
	else if(k==length)
	{
		for(int i=0; i<length-2; i++)
		{
			temp = temp->next;
		}
		delete temp->next;
		temp->next = NULL;
	}
	else
	{
		for (int i=0; i<k-1; i++)
		{
			temp = temp->next;
		}
		intnum = temp->contents;
		for(int i=k; i<length;i++)
		{
			temp->contents = temp->next->contents;
			if(i != length-1)
			{
				temp = temp->next;
			}
			else
			{
				delete temp->next;
				temp->next = NULL;
				break;
			}

		}
	}
	length--;
}
template <class Type> bool List<Type>::Find(int k, Type & intnum) const
{
	if(k > length)
		return false;
	else
	{
		Node<Type> *temp = pHead ;
		for (int i=0; i<k-1; i++)
		{
			temp = temp->next;
		}
		intnum = temp->contents;
		return true;
	}
}
template <class Type> int List<Type>::Search(const Type & intnum) const
{
		Node<Type> *temp = pHead;
		for (int i=0; i<length; i++)
		{
			if(temp->contents == intnum)
			{
				return i+1;
			}
			if(i != length-1)
			temp = temp->next;
		}
		return 0;
}
template <class Type> void List<Type>::Modify(int k,const Type &intnum)
{
	Node<Type> *temp = pHead ;
	for (int i=0; i<k-1; i++)
	{
		temp = temp->next;
	}
	temp->contents = intnum;
}


#pragma once
#include "list.h"
#include <iostream>
using namespace std;
template <class Type> class List;
template <class Type> class Node
{
	Type contents;
	Node * next;
	friend List<Type>;
};
template <class Type> class List
{
public:
	List();
	~List();
	bool IsEmpty() const {return (pHead==NULL) ? true : false;}//判断链表是否为空
	int Length() const {return length;} //返回链表中的元素总数
	bool Find(int k, Type & intnum) const; //寻找链表中的第k个元素,并将其传送至intnum
	int Search(const Type & intnum) const; //寻找intnum,如果发现intnum,则返回intnum的位置,如果intnum不在链表中,则返回0
	void Delete(int k, Type & intnum); //把第k个元素取至intnum,然后从链表中删除第k个元素
	void Insert(int k, const Type &intnum); //在第k个元素之后插入intnum
	void Modify(int k,const Type &intum);//将第k个元素的值修改为intnum
	void ShowListNode(); //显示输出链表的所有数据
private:
	Node<Type> *pHead;
	int length;
};


// tt3.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "tt3.h"
#include <stdio.h>
#include <fstream>
#include "Astart.h"
#include "List.h"
#include "List.cpp"
using namespace std;

#define MAX_LOADSTRING 100

// 全局变量:
HINSTANCE hInst;								// 当前实例
TCHAR szTitle[MAX_LOADSTRING];					// 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];			// 主窗口类名

// 此代码模块中包含的函数的前向声明:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

///////////////////////////////////////////////////////////////////////////////////
HDC hdc;															//设备描述
HWND hWnd;															//窗口句柄
HPEN pen,bluepen,greenpen,redpen;									//画笔
HBRUSH bluebrush,greenbrush,redbrush;								//画刷
int map[37][64];													//地图数组
bool start = false,over = false;									//开始结束是否被标记
int begin = 0,end = 0;												//开始结束位置

#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
///////////////////////////////////////////////////////////////////////////////////
//读取上次地图
void ReadMap()
{
	ifstream in("try.map");
	for(int i=0;i<37;i++)
	{
		for(int j=0;j<64;j++)
		{
			in>>map[i][j];
		}
	}
	in.close();
}

//刷新
void Update()
{
	SelectObject(hdc,pen);
	for(int i=0;i<=37*20;i+=20)
	{
		MoveToEx(hdc,0,i,NULL);
		LineTo(hdc,1280,i);
	}
	for(int i=0;i<=1280;i+=20)
	{
		if(i==1280)
		{
			MoveToEx(hdc,i-1,0,NULL);
			LineTo(hdc,i-1,740);
		}
		else
		{
			MoveToEx(hdc,i,0,NULL);
			LineTo(hdc,i,740);
		}
	}
	for(int i=0;i<37;i++)
	{
		for(int j=0;j<64;j++)
		{
			int x = j*20;
			int y = i*20;
			if(map[i][j] == 1)
			{
				SelectObject(hdc,bluepen);
				SelectObject(hdc,bluebrush);
				if(x == 63*20)
				{
					Rectangle(hdc,x+1,y+1,x+19,y+20);
				}
				else
				{
					Rectangle(hdc,x+1,y+1,x+20,y+20);
				}
			}
			else if(map[i][j] == 2)
			{
				SelectObject(hdc,greenpen);
				SelectObject(hdc,greenbrush);
				if(x == 63*20)
				{
					Rectangle(hdc,x+1,y+1,x+19,y+20);
				}
				else
				{
					Rectangle(hdc,x+1,y+1,x+20,y+20);
				}
				start = true;
				begin = i*64 + j;
			}
			else if(map[i][j] == 3)
			{
				SelectObject(hdc,redpen);
				SelectObject(hdc,redbrush);
				if(x == 63*20)
				{
					Rectangle(hdc,x+1,y+1,x+19,y+20);
				}
				else
				{
					Rectangle(hdc,x+1,y+1,x+20,y+20);
				}
				over = true;
				end = i*64 + j;
			}
		}
	}
}

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: 在此放置代码。
	MSG msg;
	HACCEL hAccelTable;

	// 初始化全局字符串
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_TT3, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// 执行应用程序初始化:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TT3));

	///////////////////////////////////////////////////////////////////////////////////////////////////////
	//加载地图
	for(int i=0;i<37;i++)
	{
		for(int j=0;j<64;j++)
		{
			map[i][j] = 0;
		}
	}
	ReadMap();

	//背景绘制
	hdc = GetDC(hWnd);
	pen = ::CreatePen(PS_SOLID,1,RGB(255,255,255));
	bluepen = ::CreatePen(PS_SOLID,1,RGB(0,0,255));
	greenpen = ::CreatePen(PS_SOLID,1,RGB(0,255,0));
	redpen = ::CreatePen(PS_SOLID,1,RGB(255,0,0));
	bluebrush = ::CreateSolidBrush(RGB(0,0,255));
	greenbrush = ::CreateSolidBrush(RGB(0,255,0));
	redbrush = ::CreateSolidBrush(RGB(255,0,0));
	SelectObject(hdc,pen);
	for(int i=0;i<=37*20;i+=20)
	{
		MoveToEx(hdc,0,i,NULL);
		LineTo(hdc,1280,i);
	}
	for(int i=0;i<=1280;i+=20)
	{
		if(i==1280)
		{
			MoveToEx(hdc,i-1,0,NULL);
			LineTo(hdc,i-1,740);
		}
		else
		{
			MoveToEx(hdc,i,0,NULL);
			LineTo(hdc,i,740);
		}
	}

	//刷新界面
	Update();

	// 主消息循环:
// 	while (GetMessage(&msg, NULL, 0, 0))
// 	{
// 		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
// 		{
// 			TranslateMessage(&msg);
// 			DispatchMessage(&msg);
// 		}
// 	}
	while (true) 
	{
		if(KEYDOWN(VK_ESCAPE))
		{
			SendMessage(hWnd,WM_DESTROY,0,0);
		}
		if( PeekMessage( &msg, NULL, 0,0 ,PM_REMOVE) )
		{
			if(msg.message==WM_QUIT)
				break;
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
	}

	return (int) msg.wParam;
}

//
//  函数: MyRegisterClass()
//
//  目的: 注册窗口类。
//
//  注释:
//
//    仅当希望
//    此代码与添加到 Windows 95 中的“RegisterClassEx”
//    函数之前的 Win32 系统兼容时,才需要此函数及其用法。调用此函数十分重要,
//    这样应用程序就可以获得关联的
//    “格式正确的”小图标。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(NULL, IDI_INFORMATION);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)GetStockObject(BLACK_BRUSH);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_TT3);
	wcex.lpszClassName	= "lujian";
	wcex.hIconSm		= LoadIcon(wcex.hInstance, NULL);

	return RegisterClassEx(&wcex);
}

//
//   函数: InitInstance(HINSTANCE, int)
//
//   目的: 保存实例句柄并创建主窗口
//
//   注释:
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // 将实例句柄存储在全局变量中

   hWnd = CreateWindow(	"LuJian",
	   "windows",
	   WS_POPUP,
	   GetSystemMetrics(SM_CXSCREEN),
	   GetSystemMetrics(SM_CYSCREEN),
	   CW_USEDEFAULT,
	   CW_USEDEFAULT,
	   NULL,
	   NULL,
	   hInstance,
	   NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, SW_MAXIMIZE);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的: 处理主窗口的消息。
//
//  WM_COMMAND	- 处理应用程序菜单
//  WM_PAINT	- 绘制主窗口
//  WM_DESTROY	- 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;

	switch (message)
	{
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// 分析菜单选择:
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		case ID_S***E:
			{
				ofstream out("try.map");
				for(int i=0; i<37; i++)
				{
					for(int j=0; j<64; j++)
					{
						out<<map[i][j]<<" ";
					}
					out<<endl;
				}
				out.close();
			}
			break;
		case ID_LOAD:
			{
				ReadMap();
				Update();
			}
			break;
		case ID_RESET:
			{
				HBRUSH backbrush = (HBRUSH)GetStockObject(BLACK_BRUSH);
				SelectObject(hdc,backbrush);
				RECT rect;
				GetClientRect(hWnd,&rect);
				Rectangle(hdc,rect.left,rect.top,rect.right,rect.bottom);
				SelectObject(hdc,pen);
				for(int i=0;i<=37*20;i+=20)
				{
					MoveToEx(hdc,0,i,NULL);
					LineTo(hdc,1280,i);
				}
				for(int i=0;i<=1280;i+=20)
				{
					if(i==1280)
					{
						MoveToEx(hdc,i-1,0,NULL);
						LineTo(hdc,i-1,740);
					}
					else
					{
						MoveToEx(hdc,i,0,NULL);
						LineTo(hdc,i,740);
					}
				}
				for(int i=0;i<37;i++)
				{
					for(int j=0;j<64;j++)
					{
						map[i][j] = 0;
					}
				}
				start = false;
			}
			break;
		case ID_START:
			{
				SetBkColor(hdc,RGB(0,0,0));
				SetTextColor(hdc,RGB(255,255,255));
				TextOut(hdc,400,745,"                                  ",(int)strlen("                                  "));
				Astart astart(map,64,37,begin,end);
				if(!astart.Find())
				{
					SetBkColor(hdc,RGB(0,0,0));
					SetTextColor(hdc,RGB(255,255,255));
					TextOut(hdc,400,745,"没有可以到达的路线",(int)strlen("没有可以到达的路线"));
					break;
				}
				astart.GetResult();
				for(int i=astart.value_list.Length(); i>=1; i--)
				{
					DWORD w1 = GetTickCount();
					Rect a;
					astart.value_list.Find(i,a);
					int x = a.map_x *20;
					int y = a.map_y *20;
					SelectObject(hdc,redpen);
					SelectObject(hdc,redbrush);
					if(x == 63*20)
					{
						Rectangle(hdc,x+1,y+1,x+19,y+20);
					}
					else
					{
						Rectangle(hdc,x+1,y+1,x+20,y+20);
					}
					while(GetTickCount() - w1 <= 10);
				}
			}
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: 在此添加任意绘图代码...
		Update();
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_MOUSEMOVE:
		{
			char buffer[13] = {};
			sprintf(buffer,"X=%d,Y=%d",LOWORD(lParam),HIWORD(lParam));
			SetBkColor(hdc,RGB(0,0,0));
			SetTextColor(hdc,RGB(255,255,255));
			TextOut(hdc,10,745,buffer,(int)strlen(buffer));
		}
		break;
	case WM_LBUTTONDOWN:
		{
			char buffer[15] = {};
			int x = LOWORD(lParam);
			int y = HIWORD(lParam);
			x=x/20*20;
			y=y/20*20;
			if(map[y/20][x/20] == 1)
			{
				map[y/20][x/20] = 0;
				SelectObject(hdc,pen);
				SelectObject(hdc,GetStockObject(BLACK_BRUSH));
				Rectangle(hdc,x,y,x+21,y+21);
			}
			else if(map[y/20][x/20] == 2)
			{
				start = false;
				map[y/20][x/20]=1;
				SelectObject(hdc,bluepen);
				SelectObject(hdc,bluebrush);
				Rectangle(hdc,x+1,y+1,x+20,y+20);
			}
			else
			{
				map[y/20][x/20]=1;
				SelectObject(hdc,bluepen);
				SelectObject(hdc,bluebrush);
				Rectangle(hdc,x+1,y+1,x+20,y+20);
			}
			sprintf(buffer,"X=%d,Y=%d",LOWORD(lParam),HIWORD(lParam));
			SetBkColor(hdc,RGB(0,0,0));
			SetTextColor(hdc,RGB(255,255,255));
			TextOut(hdc,10,745,buffer,(int)strlen(buffer));
		}
		break;
	case WM_RBUTTONDOWN:
		{
			char buffer[15] = {};
			int x = LOWORD(lParam);
			int y = HIWORD(lParam);
			x=x/20*20;
			y=y/20*20;
			if(!start)
			{
				start = true;
				SelectObject(hdc,greenpen);
				SelectObject(hdc,greenbrush);
				Rectangle(hdc,x+1,y+1,x+20,y+20);
				sprintf(buffer,"X=%d,Y=%d",LOWORD(lParam),HIWORD(lParam));
				SetBkColor(hdc,RGB(0,0,0));
				SetTextColor(hdc,RGB(255,255,255));
				TextOut(hdc,10,745,buffer,(int)strlen(buffer));
				map[y/20][x/20]=2;
				begin = y/20*64 + x/20;
			}
			else
			{
				if(!over)
				{
					over = true;
					SelectObject(hdc,redpen);
					SelectObject(hdc,redbrush);
					Rectangle(hdc,x+1,y+1,x+20,y+20);
					sprintf(buffer,"X=%d,Y=%d",LOWORD(lParam),HIWORD(lParam));
					SetBkColor(hdc,RGB(0,0,0));
					SetTextColor(hdc,RGB(255,255,255));
					TextOut(hdc,10,745,buffer,(int)strlen(buffer));
					map[y/20][x/20]=3;
					end = y/20*64 + x/20;
				}
// 				else
// 				{
// 					map[end/64][end%64] = 0;
// 					SelectObject(hdc,pen);
// 					SelectObject(hdc,GetStockObject(BLACK_BRUSH));
// 					Rectangle(hdc,(end%64)*20,(end/64)*20,(end%64*20)+21,(end/64*20)+21);
// 					over = false;
// 				}
			}
		}
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}


上面就是主要源码,但还不是全部工程,还有些资源文件。如有需要,请下载整个工程
http://download.csdn.net/detail/liujiayu2/8910871
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: