#include<Windows.h>
#include<windowsx.h>
#include<strsafe.h>
//回调函数,windows自己调用
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int End();
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, 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("这个程序需要在windowsNT才能执行!"), szAppName, MB_ICONERROR);
return 0;
}
//设置窗口具体特征(分化)
hWnd = CreateWindow(szAppName, TEXT("鱼C工作室"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);
//消息循环,windows核心
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg); //调用窗口过程函数(回调函数)
}
return msg.wParam;
}
//棋盘范围
RECT chess;
//棋盘点
typedef struct CHESS
{
LONG x;
LONG y;
int c; //颜色
}Chess[15][15];
Chess ptChess;
//棋子宽度
LONG pieceWidth;
//棋子颜色
#define UNKNOW 0
#define BLACK 1
#define WHITE 2
//棋子
typedef struct PIECE
{
int i;
int j;
int color;
}Piece[255];
Piece pieces;
int ip = 0;
//当前手的棋子颜色
int nowColor = WHITE;
void Reverse()
{
switch (nowColor)
{
case WHITE:
nowColor = BLACK;
break;
case BLACK:
nowColor = WHITE;
break;
}
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
static int cxClient, cyClient;
HBRUSH hOldBrush, hBlackBrush,hWhiteBrush;
POINT ptClick;
TCHAR szBuffer[30] = TEXT("%s棋赢了!"), szDest[30];
RECT rect;
int i, j;
switch (message)
{
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
//获取棋子宽度
pieceWidth = min(cxClient, cyClient) / 19;
//获取棋盘点
for (int i = 0; i < 15; ++i)
{
for (int j = 0; j < 15; ++j)
{
ptChess[i][j].x = pieceWidth*(i + 2);
ptChess[i][j].y = pieceWidth*(j + 2);
}
}
return 0;
case WM_LBUTTONDOWN:
//获取单击位置
ptClick.x = GET_X_LPARAM(lParam);
ptClick.y = GET_Y_LPARAM(lParam);
//计算棋子安放位置
i= (ptClick.x + pieceWidth / 2) / pieceWidth - 2;
j= (ptClick.y + pieceWidth / 2) / pieceWidth - 2;
//判断棋子安放位置是否合理
if (i < 0 || i>14 || j < 0 || j>14 || ptChess[i][j].c != UNKNOW)
{
return 0;
}
//载入棋子队列
pieces[ip].i = i;
pieces[ip].j = j;
pieces[ip].color = nowColor;
ptChess[i][j].c = nowColor;
Reverse();
ip++;
//重绘
SetRect(&rect, ptChess[i][j].x - pieceWidth / 2, ptChess[i][j].y - pieceWidth / 2,
ptChess[i][j].x + pieceWidth / 2, ptChess[i][j].y + pieceWidth / 2);
InvalidateRect(hWnd, &rect, FALSE);
return 0;
case WM_RBUTTONDOWN:
if (ip == 0)
{
return 0;
}
ip--;
i = pieces[ip].i;
j = pieces[ip].j;
//值回溯
ptChess[i][j].c = UNKNOW;
pieces[ip].i = 0;
pieces[ip].j = 0;
pieces[ip].color = UNKNOW;
SetRect(&rect, ptChess[i][j].x - pieceWidth / 2, ptChess[i][j].y - pieceWidth / 2,
ptChess[i][j].x + pieceWidth / 2, ptChess[i][j].y + pieceWidth / 2);
InvalidateRect(hWnd, &rect, TRUE);
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
//绘制棋盘
for (int i = 0; i < 15; ++i)
{
MoveToEx(hdc, ptChess[i][0].x, ptChess[i][0].y, NULL);
LineTo(hdc, ptChess[i][14].x, ptChess[i][14].y);
}
for (int j = 0; j < 15; ++j)
{
MoveToEx(hdc, ptChess[0][j].x, ptChess[0][j].y, NULL);
LineTo(hdc, ptChess[14][j].x, ptChess[14][j].y);
}
//绘制棋子
hBlackBrush = CreateSolidBrush(RGB(0,0,0));
hWhiteBrush = CreateSolidBrush(RGB(255,255,255));
hOldBrush = SelectObject(hdc, hBlackBrush);
for (int i = 0,j = 0,k = 0; k < ip; ++k)
{
if (pieces[k].color == UNKNOW)
continue;
if(pieces[k].color == BLACK)
SelectObject(hdc, hBlackBrush);
if(pieces[k].color == WHITE)
SelectObject(hdc, hWhiteBrush);
int i = pieces[k].i, j = pieces[k].j;
Ellipse(hdc, ptChess[i][j].x - pieceWidth / 2, ptChess[i][j].y - pieceWidth / 2, ptChess[i][j].x + pieceWidth / 2, ptChess[i][j].y + pieceWidth / 2);
}
//判断五子连珠
switch (End())
{
case WHITE:
SendMessage(hWnd, WM_CLOSE, WHITE, 0);
break;
case BLACK:
SendMessage(hWnd, WM_CLOSE, BLACK, 0);
break;
}
SelectObject(hdc, hOldBrush);
EndPaint(hWnd, &ps);
return 0;
case WM_CLOSE:
switch (wParam)
{
case WHITE:
StringCchPrintf(szDest, 30, szBuffer, TEXT("白"));
break;
case BLACK:
StringCchPrintf(szDest, 30, szBuffer, TEXT("黑"));
break;
default:
StringCchPrintf(szDest, 30, TEXT("结束游戏!"));
break;
}
if (MessageBox(hWnd, szDest, TEXT("结束"), MB_OK) == IDOK)
DestroyWindow(hWnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
//判断五子连珠
int End()
{
int current = ip - 1;
if (current < 8)
{
return UNKNOW;
}
int iTarget, i, j, x, y ,color;
i = pieces[current].i;
j = pieces[current].j;
color = pieces[current].color;
//判断横向
x = max(i - 4, 0);
y = j;
iTarget = 0;
for (; x <= min(i + 4, 14); ++x)
{
if (ptChess[x][y].c == color)
{
++iTarget;
if (iTarget == 5)
{
return color;
}
}
else iTarget = 0;
}
//判断纵向
x = i;
y = max(j - 4, 0);
iTarget = 0;
for (; y <= min(j + 4, 14); ++y)
{
if (ptChess[x][y].c == color)
{
++iTarget;
if (iTarget == 5)
{
return color;
}
}
else iTarget = 0;
}
//判断斜向
x = max(i - 4, 0);
y = max(j - 4, 0);
iTarget = 0;
for (; y <= min(y + 4, 14)&& x <= min(i + 4, 14); ++x,++y)
{
if (ptChess[x][y].c == color)
{
++iTarget;
if (iTarget == 5)
{
return color;
}
}
else iTarget = 0;
}
x = min(i + 4, 14);
y = max(j - 4, 0);
iTarget = 0;
for (; y <= min(y + 4, 14) && x >= max(i - 4, 0); --x, ++y)
{
if (ptChess[x][y].c == color)
{
++iTarget;
if (iTarget == 5)
{
return color;
}
}
else iTarget = 0;
}
return UNKNOW;
}
简单五子棋-win32API(1)
最新推荐文章于 2020-02-20 17:06:20 发布