|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
这是我用 SDK 写的,很简单,基本功能是实现了  - /* -------------------------------------------------------------------
- MyWindows.c -- 基本窗口模型
- 《Windows 程序设计(SDK)》视频教程
- --------------------------------------------------------------------*/
- #include <windows.h>
- #include <strsafe.h>
- #include<windowsx.h>
- // 判断白黑棋是否赢
- bool black_white_win(const POINT *PW, int w_num);
- // 一个画白色圆的函数 传入一个坐标
- void my_Circle(HDC hdc, POINT cri);
- // 一个画黑色圆的函数 传入一个坐标
- void my_Circle_b(HDC hdc, POINT cri);
- // 棋盘
- void DrawSquare(HDC hdc, POINT point);
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
- {
- static TCHAR szAppName[] = TEXT("MyWindows");
- HWND hwnd;
- MSG msg;
- WNDCLASS wndclass;
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = WndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = szAppName;
- if (!RegisterClass(&wndclass))
- {
- MessageBox(NULL, TEXT("这个程序需要在 Windows NT 才能执行!"), szAppName, MB_ICONERROR);
- return 0;
- }
- hwnd = CreateWindow(szAppName,
- TEXT("鱼C工作室"),
- WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL,
- NULL,
- hInstance,
- NULL);
- ShowWindow(hwnd, iCmdShow);
- UpdateWindow(hwnd);
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return msg.wParam;
- }
- LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- HDC hdc;
- PAINTSTRUCT ps;
- RECT rect;
- static int cxClient, cyClient; // 表是客户区的宽 和 高
- size_t iTarget; // unsigent int 无符号整形 用来计算字符串长度
- static int cx_char; // 水平 与 垂直 方向字体的设置
- static int cy_char;
- // TEXTMETRIC 结构记录当前设备环境中有关字体的各种信息。
- // 结构成员的值的单位取决于设备环境中当前选定的映射模式,默认的映射模式是 MM_TEXT,所以它们的值是以像素为单位的
- TEXTMETRIC tm; // 指向 TEXTMETRIC 的指针
- static TCHAR szBuffer[128] = TEXT("五子棋少年的追梦之旅");
- static TCHAR sz_rule[128] = TEXT("规则:1.按鼠标左右键下棋 按左键白子先下 按右键黑子先下 2.任意一方五个棋子相连获得胜利");
- static TCHAR wb_szstr[128];
- int x, y , xPos , yPos; // xPos yPos 表示鼠标点击的坐标
- POINT point;
- static int numA = 0, numB = 0; // 记录落子的个数
- static POINT w_point[1000]; // 记录白子的所有坐标
- static POINT b_point[1000]; // 记录黑子的所有坐标
- int i;
- // 控制黑白子是否落下的开关( 1表示关 0表示开)
- static int w_off = 0, b_off = 0;
- // 赢了后接受消息
- int S_MSG;
- switch (message)
- {
- case WM_CREATE:
- hdc = GetDC(hwnd);
- GetTextMetrics(hdc , &tm);
- cx_char = tm.tmAveCharWidth;
- cy_char = tm.tmHeight + tm.tmExternalLeading;
- ReleaseDC(hwnd , hdc);
- return 0;
- case WM_SIZE:
- cxClient = LOWORD(lParam); // 获得客户区的宽
- cyClient = HIWORD(lParam); // 获得客户区的高
- case WM_PAINT:
- hdc = BeginPaint(hwnd, &ps);
- GetClientRect(hwnd, &rect);
- SetTextAlign(hdc,GetTextAlign(hdc) | TA_LEFT );
- // 绘制棋盘方格
- StringCchLength(szBuffer , 128 , &iTarget);
- TextOut(hdc, cxClient/2-100, cy_char, szBuffer, iTarget);
- for (x = 40; x < cxClient-40; x+=20)
- {
- for (y = 40; y < cyClient-40; y += 20)
- {
- point.x = x;
- point.y = y;
- DrawSquare(hdc, point);
- }
- }
- StringCchLength(sz_rule, 128, &iTarget);
- TextOut(hdc, cy_char, cyClient-25, sz_rule, iTarget);
- EndPaint(hwnd, &ps);
- return 0;
- // WM_LBUTTONUP 0x0202 释放鼠标左键
- case WM_LBUTTONUP:
- hdc = GetDC(hwnd);
- GetClientRect(hwnd, &rect);
- xPos = GET_X_LPARAM(lParam);// GET_X_LPARAM(lParam) 返回坐标的 x 值;
- yPos = GET_Y_LPARAM(lParam);// GET_Y_LPARAM(lParam) 返回坐标的 y 值;
- // 用户通常没办法将鼠标100%点中下棋子的位置,因此我们的程序应该自动找到最接近的下子位置
- if (xPos % 20 >= 10)
- xPos = xPos + 10 - xPos % 10;
- else
- xPos = xPos - xPos % 10;
- if (yPos % 20 >= 10)
- yPos = yPos + 10 - yPos % 10;
- else
- yPos = yPos - yPos % 10;
-
- // 画一个白色的圆
- point.x = xPos;
- point.y = yPos;
- // 下的棋子的位置不能超界
- if (point.x < 40 || point.y < 40)
- {
- ReleaseDC(hwnd, hdc);
- return 0;
- }
- // 判断与黑子的坐标是否重复
- for (i = 0; i < numB; i++)
- {
- if (point.x == b_point[i].x && point.y == b_point[i].y )
- {
- ReleaseDC(hwnd, hdc);
- return 0;
- }
- }
- // 判断白子有没有多画(只画一个白子)
- if (w_off == 1)
- {
- ReleaseDC(hwnd, hdc);
- return 0;
- }
- // 记录下白子的坐标
- w_point[numA] = point;
- numA+=1;
-
-
- StringCchPrintf(wb_szstr, 128, TEXT("%d 白棋坐标(%d , %d)"), numA , point.x, point.y);
- StringCchLength(wb_szstr, 128, &iTarget);
- TextOut(hdc , rect.right-200 , 10 , wb_szstr, iTarget);
- my_Circle(hdc , point);
- w_off = 1; // 画完白子后关了
- b_off = 0; // 画完白子后开
- // 判断棋子是否赢
- if ( numA >= 5 && black_white_win(w_point , numA) )
- {
- S_MSG = MessageBox(NULL , TEXT("恭喜白子获得胜利\n是不是要开始新的一局?") , TEXT("赢了。。赢了") , MB_YESNO);
- if (IDYES == S_MSG)
- {
-
- for (int i = 0; i <numA; i++)
- {
- w_point[i].x = 0;
- w_point[i].y = 0;
- b_point[i].x = 0;
- b_point[i].y = 0;
- }
- numB = 0;
- numA = 0;
- w_off = 0;
- b_off = 0;
- InvalidateRect(hwnd, NULL, TRUE);
- UpdateWindow(hwnd);
- ReleaseDC(hwnd, hdc);
- return 0;
- }
- }
- ReleaseDC(hwnd , hdc);
- return 0;
- // WM_RBUTTONDOWN 0x0204 按下鼠标右键
- case WM_RBUTTONDOWN:
- hdc = GetDC(hwnd);
- GetClientRect(hwnd, &rect);
- xPos = GET_X_LPARAM(lParam);// GET_X_LPARAM(lParam) 返回坐标的 x 值;
- yPos = GET_Y_LPARAM(lParam);// GET_Y_LPARAM(lParam) 返回坐标的 y 值;
- // 用户通常没办法将鼠标100%点中下棋子的位置,因此我们的程序应该自动找到最接近的下子位置
- if (xPos % 20 >= 10)
- xPos = xPos + 10 - xPos % 10;
- else
- xPos = xPos - xPos % 10;
- if (yPos % 20 >= 10)
- yPos = yPos + 10 - yPos % 10;
- else
- yPos = yPos - yPos % 10;
- // 画一个黑色的圆
- point.x = xPos;
- point.y = yPos;
- // 下的棋子的位置不能超界
- if (point.x < 40 || point.y < 40)
- {
- ReleaseDC(hwnd, hdc);
- return 0;
- }
- // 判断与白子的坐标是否重复
- for (i = 0; i < numA; i++)
- {
- if (point.x == w_point[i].x && point.y == w_point[i].y )
- {
- ReleaseDC(hwnd, hdc);
- return 0;
- }
- }
- // 判断黑子有没有多画(只画一个黑子)
- if (b_off == 1)
- {
- ReleaseDC(hwnd, hdc);
- return 0;
- }
- b_point[numB] = point;
- numB+=1;
-
- StringCchPrintf(wb_szstr, 128, TEXT("%d 黑棋坐标(%d , %d)"), numB, point.x, point.y);
- StringCchLength(wb_szstr, 128, &iTarget);
- TextOut(hdc, rect.left, 10, wb_szstr, iTarget);
- // 画黑子
- my_Circle_b(hdc, point);
- w_off = 0; // 画完黑子后开
- b_off = 1; // 画完黑子后关了
- // 判断棋子是否赢
- if (numB >= 5 && black_white_win(b_point, numB))
- {
- S_MSG = MessageBox(NULL, TEXT("恭喜黑子获得胜利\n是不是要开始新的一局?"), TEXT("赢了。。赢了"), MB_YESNO);
- if (IDYES == S_MSG)
- {
-
- for (int i = 0; i < numB; i++)
- {
- b_point[i].x = 0;
- b_point[i].y = 0;
- w_point[i].x = 0;
- w_point[i].y = 0;
- }
- numB = 0;
- numA = 0;
- w_off = 0;
- b_off = 0;
- InvalidateRect(hwnd, NULL, TRUE);
- UpdateWindow(hwnd);
- ReleaseDC(hwnd, hdc);
- return 0;
- }
- }
-
- ReleaseDC(hwnd, hdc);
- return 0;
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
- void my_Circle(HDC hdc, POINT cri)
- {
- // 根据中心点的坐标 确定左上角和右下角的坐标
- RECT rect;
- rect.right = cri.x - 10;
- rect.top = cri.y - 10;
- rect.left = cri.x + 10;
- rect.bottom = cri.y + 10;
- // 画园
- Ellipse(hdc, rect.right, rect.top, rect.left, rect.bottom);
- return;
- }
- void my_Circle_b(HDC hdc, POINT cri)
- {
- // 根据中心点的坐标 确定左上角和右下角的坐标
- RECT rect;
- // 定义一个画刷类型
- HBRUSH hBrush, holdBrush;
- rect.right = cri.x - 10;
- rect.top = cri.y - 10;
- rect.left = cri.x + 10;
- rect.bottom = cri.y + 10;
- hBrush = (HBRUSH)GetStockObject(BLACK_BRUSH); // BLACK_BRUSH 黑色画刷
- // SelectObject 函数用于选择一对象到指定的设备环境中,该新对象将替换先前的相同类型的对象
- holdBrush = (HBRUSH)SelectObject(hdc, hBrush);
- // 画园
- Ellipse(hdc, rect.right, rect.top, rect.left, rect.bottom);
- SelectObject(hdc, holdBrush);
- return;
- }
- void DrawSquare(HDC hdc, POINT point)
- {
- MoveToEx(hdc, point.x, point.y, NULL);
- LineTo(hdc, point.x + 20, point.y);
- LineTo(hdc, point.x + 20, point.y + 20);
- LineTo(hdc, point.x, point.y + 20);
- LineTo(hdc, point.x, point.y);
- }
- // 判断白棋是否赢
- bool black_white_win(const POINT *PW, int w_num)
- {
- POINT temp;
- POINT A[4];
- int num_con = 0;
- // 遍历整个数组
- for (int i = 0; i < w_num; i++)
- {
- // 把要判断的白子赋给temp
- temp = *(PW + i);
- for (int a = 0 ; a < 4; a++ )
- {
- //同一方向的向右的四个棋子存入数组
- A[a].x = temp.x + (a + 1) * 20;
- A[a].y = temp.y;
- }
- // 判断同一方向的向右的四个棋子是否在数组内
- for (int b = 0; b < 4; b++)
- {
- for (int y = 0; y < w_num; y++)
- {
- if (A[b].x == (*(PW + y)).x && A[b].y == (*(PW + y)).y)
- num_con++;
- }
- }
- if (num_con == 4)
- return true;
- else
- num_con = 0;
- for (int a = 0; a < 4; a++)
- {
- //同一方向的向左的四个棋子存入数组
- A[a].x = temp.x - (a + 1) * 20;
- A[a].y = temp.y;
- }
- // 判断同一方向的向左的四个棋子是否在数组内
- for (int b = 0; b < 4; b++)
- {
- for (int y = 0; y < w_num; y++)
- {
- if (A[b].x == (*(PW + y)).x && A[b].y == (*(PW + y)).y)
- num_con++;
- }
- }
- if (num_con == 4)
- return true;
- else
- num_con = 0;
- for (int a = 0; a < 4; a++)
- {
- //同一方向的向上的四个棋子存入数组
- A[a].x = temp.x;
- A[a].y = temp.y - (a+1)*20;
- }
- // 判断同一方向的向上的四个棋子是否在数组内
- for (int b = 0; b < 4; b++)
- {
- for (int y = 0; y < w_num; y++)
- {
- if (A[b].x == (*(PW + y)).x && A[b].y == (*(PW + y)).y)
- num_con++;
- }
- }
- if (num_con == 4)
- return true;
- else
- num_con = 0;
- for (int a = 0; a < 4; a++)
- {
- //同一方向的向下的四个棋子存入数组
- A[a].x = temp.x;
- A[a].y = temp.y + (a + 1) * 20;
- }
- // 判断同一方向的向下的四个棋子是否在数组内
- for (int b = 0; b < 4; b++)
- {
- for (int y = 0; y < w_num; y++)
- {
- if (A[b].x == (*(PW + y)).x && A[b].y == (*(PW + y)).y)
- num_con++;
- }
- }
- if (num_con == 4)
- return true;
- else
- num_con = 0;
- for (int a = 0; a < 4; a++)
- {
- //同一方向的向左斜上的四个棋子存入数组
- A[a].x = temp.x - (a + 1) * 20;
- A[a].y = temp.y - (a + 1) * 20;
- }
- // 判断同一方向的向左斜上的四个棋子是否在数组内
- for (int b = 0; b < 4; b++)
- {
- for (int y = 0; y < w_num; y++)
- {
- if (A[b].x == (*(PW + y)).x && A[b].y == (*(PW + y)).y)
- num_con++;
- }
- }
- if (num_con == 4)
- return true;
- else
- num_con = 0;
- for (int a = 0; a < 4; a++)
- {
- //同一方向的向左斜下的四个棋子存入数组
- A[a].x = temp.x - (a + 1) * 20;
- A[a].y = temp.y + (a + 1) * 20;
- }
- // 判断同一方向的向左斜下的四个棋子是否在数组内
- for (int b = 0; b < 4; b++)
- {
- for (int y = 0; y < w_num; y++)
- {
- if (A[b].x == (*(PW + y)).x && A[b].y == (*(PW + y)).y)
- num_con++;
- }
- }
- if (num_con == 4)
- return true;
- else
- num_con = 0;
- for (int a = 0; a < 4; a++)
- {
- //同一方向的向右斜下的四个棋子存入数组
- A[a].x = temp.x + (a + 1) * 20;
- A[a].y = temp.y + (a + 1) * 20;
- }
- // 判断同一方向的向右斜下的四个棋子是否在数组内
- for (int b = 0; b < 4; b++)
- {
- for (int y = 0; y < w_num; y++)
- {
- if (A[b].x == (*(PW + y)).x && A[b].y == (*(PW + y)).y)
- num_con++;
- }
- }
- if (num_con == 4)
- return true;
- else
- num_con = 0;
- for (int a = 0; a < 4; a++)
- {
- //同一方向的向右斜上的四个棋子存入数组
- A[a].x = temp.x + (a + 1) * 20;
- A[a].y = temp.y - (a + 1) * 20;
- }
- // 判断同一方向的向右斜上的四个棋子是否在数组内
- for (int b = 0; b < 4; b++)
- {
- for (int y = 0; y < w_num; y++)
- {
- if (A[b].x == (*(PW + y)).x && A[b].y == (*(PW + y)).y)
- num_con++;
- }
- }
- if (num_con == 4)
- return true;
- else
- num_con = 0;
-
- }
- return false;
- }
复制代码 |
|