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

📄 迷宫.cpp

📁 实现走迷宫的功能
💻 CPP
字号:
// 迷宫.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "迷宫.h"
#include"Stack.cpp"
#include"Graph.cpp"
#include<iostream>
#include<Time.h>
using namespace std;
#define MAX_LOADSTRING 100

// 全局变量:
HINSTANCE hInst;								// 当前实例
TCHAR szTitle[MAX_LOADSTRING];					// 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];			// 主窗口类名
HBITMAP ball;
clock_t ttPre;  //记录之前时间
clock_t ttNow;  //记录当前时间
int ttime;     //计算时间差
HBITMAP backer;  //背景
 HBITMAP bmp;
 HBITMAP outer;   //出口
HDC hdc,mdc,bufdc;
bool keydown;     //判断是否重新开始游戏
  HBITMAP tile;   //墙
  wchar_t step[60];  //显示步数
  wchar_t timee[60];  //显示时间
  wchar_t* automo;    //自动生成路径
  wchar_t* info;      //重新开始
  wchar_t* begin;     //游戏开始
HWND hWnd;
int curx = 0,cury = 0;  
DWORD tPre,tNow;
int nowPos,prePos;  //记录当前和上一步的位置
bool find;         //是否找到出口
bool autoplay;     //判断是否自动生成路径
bool begint;   //判断是否开始游戏
int rowNum,colNum;
const int X=700;    
const int Y=700;
int up,down;
int COUNT = 0;
int leeft,riight;
SStack<int> path;
Graph mazes;

 const int rows = 35;
 const int cols = 35;
int mapIndex[rows*cols];
int mapCopy[rows*cols];
int record[rows*cols];
//计算迷宫的路径



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

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_MY, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

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

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

	// 主消息循环:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			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(hInstance, MAKEINTRESOURCE(IDI_MY));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_MY);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}




//生成最短路径函数
void getpath()
{
	int count=0;
	while(count<cols*rows&&!find)
	{
		if(!find)
		{
			rowNum = nowPos/cols;
			colNum=nowPos%cols;
			up = nowPos - cols;
			down = nowPos + cols;
			leeft = nowPos - 1;
			riight = nowPos +1;
			if( up>= 0 && record[up])
			{
				path.push(up);
				record[up] = 0;
				prePos = nowPos;
				nowPos = up;
				if(mapIndex[nowPos] == 3)
					find = true;
			}
			else if(down <=cols*rows - 1 && record[down])
			{
				path.push(down);
				record[down] = 0;
				prePos = nowPos;
				nowPos = down;
				if(mapIndex[nowPos] == 3)
					find = true;
			}
			else if(leeft >= rowNum*cols && record[leeft])
			{
				path.push(leeft);
				record[leeft] = 0;
				prePos = nowPos;
				nowPos = leeft;
				if(mapIndex[nowPos] == 3)
					find = true;
			}
			else if(riight <=(rowNum+1)*cols - 1&& record[riight])
			{
				path.push(riight);
				record[riight] = 0;
				prePos = nowPos;
				nowPos = riight;
				if(mapIndex[nowPos] == 3)
					find = true;
			}
			else
			{		
				if(path.empty())
				{
					count++;
				}					
				else
				{
					path.pop();
					if(!path.empty())
					{
						prePos = nowPos;
						nowPos = path.top();
					}
				}
			}
		}
	}
}

//获取随机迷宫
void getMaze()
{
	for(int a = 0;a<rows;a++)
	{
		int* p = mazes.get_Maze(a);
		for(int b = 0;b<cols;b++)	
		{
		  mapIndex[a*cols+b]=p[b];
		}
	}
}
//画迷宫图  重新游戏时的初始化
void backPaint()
{
	begin = L"BEGIN!";
	find = false;
	if(keydown ) 
	{
		getMaze();
		curx = cury = 0;
	}
	SelectObject(mdc,bmp);
	int i,x,y;
	for( i = 0;i < rows*cols;i++)
	{
		record[i] = mapIndex[i];
		mapCopy[i]=mapIndex[i];
		rowNum = i/cols;
		colNum = i%cols;
		x = colNum*4*X/(5*rows);y = rowNum*4*X/(5*cols);
		if(!mapIndex[i])
		{
			SelectObject(bufdc,tile);
			BitBlt(mdc,x,y,4*X/(5*rows),4*X/(5*cols),bufdc,0,0,SRCCOPY);
		}
		else
		{
			if(mapIndex[i]==2)
			{
				nowPos = i;
				path.push(i);
				SelectObject(bufdc,tile);
				BitBlt(mdc,x,y,4*X/(5*rows),4*X/(5*cols),bufdc,0,0,WHITENESS);
			}
			else if(mapIndex[i]==3)
			{
				SelectObject(bufdc,outer);
				BitBlt(mdc,x,y,4*X/(5*rows),4*X/(5*cols),bufdc,0,0,SRCCOPY);
			}
			else
			{
				SelectObject(bufdc,tile);
				BitBlt(mdc,x,y,4*X/(5*rows),4*X/(5*cols),bufdc,0,0,WHITENESS);
			}
		}
	}
	prePos = cols*rows+1;
}
void MyPaint(HDC hdc)
{
	if(begint)
	{
		ttPre = ttNow;
		ttNow = clock();
		ttime+=(ttNow-ttPre)*1.0/CLOCKS_PER_SEC ;
	}
	else
	{
		ttime = 0;
	}
	/*if((curx!=0||cury!=0))
	{
		SelectObject(bufdc,tile);
		if(mapIndex[curx*cols+cury]==1)
			BitBlt(mdc,curx*4*X/(5*rows),cury*4*Y/(5*cols),4*X/(5*rows),4*X/(5*cols),bufdc,0,0,SRCCOPY);
		else if(mapIndex[curx*cols+cury]==0)
			BitBlt(mdc,curx*4*X/(5*rows),cury*4*Y/(5*cols),4*X/(5*rows),4*X/(5*cols),bufdc,0,0,WHITENESS);
	}*/
	SelectObject(bufdc,backer);
	BitBlt(hdc,X*4/5-75,-30,X,Y,bufdc,0,0,SRCCOPY);
	int x,y;
	//消除上次贴图
	rowNum = prePos / cols;
	colNum = prePos % cols;
	x = colNum*(4*X/(5*rows));
	y = rowNum*(4*Y/(5*cols));
	SelectObject(bufdc,ball);
	BitBlt(mdc,x,y,4*X/(5*rows),4*Y/(5*cols),bufdc,0,0,WHITENESS);
	//小球贴图
	rowNum = nowPos / cols;
	colNum = nowPos%cols;
	x=colNum*4*X/(5*rows);
	y=rowNum*4*Y/(5*cols);
	SelectObject(bufdc,ball);
	BitBlt(mdc,x,y,4*X/(5*rows),4*Y/(5*cols),bufdc,0,0,SRCCOPY);
	swprintf(step,L"STEPS:  %d",COUNT);
	TextOut(hdc,X*4/5,200,step,wcslen(step));
	swprintf(timee,L"TIME:  %d S",ttime);
	TextOut(hdc,4*X/5,100,timee,wcslen(timee));
	TextOut(hdc,X*4/5,300,info,wcslen(info));
	TextOut(hdc,X*4/5,400,automo,wcslen(automo));
	TextOut(hdc,4*X/5,500,begin,wcslen(begin));
	wchar_t remind[90];
	swprintf(remind,L"Total Time : %d S",180-ttime);
	TextOut(hdc,4*X/5,600,remind,wcslen(remind));


	//重新开始游戏时重新绘制地图  地图随机产生
	if(keydown||autoplay)
	{
		for( int i = 0;i < rows*cols;i++)
		{
			rowNum = i/cols;
			colNum = i%cols;
			x = colNum*4*X/(5*rows);y = rowNum*4*X/(5*cols);
			if(!mapCopy[i])
			{
				SelectObject(bufdc,tile);
				BitBlt(mdc,x,y,4*X/(5*rows),4*X/(5*cols),bufdc,0,0,SRCCOPY);
			}
			else
			{
				if(mapCopy[i]==2)
				{
					nowPos = i;
					path.push(i);
					record[i]=0;
					SelectObject(bufdc,ball);
					BitBlt(mdc,x,y,4*X/(5*rows),4*X/(5*cols),bufdc,0,0,SRCCOPY);
				}
				else if(mapCopy[i]==3)
				{
					SelectObject(bufdc,outer);
					BitBlt(mdc,x,y,4*X/(5*rows),4*X/(5*cols),bufdc,0,0,SRCCOPY);
				}
				else if(mapCopy[i]==4)
				{
					SelectObject(bufdc,ball);
					BitBlt(mdc,x,y,4*X/(5*rows),4*X/(5*cols),bufdc,0,0,SRCCOPY);
				}
				else 
				{
					SelectObject(bufdc,tile);
					BitBlt(mdc,x,y,4*X/(5*rows),4*X/(5*cols),bufdc,0,0,WHITENESS);
				}
			}
		}
   }
	BitBlt(hdc,0,0,cols*4*X/(5*rows),rows*4*Y/(5*cols),mdc,0,0,SRCCOPY);
	tPre = GetTickCount();
}


//获取生成的最短路径存入数组
void getRoute()
{
	if(path.empty())begin=L"NO WAY!";
	while(!path.empty())
	{
		
		int current = path.top();
		path.pop();
		int currentx = current/cols;
		int currenty = current%cols;
		if(!path.empty())
		{
			int current1 = path.top();
			int current1x = current1;
			int current1y = current1;
			
		}
		if((mapIndex[current]!=2)||(mapIndex[current]!=3))
			mapCopy[current]=4;
	}
}
//
//   函数: InitInstance(HINSTANCE, int)
//
//   目的: 保存实例句柄并创建主窗口
//
//   注释:
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
  
   hInst = hInstance; // 将实例句柄存储在全局变量中
   info=L"REPLAY!!";
   begin = L"BEGIN!";
   automo=L"PLAY AUTOMOLLY!";
   for(int a = 0;a<rows;a++)
   {
	  int* p = mazes.get_Maze(a);
	  for(int b = 0;b<cols;b++)
	  {
		  mapIndex[a*cols+b]=p[b];
	  }
   }
   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }
   MoveWindow(hWnd,10,10,X,Y,true);
   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);
     hdc = GetDC(hWnd);
   mdc = CreateCompatibleDC(hdc);
   bufdc = CreateCompatibleDC(hdc);
   bmp = CreateCompatibleBitmap(hdc,cols*4*X/(5*rows),rows*4*X/(5*cols));
   
   tile = (HBITMAP)LoadImage(NULL,L"tile.bmp",IMAGE_BITMAP,4*X/(5*rows),4*X/(5*cols),LR_LOADFROMFILE);
   ball = (HBITMAP)LoadImage(NULL,L"ball.bmp",IMAGE_BITMAP,4*X/(5*rows),4*X/(5*cols),LR_LOADFROMFILE);
   backer=(HBITMAP)LoadImage(NULL,L"2.bmp",IMAGE_BITMAP,X,Y,LR_LOADFROMFILE);
   outer = (HBITMAP)LoadImage(NULL,L"out.bmp",IMAGE_BITMAP,4*X/(5*rows),4*X/(5*cols),LR_LOADFROMFILE);

   getMaze();
   backPaint();
   MyPaint(hdc);
   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_KEYDOWN:                           //键盘输入  利用方向键控制小鼠的移动
		if(!find)
		{
			begin = L"finding..";
			switch(wParam)
			{
			case VK_UP:                    //向上移动
				up = nowPos - cols;
				if( up>= 0 && record[up])
				{
					prePos = nowPos;
					nowPos = up;
					if(mapIndex[nowPos] == 3)
						find = true;
				}
					else
				{
						begin= L"BLOCK.";
				}
				break;
			case VK_DOWN:                 //向下移动
				down = nowPos + cols;
				if(down <=cols*rows - 1 && record[down])
				{
					prePos = nowPos;
					nowPos = down;
					if(mapIndex[nowPos] == 3)
						find = true;
				}
				else
				{
						begin= L"BLOCK.";
					
				}
				break;
			case VK_LEFT:                  //向左移
				leeft = nowPos - 1;
				if(leeft >= rowNum*cols && record[leeft])
				{
					prePos = nowPos;
					nowPos = leeft;
					if(mapIndex[nowPos] == 3)
						find = true;
				}
					else
				{
						begin= L"BLOCK.";
					
				}
				break;
			case VK_RIGHT:                 //向右移
				riight = nowPos +1;
				if(riight <=(rowNum+1)*cols - 1&& record[riight])
				{
					prePos = nowPos;
					nowPos = riight;
					if(mapIndex[nowPos] == 3)
						find = true;
				}
				else
				{
					begin= L"BLOCK.";
				}
				break;
		
			}
		}
		else if(find==true&&ttime<=180){begin=L"YOU WIN";}           //找到出口
		else if(ttime>180){begin = L"YOU LOSE";}
		COUNT++;
		keydown = false;
		MyPaint(hdc);
		break;
		case WM_LBUTTONDOWN:                      //鼠标左击
			curx = LOWORD(lParam);                //获取当前
			cury = HIWORD(lParam);                //鼠标的坐标值
			if(0<=curx&&curx<=4*X/5&&0<=cury&&cury<=4*Y/5)       //墙变路  路变墙
			{
				curx = curx/(4*X/(5*rows));
				cury = cury/(4*Y/(5*cols));
				if(mapIndex[curx*cols+cury]==0)
					mapIndex[curx*cols+cury]=1;
				else if(mapIndex[curx*cols+cury]==1)
					mapIndex[curx*cols+cury]=0;
				autoplay = false;
				keydown = false;
				begint = false;
				find = false;
				backPaint();
				MyPaint(hdc);
			}
			else if(curx>=X*4/5&&curx<=X&&cury>=380&&cury<=420)      //自动生成路径
			{
				curx = cury = 0;
				autoplay=true;
				keydown = false;
				begint = false;
				backPaint();
				ttime = 0;
				backPaint();
				getpath();
				getRoute();
				MyPaint(hdc);
			}
			else if(curx>=X*4/5&&curx<=X&&cury>=280&&cury<=320)           //重新游戏
			{
				curx = cury = 0;
				begin = L"BEGIN";
				autoplay = false;
				keydown = true;
				begint = false;
				backPaint();
				MyPaint(hdc);
				record[1*cols+5]=3;
			}
			else if(curx>=X*4/5&&curx<=X&&cury>=480&&cury<=520)           //开始游戏
			{
				curx = cury = 0;
				ttNow = clock();
				begint = true;
			}
			break;
	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;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		MyPaint(hdc);
		// TODO: 在此添加任意绘图代码...
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	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;
}

⌨️ 快捷键说明

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