#include<windows.h>
#include<iostream>
#include<cstdlib>
#include<ctime>
#include"resource.h"
#include <tchar.h>
#include<stack>
using namespace std;
struct point//点的结构体
{
point(int x, int y) :x(x), y(y){}//带参构造
point(){};//无参构造
point &operator=(point & a)//重载=
{
x = a.x;
y = a.y;
return *this;
}
point operator+(point & a)//重载+
{
point t;
t.x = x + a.x;
t.y = y + a.y;
return t;
}
bool operator==(point& a)//重载==
{
return (x == a.x) && (y == a.y);
}
int x;
int y;
};
struct parr//定义辅助数组,在辅助数组中求路径
{
int arr;
bool isFind;
};
/*******************************************************************************************************************/
int arr[8][8];//map图数组
int coparr[8][8];
HWND hwnd;//窗口句柄
//HANDLE handle;//控制台std句柄
HMENU menu;//顶层菜单句柄 //全局变量区
HMENU hpopmenu;//菜单句柄
HMENU hpopmenu1;//菜单句柄
HINSTANCE hin;//实力句柄
HBITMAP hbitmap[8][8];//位图句柄数组
point BeginPoint;//起点
point EndPoint;//终点
RECT rec = { 0 };//实时获取窗口客户区大小
char Size = 36;
char Status = 0;//状态器
bool op = true;
/*******************************************************************************************************************/
void Swap();//随机交换
void map();//随机生成map
void CreateMyMenu(HWND hwnd);创建顶层菜单
void OnUpdateGame(HDC hdc);//刷新游戏 //函数声明
void PlayGame(LPARAM lparam);//游戏操作
void LoadImage();//加载图片资源
void CreateMyWnd(HINSTANCE pstance, LPTSTR lpstr, int mode);//创建窗口
bool DFS();//深度寻路
bool refelx(LPARAM lparam);//满足坐标在map区域才采集
/*******************************************************************************************************************/
bool DFS()//深度寻路
{
point Direction[4] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };//定义四个方向
stack<point> Msd;//定义一个栈
Msd.push(BeginPoint);//压入起点
parr Parr[12][12];//第一辅助数组
for (unsigned i = 0; i < 8; ++i)//拷贝map二维数组的值
{
for (unsigned j = 0; j < 8; ++j)
{
Parr[i][j].arr = arr[i][j];
Parr[i][j].isFind = false;
}
}
point Current;//当前点
Current = BeginPoint;//当前点为起点
while (true)
{
for (unsigned i = 0; i < 4; ++i)//循环四个方向
{
point ptemp = Current + Direction[i];
if (ptemp == EndPoint)//找到终点
{
return true;
}
if ((Parr[ptemp.x][ptemp.y].arr == 0) && !Parr[ptemp.x][ptemp.y].isFind)//满足条件压入栈改变访问权限并改变当前点跳出循环
{
Msd.push(ptemp);
Parr[ptemp.x][ptemp.y].isFind = true;
Current = ptemp;
break;
}
else if (i == 3)//如果四个方向都不能访问删除该点并将上个点赋值给当前点
{
Msd.pop();
if (!Msd.empty())//最后一个点(起点)要注意
Current = Msd.top();
break;
}
}
if (Msd.empty())//栈为空时无路径
{
return false;
}
}
}
void CreateMyMenu(HWND hwnd)创建顶层菜单
{
menu = CreateMenu();
hpopmenu = CreatePopupMenu(); //函数实现区
hpopmenu1 = CreatePopupMenu();
AppendMenu(menu, MF_POPUP, UINT(hpopmenu), L"游戏");
AppendMenu(menu, MF_POPUP, UINT(hpopmenu1), L"跳关");
AppendMenu(hpopmenu1, MF_STRING, 10002, L"下一关");
AppendMenu(hpopmenu, MF_STRING, 10001, L"重玩游戏");
SetMenu(hwnd, menu);
}
void LoadImage()//加载资源
{
for (unsigned i = 0; i < 8; ++i)
{
for (unsigned j = 0; j < 8; ++j)
{
switch (arr[i][j])
{
case 0:
case 7:
hbitmap[i][j] = LoadBitmap(hin, MAKEINTRESOURCE(IDB_BITMAP7));
break;
case 1:
hbitmap[i][j] = LoadBitmap(hin, MAKEINTRESOURCE(IDB_BITMAP1));
break;
case 2:
hbitmap[i][j] = LoadBitmap(hin, MAKEINTRESOURCE(IDB_BITMAP2));
break;
case 3:
hbitmap[i][j] = LoadBitmap(hin, MAKEINTRESOURCE(IDB_BITMAP3));
break;
case 4:
hbitmap[i][j] = LoadBitmap(hin, MAKEINTRESOURCE(IDB_BITMAP4));
break;
case 5:
hbitmap[i][j] = LoadBitmap(hin, MAKEINTRESOURCE(IDB_BITMAP5));
break;
case 6:
hbitmap[i][j] = LoadBitmap(hin, MAKEINTRESOURCE(IDB_BITMAP6));
break;
}
}
}
}
void OnUpdateGame(HDC hdc)//刷新游戏
{
GetClientRect(hwnd, &rec);
HDC hmdc = CreateCompatibleDC(hdc);
HGDIOBJ old;
for (unsigned i = 1; i < 7; ++i)
{
for (unsigned j = 1; j < 7; ++j)
{
if (i == 1 && j == 1)
old = SelectObject(hmdc, hbitmap[i][j]);
else
SelectObject(hmdc, hbitmap[i][j]);
StretchBlt(hdc, j* (rec.right - rec.left) / 8, i*(rec.bottom - rec.top) / 8, (rec.right - rec.left) / 8, (rec.bottom - rec.top) / 8, hmdc, 0, 0, 113, 113, SRCCOPY);
}
}
SelectObject(hmdc, old);
for (unsigned i = 0; i < 8; ++i)
{
for (unsigned j = 0; j < 8; ++j)
{
DeleteObject(hbitmap[i][j]);
}
}
DeleteDC(hmdc);
}
bool refelx(LPARAM lparam)//满足坐标在map区域才采集
{
if (((LOWORD(lparam) >= (rec.right - rec.left) / 8) && (LOWORD(lparam) <= (7 * (rec.right - rec.left) / 8))) //客户x坐标
&& ((HIWORD(lparam) >= (rec.bottom - rec.top) / 8) && (HIWORD(lparam) <= (7 * (rec.bottom - rec.top) / 8))))//客户y坐标
{
return true;
}
else
return false;
}
void PlayGame(LPARAM lparam)//游戏操作
{
int x = LOWORD(lparam);
int y = HIWORD(lparam);
if (refelx(lparam) && arr[HIWORD(lparam) / ((rec.bottom - rec.top) / 8)][LOWORD(lparam) / ((rec.right - rec.left) / 8)] != 0)
{
if (Status == 2)
{
Status = 0;
}
if (!Status)
{
BeginPoint.y = LOWORD(lparam) / ((rec.right - rec.left) / 8);
BeginPoint.x = HIWORD(lparam) / ((rec.bottom - rec.top) / 8);
/* PrintXyConsole(BeginPoint);*/
Status++;
}
else
{
EndPoint.y = LOWORD(lparam) / ((rec.right - rec.left) / 8);
EndPoint.x = HIWORD(lparam) / ((rec.bottom - rec.top) / 8);
if (!(BeginPoint == EndPoint))
Status++;
}
}
}
LRESULT CALLBACK Winproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)//窗口消息处理函数
{
HDC hdc;
PAINTSTRUCT ps;
switch (msg)
{
case WM_COMMAND:
switch (LOWORD(wparam))
{
case 10001:
if (!op)
memcpy(arr, coparr, sizeof(int)* 64);
LoadImage();
InvalidateRect(hwnd, NULL, false);
break;
case 10002:
map();
LoadImage();
InvalidateRect(hwnd, NULL, false);
break;
}
break;
case WM_DESTROY://关闭消息
PostQuitMessage(0);//处理关闭消息的函数
break;
case WM_PAINT:
{
hdc = BeginPaint(hwnd, &ps);
OnUpdateGame(hdc);
EndPaint(hwnd, &ps);
}
break;
case WM_LBUTTONUP:
if (op)//按下鼠标判断是否需要备份map
{
memcpy(coparr, arr, sizeof(int)* 64);
op = false;
}
PlayGame(lparam);
if (Status == 2)
{
bool a = DFS();
if (DFS() && (arr[BeginPoint.x][BeginPoint.y] == arr[EndPoint.x][EndPoint.y]))
{
Size -= 2;
arr[BeginPoint.x][BeginPoint.y] = 0;
arr[EndPoint.x][EndPoint.y] = 0;
LoadImage();
InvalidateRect(hwnd, NULL, false);
if (!Size)//判断是否清完
{
op = true;
Size = 36;
map();
LoadImage();
InvalidateRect(hwnd, NULL, false);
}
}
}
break;
default:
return DefWindowProc(hwnd, msg, wparam, lparam);//自动处理消息
break;
}
return 0;
}
void CreateMyWnd(HINSTANCE pstance, LPTSTR lpstr, int mode)//创建窗口
{
WNDCLASS wc;//定义窗口类
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);//背景画刷句柄
wc.hCursor = NULL;//光标句柄
wc.hIcon = LoadIcon(pstance, MAKEINTRESOURCE(IDI_ICON1));//图标句柄
wc.hInstance = hin;//应用程序句柄
wc.lpfnWndProc = Winproc;//消息处理函数指针
wc.lpszClassName = L"连连看";//类名(ID)
wc.lpszMenuName = NULL;//菜单名(ID)
wc.style = CS_VREDRAW | CS_HREDRAW; //窗口类模式垂直水平
if (!RegisterClass(&wc))//注册窗口类
MessageBox(NULL, L"注册失败", L"注册失败", MB_OK);
hwnd = CreateWindow(L"连连看", L"连连看", WS_OVERLAPPEDWINDOW, 515, 50, 904, 904, NULL, NULL, hin, NULL);//创建窗口类
LoadImage();
CreateMyMenu(hwnd);
//AllocConsole();//创建控制台窗口
//handle = GetStdHandle(STD_OUTPUT_HANDLE);//获取STD句柄
if (!hwnd)
MessageBox(NULL, L"创建失败", L"创建失败", MB_OK);
ShowWindow(hwnd, mode);//显示窗口
UpdateWindow(hwnd);//更新窗口
MSG msg = { 0 };//消息结构体
while (true)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))//从消息队列获取窗口消息不出队列,有消息返回真
{
if (GetMessage(&msg, NULL, 0, 0))//获取消息,有关闭消息时返回假其他消息为真(1,先判断系统队列有无消息,有则处理,无判断有无窗口队列消息,
//有派发进系统队列处理,无判断是否需要重绘,有派发WM_PAINT消息,再判断有无定时器消息有派发WM_TIMER)
{
TranslateMessage(&msg);//翻译消息
DispatchMessage(&msg);//派发消息
}
else
{//有关闭消息退出
return;
}
}
}
}
void Swap()//随机交换
{
for (unsigned i = 0; i < 15; ++i)
{
int a = rand() % 3 + 1;
int b = rand() % 6 + 1;
int c = rand() % 3 + 4;
int d = rand() % 6 + 1;
arr[a][b] ^= arr[c][d];
arr[c][d] ^= arr[a][b];
arr[a][b] ^= arr[c][d];
}
}
void map()//连连看map生成
{
srand(unsigned(time(NULL)));
for (unsigned i = 1; i < 4; ++i)
{
for (unsigned j = 1; j < 7; ++j)
{
arr[i][j] = arr[3 + i][j] = rand() % 6 + 1;
}
}
Swap();
}
/*******************************************************************************************************************/
int _tWinMain(HINSTANCE hinstance, HINSTANCE pstance, LPTSTR lpstr, int mode)//win32入口函数,应用程序进程句柄,父类句柄,命令行字符串,模式(注意_tWinMain和LPTSTR配套使用兼容模式(默认宽字节))
{
hin = hinstance;//把实例句柄赋值给全局变量
arr[8][8] = { 0 };
map();//生成map
CreateMyWnd(pstance, lpstr, mode);//创建窗口
return 0;
}
win32和DFS(目前不能限制拐弯数为2)实现假的连连看
最新推荐文章于 2018-10-13 17:10:05 发布