这里编译时没开XP支持,所以不兼容XP。XP用户可以用Visual Studio 2010自己编译一下。
<code class="lang-cpp">// OOXX.cpp : Defines the entry point for the console application. // //#include "stdafx.h" #define UNICODE 1 #include <windows.h> #include <windowsx.h> // HANDLE_MSG HWND hMainWnd; int data[3][3] = { 0 }; int status = 1; RECT rects[3][3] = { 0, 0, 100, 100, 100, 0, 200, 100, 200, 0, 300, 100, 0, 100, 100, 200, 100, 100, 200, 200, 200, 100, 300, 200, 0, 200, 100, 300, 100, 200, 200, 300, 200, 200, 300, 300, }; void DrawHash(HDC hdc, RECT firstrc) // 绘制边线 { int width = firstrc.right - firstrc.left; int height = firstrc.bottom - firstrc.top; MoveToEx(hdc, firstrc.left, firstrc.bottom, NULL); LineTo(hdc, firstrc.left + 3 * width, firstrc.bottom); MoveToEx(hdc, firstrc.left, firstrc.bottom + height, NULL); LineTo(hdc, firstrc.left + 3 * width, firstrc.bottom + height); MoveToEx(hdc, firstrc.right, firstrc.top, NULL); LineTo(hdc, firstrc.right, firstrc.top + 3 * height); MoveToEx(hdc, firstrc.right + width, firstrc.top, NULL); LineTo(hdc, firstrc.right + width, firstrc.top + 3 * height); } void DrawO(HDC hdc, RECT rc) // 绘制O { Ellipse(hdc, rc.left + 10, rc.top + 10, rc.right - 10, rc.bottom - 10); } void DrawX(HDC hdc, RECT rc) // 绘制X { MoveToEx(hdc, rc.left, rc.top, NULL); LineTo(hdc, rc.right, rc.bottom); MoveToEx(hdc, rc.right, rc.top, NULL); LineTo(hdc, rc.left, rc.bottom); } void MainWnd_OnPaint(HWND hwnd) { // WM_PAINT界面重绘消息 PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); // 开始重绘 DrawHash(hdc, rects[0][0]); // 绘制边线 for (int j = 0; j < 3; j++) { for (int k = 0; k < 3; k++) // 绘制棋子 { if (data[j][k] == 1) DrawO(hdc, rects[j][k]); else if (data[j][k] == 2) DrawX(hdc, rects[j][k]); } } EndPaint(hwnd, &ps); // 结束重绘 } void DropOX(HWND hwnd, int j, int k) // 落子 { if (data[j][k] == 0) // 如果这个位置没有棋子 { data[j][k] = status; // 落子 if (status == 1) status = 2; // 换对手 else status = 1; InvalidateRect(hwnd, NULL, FALSE); // 绘制棋子 } } void WinGame(HWND hwnd, int winner) // 显示胜负并重新开局 { switch (winner) { case 0: MessageBox(hwnd, L"No one won the game.", L"Result", MB_OK); break; case 1: MessageBox(hwnd, L"'O' won the game.", L"Result", MB_OK); break; case 2: MessageBox(hwnd, L"'X' won the game.", L"Result", MB_OK); break; } memset(data, 0, sizeof data); // 重新开局 InvalidateRect(hwnd, NULL, TRUE); // 重新绘制界面 } void DetectWinner(HWND hwnd) // 检测是否有胜出 { if (data[0][0] != 0 && data[0][0] == data[1][1] && data[1][1] == data[2][2]) return WinGame(hwnd, data[0][0]); // 正对角线 if (data[0][2] != 0 && data[0][2] == data[1][1] && data[1][1] == data[2][0]) return WinGame(hwnd, data[0][2]); // 反对角线 for (int j = 0; j < 3; j++) { if (data[0][j] != 0 && data[0][j] == data[1][j] && data[1][j] == data[2][j]) return WinGame(hwnd, data[0][j]); // 横向 if (data[j][0] != 0 && data[j][0] == data[j][1] && data[j][1] == data[j][2]) return WinGame(hwnd, data[j][0]); // 纵向 } int zeros = 0; for (int j = 0; j < 3; j++) for (int k = 0; k < 3; k++) // 计数空位 if (data[j][k] == 0) zeros++; if (zeros == 0) // 如果全部下满 { int ones = 0, twos = 0; for (int j = 0; j < 3; j++) for (int k = 0; k < 3; k++) // 计数两种棋子 { if (data[j][k] == 1) ones++; else if (data[j][k] == 2) twos++; } if (ones > twos) return WinGame(hwnd, 1); // 圈多于叉 else if (twos > ones) return WinGame(hwnd, 2); // 叉多余圈 else return WinGame(hwnd, 0); // 相等(实际不可能出现) } } void MainWnd_OnLButtonDown(HWND hwnd, BOOL dblclk, int x, int y, UINT vkey) { // WM_LBUTTONDOWN鼠标按下消息 POINT pt = { x, y }; for (int j = 0; j < 3; j++) { for (int k = 0; k < 3; k++) { if (PtInRect(&rects[j][k], pt)) // 如果在落子区域按下 { DropOX(hwnd, j, k); // 落子 DetectWinner(hwnd); // 检测是否有胜出 } } } } BOOL MainWnd_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct) { // WM_CREATE窗口创建消息 RECT rcwindow, rcclient; GetWindowRect(hwnd, &rcwindow); GetClientRect(hwnd, &rcclient); rcwindow.right += 300 - (rcclient.right - rcclient.left); rcwindow.bottom += 300 - (rcclient.bottom - rcclient.top); MoveWindow(hwnd, rcwindow.left, rcwindow.top, rcwindow.right - rcwindow.left, rcwindow.bottom - rcwindow.top, FALSE); // 保证客户区为300x300 return TRUE; } void MainWnd_OnDestroy(HWND hwnd) { // WM_DESTROY窗口销毁消息 PostQuitMessage(0); } LRESULT CALLBACK MainWnd_WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { // WndProc窗口消息处理函数 switch (message) { HANDLE_MSG(hwnd, WM_CREATE, MainWnd_OnCreate); HANDLE_MSG(hwnd, WM_DESTROY, MainWnd_OnDestroy); HANDLE_MSG(hwnd, WM_PAINT, MainWnd_OnPaint); HANDLE_MSG(hwnd, WM_LBUTTONDOWN, MainWnd_OnLButtonDown); } return DefWindowProc(hwnd, message, wParam, lParam); } int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR lpszCmdLine, int nCmdShow) { // wWinMain入口点 WNDCLASSEX wc = { sizeof wc, CS_HREDRAW | CS_VREDRAW, // 窗口显示方式 MainWnd_WndProc, // 窗口消息处理函数 0, 0, // 类附加数据、窗口附加数据 NULL, // 模块句柄(EXE模块可NULL) LoadIcon(NULL, IDI_APPLICATION), // 图标 LoadCursor(NULL, IDC_ARROW), // 鼠标指针 (HBRUSH)GetStockObject(WHITE_BRUSH), // 背景画刷 NULL, // 菜单 L"MyOOXXClass", // 窗口类名 LoadIcon(NULL, IDI_APPLICATION) // 小图标 }; RegisterClassEx(&wc); // 注册窗口类 hMainWnd = CreateWindowEx( // 创建窗口 WS_EX_OVERLAPPEDWINDOW, // 扩展风格 L"MyOOXXClass", L"OOXX", // 窗口类,窗口标题 WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU, // 基本风格 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, // 四角坐标 NULL, NULL, NULL, NULL); // 父窗口,菜单或序号,模块句柄,附加信息 ShowWindow(hMainWnd, nCmdShow); // 显示窗口 UpdateWindow(hMainWnd); // 刷新窗口 MSG msg; while (GetMessage(&msg, NULL, 0, 0)) // 获取消息(同时分发高优先级消息) { TranslateMessage(&msg); // 翻译键盘消息 DispatchMessage(&msg); // 分发消息 } return (int)msg.wParam; // 收到WM_QUIT,GetMessage返回FALSE退出 }</windowsx.h></windows.h></code>
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |
200字以内,仅用于支线交流,主线讨论请采用回复功能。