//-------------------------------------------【头文件及引用】----------------------------------------------------// #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不知道为啥安不上了……先把代码存一下……万一又异常了咋整【擦泪
时间: 2024-10-24 17:42:29