一、实验目的
用 C++窗口类函数写一个五子棋小游戏
二、实验环境
VC++6.0、Windows10
三、实验内容
创建对话框,绘制五子棋,并实现五子棋的输赢判断。
四、实验步骤(描述详细过程)
1)相关知识
掌握 GDI 绘图,打印字符串等、鼠标事件响应。
2)编程要求
实现五子棋棋盘的格子定位,实现五子棋游戏正常进行。
3)测试说明
2.1.4 代码编写
#include <windows.h>
#include <tchar.h>
#define DIVISIONS 10
static int fState[DIVISIONS + 1][DIVISIONS + 1];
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOLEAN InitWindowClass(HINSTANCE hInstacne, int nCmdShow);
void drawChessBoard(HDC hdc, int myBlock);
void drawDyna(HDC hdc, int myBlock);
void getMousePosition(HWND hwnd, HDC hdc, int myBlock, WPARAM wParam, LPARAM lParam);
void switchState(HWND hwnd, HDC hdc, int myBlock, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int nCmdShow) {
HWND hWnd;
MSG msg;
if (!InitWindowClass(hInstance, nCmdShow)) {
MessageBox(NULL, L"定义窗口失败!", L"定义窗口!", NULL);
return FALSE;
}
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
BOOLEAN InitWindowClass(HINSTANCE hInstance, int nCmdShow) {
WNDCLASSEX wcex;
HWND hWnd;
TCHAR szWindowClass[] = L"窗口事例";
TCHAR szTitle[] = L"Checker1";
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = 0;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
if (!RegisterClassEx(&wcex))return FALSE;
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
static int cxBlock, cyBlock;
static int myBlock;
HDC hdc;
hdc = GetDC(hwnd);
PAINTSTRUCT ps;
switch (message) {
case WM_SIZE:
cxBlock = LOWORD(lParam) / (DIVISIONS + 2);
cyBlock = LOWORD(lParam) / (DIVISIONS + 2);
myBlock = cxBlock > cyBlock ? cyBlock : cxBlock;
return 0;
case WM_MOUSEMOVE: {
getMousePosition(hwnd, hdc, myBlock, wParam, lParam);
ReleaseDC(hwnd, hdc);
}
break;
case WM_LBUTTONDOWN:
switchState(hwnd, hdc, myBlock, wParam, lParam);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
drawChessBoard(hdc, myBlock);
drawDyna(hdc, myBlock);
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
void drawChessBoard(HDC hdc, int myBlock)
{
int num;
Rectangle(hdc, (1) * myBlock, (1) * myBlock, (DIVISIONS + 1) * myBlock, (DIVISIONS + 1) * myBlock);
for (num = 1; num < DIVISIONS; num++)
{
MoveToEx(hdc, (num + 1) * myBlock, 1 * myBlock, NULL);
LineTo(hdc, (num + 1) * myBlock, (DIVISIONS + 1) * myBlock);
MoveToEx(hdc, (1 + 0) * myBlock, (num + 1) * myBlock, NULL);
LineTo(hdc, (DIVISIONS + 1) * myBlock, (num + 1) * myBlock);
}
}
void drawDyna(HDC hdc, int myBlock)
{
int x, y;
for (x = 0; x < DIVISIONS + 1; x++)
{
for (y = 0; y < DIVISIONS + 1; y++)
{
if (fState[x][y] == 2) {
MoveToEx(hdc, x * myBlock + 3 * myBlock / 4, y * myBlock + 3 * myBlock / 4, NULL);
LineTo(hdc, (x + 1) * myBlock + myBlock / 4, (y + 1) * myBlock + myBlock / 4);
MoveToEx(hdc, x * myBlock + 3 * myBlock / 4, (y + 1) * myBlock + 3 * myBlock / 4, NULL);
LineTo(hdc, (x + 1) * myBlock + myBlock / 4, y * myBlock + myBlock / 4);
}
if (fState[x][y] == 1) {
SelectObject(hdc, GetStockObject(WHITE_BRUSH));
Ellipse(hdc, x * myBlock + 65 * myBlock / 100, y * myBlock + 65 * myBlock / 100, (x + 1) * myBlock + 35 * myBlock / 100, (y + 1) * myBlock + 35 * myBlock / 100);
}
if (fState[x][y] == -1) {
SelectObject(hdc, GetStockObject(BLACK_BRUSH));
Ellipse(hdc, x * myBlock + 65 * myBlock / 100, y * myBlock + 65 * myBlock / 100, (x + 1) * myBlock + 35 * myBlock / 100, (y + 1) * myBlock + 35 * myBlock / 100);
}
}
}
}
void getMousePosition(HWND hwnd, HDC hdc, int myBlock, WPARAM wParam, LPARAM lParam) {
TCHAR myBuffer[80];
int x, y;
RECT rect;
int iLength;
int mouse_x = (int)LOWORD(lParam);
int mouse_y = (int)HIWORD(lParam);
SetTextColor(hdc, RGB(0, 0, 0));
SetBkColor(hdc, RGB(255, 255, 255));
SetBkMode(hdc, OPAQUE);
iLength = wsprintf(myBuffer, TEXT("mX:%5d,mY:%5d"), mouse_x, mouse_y);
TextOut(hdc, 2, 0, myBuffer, lstrlen(myBuffer));
for (x = 0; x < DIVISIONS + 1; x++)
for (y = 0; y < DIVISIONS + 1; y++) {
if (fState[x][y] == 2) fState[x][y] = 0;
rect.left = x * myBlock + myBlock / 2;
rect.top = y * myBlock + myBlock / 2;
rect.right = (x + 1) * myBlock + myBlock / 2;
rect.bottom = (y + 1) * myBlock + myBlock / 2;
InvalidateRect(hwnd, &rect, true);
}
x = (LOWORD(lParam) + myBlock / 2) / myBlock - 1;
y = (HIWORD(lParam) + myBlock / 2) / myBlock - 1;
iLength = wsprintf(myBuffer, TEXT("X:%3d,Y:%3d"), x, y);
TextOut(hdc, 160, 0, myBuffer, lstrlen(myBuffer));
iLength = wsprintf(myBuffer, TEXT("Bx:%5d,By:%5d,Lx:%5d,Ly:%5d"), x * myBlock + myBlock / 2,
y * myBlock + myBlock / 2, (x + 1) * myBlock + myBlock / 2, (y + 1) * myBlock + myBlock / 2);
TextOut(hdc, 2, 14, myBuffer, lstrlen(myBuffer));
if (x < DIVISIONS + 1 && y < DIVISIONS + 1)
if (fState[x][y] == 0) fState[x][y] = 2;
}
void switchState(HWND hwnd, HDC hdc, int myBlock, WPARAM wParam, LPARAM lParam) {
RECT rect;
int x = (LOWORD(lParam) + myBlock / 2) / myBlock - 1;
int y = (HIWORD(lParam) + myBlock / 2) / myBlock - 1;
if (x < DIVISIONS + 1 && y < DIVISIONS + 1) {
switch (fState[x][y]) {
case-1:
fState[x][y] = 1;
break;
case 1:
fState[x][y] = 0;
break;
case 0:
fState[x][y] = 2;
break;
case 2:
fState[x][y] = -1;
break;
}
rect.left = x * myBlock + myBlock / 2;
rect.top = y * myBlock + myBlock / 2;
rect.right = (x + 1) * myBlock + myBlock / 2;
rect.bottom = (y + 1) * myBlock + myBlock / 2;
InvalidateRect(hwnd, &rect, true);
}