简单五子棋-win32API(1)

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值