zoukankan      html  css  js  c++  java
  • gdi写的2048

    //-------------------------------------------【头文件及引用】----------------------------------------------------//
    #include <Windows.h>
    #include <time.h>
    #include <stdlib.h>
    #include <vector>
    #include <map>
    #include <string>
    #include <iostream>
    #pragma comment(lib,"winmm.lib")
    #pragma comment(lib,"Msimg32.lib")
    using namespace std;
    
    //-------------------------------------------【宏定义】----------------------------------------------------------//
    #define WINDOW_WIDTH 800
    #define WINDOW_HEIGHT 600
    #define WINDOW_TITLE  L"窗口"
    
    //-------------------------------------------【全局变量声明部分】------------------------------------------------//
    HDC g_hdc = NULL, g_mdc = NULL, g_bufdc = NULL;  //全局设备环境句柄
    HBITMAP g_hBitMap = NULL, g_hNumber[7] = {NULL}; //位图句柄
    HFONT g_hFont;//文字句柄
    
    int Map[4][4];
    int score;
    const int WinFlag = 2048;
    int IsOver;
    
    struct node
    {
    	int ChangeMap[4][4];//操作后的数组
    	int GetScore;//得分
    	int flag;//操作是否成功
    	node(int CM[][4], int scr, int f)
    	{
    		memcpy(ChangeMap, CM, sizeof ChangeMap);
    		GetScore = scr;
    		flag = f;
    	}
    	node() {}
    };
    
    //-------------------------------------------【全局函数声明部分】------------------------------------------------//
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
    BOOL Game_Init(HWND hwnd);
    VOID Game_Paint(HWND hwnd);
    BOOL Game_CleanUp(HWND hwnd);
    
    VOID Map_Init();
    //四种操作(主要对数组进行旋转)
    node up();
    node down();
    node left();
    node right();
    //统一转成左移后操作
    node change(int a[4][4]);
    
    void InsertNumber();//随机插入数字
    int judge();//判断矩阵情况,0为无法继续移动,1为可以继续移动但未达到胜利标准,2为达到胜利标准
    
    //-------------------------------------------【 main函数 】------------------------------------------------//
    int main() {
    	HINSTANCE hInstance = GetModuleHandle(NULL);
    	int nShowCmd = true;
    	WNDCLASSEX wndClass = {
    		sizeof(WNDCLASSEX),
    		CS_HREDRAW | CS_VREDRAW,
    		WndProc,
    		0L,
    		0L,
    		hInstance,
    		(HICON)::LoadImage(NULL,L"icon.ico", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE),
    		LoadCursor(NULL, IDC_ARROW),
    		(HBRUSH)GetStockObject(GRAY_BRUSH),
    		NULL,
    		L"ForTheDream",//窗口类的名称
    		NULL
    	};
    	if( !RegisterClassEx(&wndClass)) return -1;
    	HWND hWnd = CreateWindow( L"ForTheDream", WINDOW_TITLE, WS_OVERLAPPEDWINDOW,
    		CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);
    	MoveWindow(hWnd, 250, 80, WINDOW_WIDTH, WINDOW_HEIGHT, true);
    	ShowWindow(hWnd, nShowCmd);
    	UpdateWindow(hWnd);
    
    	if(!Game_Init(hWnd)) return -1;
    
    	//消息循环过程
    	MSG msg = {0};
    	while(msg.message != WM_QUIT) {
    		if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
    			TranslateMessage(&msg); //虚拟键消息转换成字符消息
    			DispatchMessage(&msg); //分发一个消息给窗口程序
    		}
    		else
    		{
    			Game_Paint(hWnd);
    		}
    	}
    	UnregisterClass(L"ForTheDream", wndClass.hInstance );//注销
    
    	return 0;
    }
    
    //---------------------------------------【窗口过程函数WndProc( )部分】------------------------------------------//
    //描述:窗口过程函数,对窗口消息进行处理
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    	//定义一个PAINTSTRUCT结构体来记录一些绘制信息
    	PAINTSTRUCT paintStruct;
    	switch(message) {
    	case WM_KEYDOWN:
    		{
    			if(wParam == VK_ESCAPE)
    			{
    				if(MessageBox(hwnd, L"确认退出吗?", L"退出", MB_YESNO) == IDYES)
    					DestroyWindow(hwnd);
    			}
    			else if((wParam == VK_UP || wParam == VK_DOWN ||wParam == VK_LEFT ||wParam == VK_RIGHT) && !IsOver)
    			{
    				node res;
    				switch(wParam)
    				{
    				case VK_UP:
    					res = up();
    					break;
    				case VK_DOWN:
    					res = down();
    					break;
    				case VK_LEFT:
    					res = left();
    					break;
    				case VK_RIGHT:
    					res = right();
    					break;
    				}
    				memcpy(Map, res.ChangeMap, sizeof Map);
    				score += res.GetScore;
    				if(res.flag)
    					InsertNumber();
    				int JudgeRes = judge();
    				if(JudgeRes == 2)
    				{
    					IsOver = true;
    					Game_Paint(hwnd);
    					if(MessageBox(hwnd, L"恭喜你胜利了!是否重新开始游戏?", L"恭喜!", MB_YESNO) == IDYES)
    						Map_Init();
    				}
    				else if(JudgeRes == 0)
    				{
    					IsOver = true;
    					Game_Paint(hwnd);
    					if(MessageBox(hwnd, L"哈哈哈输了吧你个菜逼!是否重新开始游戏?", L"失败", MB_YESNO) == IDYES)
    						Map_Init();
    				}
    				//MessageBox(hwnd,L"键盘",L"Mouse",MB_OK);
    			}
    		}
    		break;
    	case WM_DESTROY:
    		Game_CleanUp(hwnd);
    		PostQuitMessage(0);
    		break;
    	case WM_LBUTTONDOWN://鼠标消息
    		//MessageBox(hwnd,L"鼠标左键已按下",L"Mouse",MB_OK);
    		break;
    	default:
    		return DefWindowProc(hwnd, message, wParam, lParam);
    	}
    	return 0;
    }
    
    //---------------------------------------【游戏初始化部分】------------------------------------------//
    //描述:贴背景贴图
    BOOL Game_Init(HWND hwnd)
    {
    	HBITMAP bmp;
    	Map_Init();
    	g_hdc = GetDC(hwnd);//获取设备环境句柄k
    	g_hBitMap = (HBITMAP)LoadImage(NULL, L"back.bmp", IMAGE_BITMAP, 800, 600, LR_LOADFROMFILE);//加载位图
    	wchar_t filename[20];
    	for(int i = 0; i < 11; i++)
    	{
    		memset(filename, 0, sizeof(filename));
    		swprintf_s(filename, L"color%d.bmp", i);
    		g_hNumber[i] = (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP, 80, 80, LR_LOADFROMFILE);
    	}
    	g_mdc = CreateCompatibleDC(g_hdc);//建立兼容设备环境的内存DC
    	g_bufdc = CreateCompatibleDC(g_hdc);
    	bmp = CreateCompatibleBitmap(g_hdc, WINDOW_WIDTH, WINDOW_HEIGHT);//建立一个与窗口兼容的空的位图对象
    	SelectObject(g_mdc, bmp);
    	Game_Paint(hwnd);
    	return TRUE;
    }
    
    VOID Game_Paint(HWND hwnd)
    {
    	SelectObject(g_bufdc, g_hBitMap);//将位图对象选入到g_mdc内存DC中
    	BitBlt(g_mdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_bufdc, 0, 0, SRCCOPY);//采用BitBlt函数贴图,参数设置为窗口大小
    
    	g_hFont = CreateFont(40, 0, 0, 0, 0, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, L"微软雅黑");
    	SelectObject(g_mdc, g_hFont);
    	SetBkMode(g_mdc, TRANSPARENT);
    	wchar_t TextScore[20];
    	swprintf_s(TextScore, L"%d", score);
    	TextOut(g_mdc, 580, 225, TextScore, wcslen(TextScore));
    	DeleteObject(g_hFont);
    	for(int i = 0; i < 4; i++)
    	{
    		for(int j = 0; j < 4; j++)
    		{
    			if(Map[i][j])
    			{
    				int NO = 0;
    				int tmp = Map[i][j];
    				while(tmp != 2)
    				{
    					NO++;
    					tmp /= 2;
    				}
    				SelectObject(g_bufdc, g_hNumber[NO]);
    				BitBlt(g_mdc, 110 + j * 100, 110 + i * 100, 80, 80, g_bufdc, 0, 0, SRCCOPY);
    			}
    		}
    	}
    	BitBlt(g_hdc,0,0,WINDOW_WIDTH,WINDOW_HEIGHT,g_mdc,0,0,SRCCOPY);
    }
    
    //---------------------------------------【Game_CleanUp()函数】------------------------------------------//
    //描述:资源清理函数
    BOOL Game_CleanUp(HWND hwnd)
    {
    	DeleteObject(g_hBitMap);
    	for(int i = 0; i < 7; i++) {
    		DeleteObject(g_hNumber[i]);
    	}
    	DeleteDC(g_mdc);
    	DeleteDC(g_bufdc);
    	ReleaseDC(hwnd, g_hdc);//释放设备环境
    	return TRUE;
    }
    
    //---------------------------------------【游戏算法部分】------------------------------------------//
    VOID Map_Init()
    {
    	score = 0;
    	memset(Map, 0, sizeof Map);
    	InsertNumber();
    	InsertNumber();
    	//Map[0][0] = 1024, Map[0][1] = 1024;
    	IsOver = false;
    }
    
    void InsertNumber()
    {
    	srand((unsigned int)time(NULL));
    	int x, y;
    	x = rand() % 4;
    	y = rand() % 4;
    	while(Map[x][y])
    	{
    		x = rand() % 4;
    		y = rand() % 4;
    	}
    	int number = rand() % 10;
    	if(number)
    		Map[x][y] = 2;
    	else
    		Map[x][y] = 4;
    }
    node change(int a[4][4])
    {
    	vector <int> v[4];
    	vector <int> tmp[4];
    	int ans[4][4] = {0};
    	int GetScore = 0;
    	for(int i = 0; i < 4; i++)
    	{
    		for(int j = 0; j < 4; j++)
    		{
    			if(a[i][j])
    				v[i].push_back(a[i][j]);
    		}//去0
    		while(v[i].size() > 1)
    		{
    			if(v[i][0] == v[i][1])
    			{
    				tmp[i].push_back(v[i][0] * 2);
    				GetScore += v[i][0] * 2;
    				v[i].erase(v[i].begin(), v[i].begin() + 2);
    			}//比较是否可以合并,如果可以合并到新容器中并删除已合并的两个数
    			else
    			{
    				tmp[i].push_back(v[i][0]);
    				v[i].erase(v[i].begin(), v[i].begin() + 1);
    			}//如果不可以合并把第一个放入容器中,删掉第一个数
    		}
    		if(v[i].size())
    			tmp[i].push_back(v[i][0]);//如果有剩余的数也放进去
    		int j = 0;
    		for(; j < tmp[i].size(); j++)
    			ans[i][j] = tmp[i][j];//存进数组
    		for(; j < 4; j++)
    			ans[i][j] = 0;//补零
    	}
    	int flag = 0;
    	for(int i = 0; i < 4; i++)
    	{
    		for(int j = 0; j < 4; j++)
    			if(ans[i][j] != a[i][j])
    				flag = 1;//检查是否和原数组相同,如果相同说明不可以移动
    	}
    	return node(ans, GetScore, flag);
    }
    node up()
    {
    	int a[4][4];
    	for(int i = 0; i < 4; i++)
    		for(int j = 0; j < 4; j++)
    		{
    			a[i][j] = Map[j][3 - i];
    		}
    		node res = change(a);
    		for(int i = 0; i < 4; i++)
    			for(int j = 0; j < 4; j++)
    			{
    				a[i][j] = res.ChangeMap[3 - j][i];
    			}
    	return node(a, res.GetScore, res.flag);
    }
    node down()
    {
    	int a[4][4];
    	for(int i = 0; i < 4; i++)
    		for(int j = 0; j < 4; j++)
    		{
    			a[i][j] = Map[3 - j][i];
    		}
    		node res = change(a);
    		for(int i = 0; i < 4; i++)
    			for(int j = 0; j < 4; j++)
    			{
    				a[i][j] = res.ChangeMap[j][3 - i];
    			}
    			return node(a, res.GetScore, res.flag);
    }
    node left()
    {
    	return change(Map);
    }
    node right()
    {
    	int a[4][4];
    	for(int i = 0; i < 4; i++)
    		for(int j = 0; j < 4; j++)
    		{
    			a[i][j] = Map[i][3 - j];
    		}
    		node res = change(a);
    		for(int i = 0; i < 4; i++)
    			for(int j = 0; j < 4; j++)
    				a[i][j] = res.ChangeMap[i][3 - j];
    		return node(a, res.GetScore, res.flag);
    }
    int judge()
    {
    	for(int i = 0; i < 4; i++)
    		for(int j = 0; j < 4; j++)
    		{
    			if(Map[i][j] == WinFlag)
    				return 2;
    		}
    		int flag = 0;
    		flag = max(flag, up().flag);
    		flag = max(flag, down().flag);
    		flag = max(flag, left().flag);
    		flag = max(flag, right().flag);
    		return flag;
    }
    

    只是一只大作业……嗯哼  

    github不知道为啥安不上了……先把代码存一下……万一又异常了咋整【擦泪

  • 相关阅读:
    js判断当前年龄
    获取手机号归属地
    关于vscode控制tab控制缩进2/4个空格
    vue中的 mvvm
    关于前端性能优化
    js 深拷贝
    关于js hasOwnPropetry // instanceof 整理
    node-sass 安装报错
    JS发送跨域Post请求出现两次请求的解决办法
    Vue面试复习
  • 原文地址:https://www.cnblogs.com/Apro/p/4552935.html
Copyright © 2011-2022 走看看