#include <windows.h>
#include <winuser.h>
#define bool unsigned short
#define true 1
#define false 0
#define CHESSBOARD_NUMBER 15//棋盘规格
#define BLACK_CHESS_PIECES 1//定义黑色棋子 值为1
#define WHITE_CHESS_PIECES 2 //定义白色棋子 值为2
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int pr_chess_color;//待下棋子颜色
int z_DrawChessMap(HDC hdc,int extent,int cxClient,int cyClient);//绘制棋盘(设备环境句柄,棋盘规格extent*extent,客户区宽度,客户区高度)
int z_initialise_chessboard(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER], int cxClient, int cyClient, bool is_initialise); // 初始化棋盘, 更新棋盘坐标, 需提供客户区大小, 如果is_initialise值为true, 则初始化棋盘颜色
int z_Draw_chesspieces(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER], HDC hdc,HWND hwnd);//绘制棋子
int z_xiaqi(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER], int x, int y, HWND hwnd);//下棋
int z_is_ok(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER]);//判断是否赢棋,黑子赢返回1,白棋赢返回2
struct st_chess_pieces
{
int extra;//预留
int chess_color;//棋子颜色(RGB)
POINT x_y;//棋子坐标
};
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 | CS_DBLCLKS;
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(" ↓当前落子颜色 五子棋"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
600,
600,
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)
{
static HDC hdc;
PAINTSTRUCT ps;
RECT rect;
POINT cursor_point;
int iGainer;//胜棋者
static cx_Client;
static cy_Client;
static bool bChessBoard_invalidate;//表示棋盘是否能下棋,true不能下,false能下
static struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER];//棋盘数组
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
z_DrawChessMap(hdc, CHESSBOARD_NUMBER, rect.right, rect.bottom);//绘制棋盘
z_Draw_chesspieces(arr_chessboard, hdc,hwnd);//绘制棋子
EndPaint(hwnd, &ps);
return 0;
case WM_SIZE:
cx_Client = LOWORD(lParam);
cy_Client = HIWORD(lParam);
z_initialise_chessboard(arr_chessboard, cx_Client ,cy_Client, false);
return 0;
case WM_CREATE:
pr_chess_color=WHITE_CHESS_PIECES;
return 0;
case WM_LBUTTONUP://下棋
if (bChessBoard_invalidate == true)//棋盘不能下棋,直接返回
{
return 0;
}
GetCursorPos(&cursor_point);//获取鼠标在屏幕内坐标
ScreenToClient(hwnd, &cursor_point);//将鼠标在屏幕内坐标转换为窗口客户区坐标
z_xiaqi(arr_chessboard, cursor_point.x, cursor_point.y, hwnd);//将鼠标坐标传入下棋函数
InvalidateRect(hwnd, NULL, true);//发送客户区失效,重绘客户区
iGainer = z_is_ok(arr_chessboard);
if (iGainer == 1)//黑子胜
{
MessageBox(hwnd, TEXT("黑子胜!\n双击鼠标左键重新开盘!"), TEXT("提示:"), MB_OK);
bChessBoard_invalidate = true;
}else if(iGainer ==2 )//白子胜
{
MessageBox(hwnd,TEXT("白子胜!\n双击鼠标左键重新开盘!"),TEXT("提示:"),MB_OK);
bChessBoard_invalidate = true;
}
return 0;
case WM_LBUTTONDBLCLK://鼠标左键双击
if (MessageBox(hwnd, TEXT("是否重新开局!"), TEXT("提示:"), MB_YESNO) == IDYES)
{
z_initialise_chessboard(arr_chessboard, cx_Client, cy_Client, true);//初始化棋盘
InvalidateRect(hwnd, NULL, true);//发送客户区失效,重绘客户区
bChessBoard_invalidate = false;//
pr_chess_color = WHITE_CHESS_PIECES;
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
int z_DrawChessMap(HDC hdc,int extent,int cxClient,int cyClient)//绘制棋盘(设备环境句柄,棋盘规格extent*extent,客户区宽度,客户区高度)
{
int start_x, start_y,end_x,end_y,i;
POINT rect_x_y[4];//棋盘矩形坐标
rect_x_y[0].x = cxClient / (extent + 1) - 2;
rect_x_y[0].y = cyClient / (extent + 1) - 2;
rect_x_y[1].x = ((cxClient / (extent + 1))*extent) + 2;
rect_x_y[1].y = cyClient / (extent + 1) - 2;
rect_x_y[2].x = ((cxClient / (extent + 1))*extent) + 2;
rect_x_y[2].y = ((cyClient / (extent + 1))*extent) + 2;
rect_x_y[3].x = cxClient / (extent + 1) - 2;
rect_x_y[3].y = ((cyClient / (extent + 1))*extent) + 2;
Polygon(hdc, rect_x_y, 4);//绘制棋盘边框
//画横线
for (i = 0; i < extent; i++)
{
start_x = cxClient / (extent+1);
start_y =i*(cyClient / (extent + 1)) + (cyClient / (extent + 1));
end_x = (cxClient / (extent + 1))*extent;
end_y= i*(cyClient / (extent + 1)) + (cyClient / (extent + 1));
MoveToEx(hdc, start_x, start_y, NULL);
LineTo(hdc, end_x, end_y);
}
//画竖线
for (i = 0; i < extent; i++)
{
start_x = i*(cxClient / (extent + 1))+ (cxClient / (extent + 1));
start_y = cyClient / (extent + 1);
end_x = (cxClient / (extent + 1))*i+ (cxClient / (extent + 1));
end_y =( cyClient / (extent + 1))*extent;
MoveToEx(hdc, start_x, start_y, NULL);
LineTo(hdc, end_x, end_y);
}
return 0;
}
int z_initialise_chessboard(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER],int cxClient,int cyClient,bool is_initialise)//初始化棋盘,更新棋盘坐标,需提供客户区大小,如果is_initialise值为true,则初始化棋盘颜色
{
int i, j;
int x,y;
for (i = 0; i < CHESSBOARD_NUMBER; i++)
{
for (j = 0; j < CHESSBOARD_NUMBER; j++)
{
x = j*(cxClient / (CHESSBOARD_NUMBER+1)) + (cxClient / (CHESSBOARD_NUMBER+1));
y = i*(cyClient / (CHESSBOARD_NUMBER+1)) + (cyClient / (CHESSBOARD_NUMBER+1));
arr_chessboard[i][j].x_y.x = x;
arr_chessboard[i][j].x_y.y = y;
if (is_initialise == true)
{
arr_chessboard[i][j].chess_color = (int)NULL;
//以下为实验代码
//arr_chessboard[i][j].chess_color = WHITE_CHESS_PIECES;
}
}
}
return 0;
}
int z_Draw_chesspieces(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER], HDC hdc,HWND hwnd)//绘制棋子
{
int i, j;
RECT rect;
int chess_pieces_width;//棋子宽度
int chess_pieces_height;//棋子高度
HBRUSH white_brush, black_brush, Old_brush;
HPEN black_pen, white_pen, Old_pen;
white_brush = CreateSolidBrush(RGB(255, 255,255));//创建白色画刷
black_brush = CreateSolidBrush(RGB(64, 25, 43));//创建黑色画刷
black_pen = CreatePen(PS_SOLID, 1, RGB(34, 14, 23));//创建黑色画笔
white_pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));//创建黑白色画笔
GetClientRect(hwnd, &rect);//获取客户矩形
chess_pieces_width = (int)(rect.right / (CHESSBOARD_NUMBER + 1))*(double)(1.2 / 3.0);//计算棋子宽度半径
chess_pieces_height = (int)(rect.bottom / (CHESSBOARD_NUMBER + 1))*(double)(1.2 / 3.0);//计算棋子高度半径
//绘制棋盘加粗点
Old_brush = SelectObject(hdc, black_brush);
Old_pen = SelectObject(hdc, white_pen);
Ellipse(hdc, arr_chessboard[3][3].x_y.x -5, arr_chessboard[3][3].x_y.y - 5, \
arr_chessboard[3][3].x_y.x + 5, arr_chessboard[3][3].x_y.y + 5);
Ellipse(hdc, arr_chessboard[3][11].x_y.x - 5, arr_chessboard[3][11].x_y.y - 5, \
arr_chessboard[3][11].x_y.x + 5, arr_chessboard[3][11].x_y.y + 5);
Ellipse(hdc, arr_chessboard[11][3].x_y.x - 5, arr_chessboard[11][3].x_y.y - 5, \
arr_chessboard[11][3].x_y.x + 5, arr_chessboard[11][3].x_y.y + 5);
Ellipse(hdc, arr_chessboard[11][11].x_y.x -5, arr_chessboard[11][11].x_y.y - 5, \
arr_chessboard[11][11].x_y.x + 5, arr_chessboard[11][11].x_y.y + 5);
Ellipse(hdc, arr_chessboard[7][7].x_y.x - 5, arr_chessboard[7][7].x_y.y - 5, \
arr_chessboard[7][7].x_y.x + 5, arr_chessboard[7][7].x_y.y + 5);
////绘制待下棋子
if (pr_chess_color == WHITE_CHESS_PIECES)//绘制白棋
{
Old_brush = SelectObject(hdc, white_brush);
Old_pen = SelectObject(hdc, black_pen);
Ellipse(hdc, arr_chessboard[0][0].x_y.x, \
arr_chessboard[0][0].x_y.y - (chess_pieces_height * 2), \
arr_chessboard[0][0].x_y.x + (chess_pieces_width * 2), \
arr_chessboard[0][0].x_y.y -3);
SelectObject(hdc, Old_brush);
SelectObject(hdc, Old_pen);
}
else//绘制黑棋
{
Old_brush = SelectObject(hdc, black_brush);
Old_pen = SelectObject(hdc, white_pen);
Ellipse(hdc, arr_chessboard[0][0].x_y.x, \
arr_chessboard[0][0].x_y.y - (chess_pieces_height*2), \
arr_chessboard[0][0].x_y.x + (chess_pieces_width*2), \
arr_chessboard[0][0].x_y.y -3);
SelectObject(hdc, Old_brush);
SelectObject(hdc, Old_pen);
}
//绘制待下棋子end
SelectObject(hdc, Old_brush);
SelectObject(hdc, Old_pen);
for (i = 0; i < CHESSBOARD_NUMBER; i++)
{
for (j = 0; j < CHESSBOARD_NUMBER; j++)
{
if (arr_chessboard[i][j].chess_color == WHITE_CHESS_PIECES)//绘制白棋
{
//MessageBox(0, TEXT("hellow"), TEXT("Hi"), MB_OK);
Old_brush = SelectObject(hdc, white_brush);
Old_pen = SelectObject(hdc, black_pen);
Ellipse(hdc, arr_chessboard[i][j].x_y.x - chess_pieces_width, \
arr_chessboard[i][j].x_y.y - chess_pieces_height, \
arr_chessboard[i][j].x_y.x + chess_pieces_width, \
arr_chessboard[i][j].x_y.y + chess_pieces_height);
SelectObject(hdc, Old_brush);
SelectObject(hdc, Old_pen);
}
else if (arr_chessboard[i][j].chess_color == BLACK_CHESS_PIECES)//绘制黑棋
{
Old_brush = SelectObject(hdc, black_brush);
Old_pen = SelectObject(hdc, white_pen);
Ellipse(hdc, arr_chessboard[i][j].x_y.x - chess_pieces_width, \
arr_chessboard[i][j].x_y.y - chess_pieces_height, \
arr_chessboard[i][j].x_y.x + chess_pieces_width, \
arr_chessboard[i][j].x_y.y + chess_pieces_height);
SelectObject(hdc, Old_brush);
SelectObject(hdc, Old_pen);
}
}
}
DeleteObject(white_pen);
DeleteObject(white_brush);
DeleteObject(black_pen);
DeleteObject(black_brush);
return 0;
}
int z_xiaqi(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER], int x, int y,HWND hwnd)//下棋
{
int i, j;
RECT rect;
int chess_pieces_width;//棋子宽度
int chess_pieces_height;//棋子高度
GetClientRect(hwnd, &rect);//获取客户矩形
chess_pieces_width = (int)(rect.right / (CHESSBOARD_NUMBER + 1))*(double)(1 / 3.0);//计算棋子宽度
chess_pieces_height = (int)(rect.bottom / (CHESSBOARD_NUMBER + 1))*(double)(1 / 3.0);//计算棋子高度
for (i = 0; i < CHESSBOARD_NUMBER; i++)
{
for (j = 0; j < CHESSBOARD_NUMBER; j++)
{
if ((arr_chessboard[i][j].x_y.x - chess_pieces_width<x) &\
(arr_chessboard[i][j].x_y.y - chess_pieces_height<y) &\
(arr_chessboard[i][j].x_y.x + chess_pieces_width>x) &\
(arr_chessboard[i][j].x_y.y + chess_pieces_height>y) & \
((arr_chessboard[i][j].chess_color!= WHITE_CHESS_PIECES) \
& (arr_chessboard[i][j].chess_color != BLACK_CHESS_PIECES)))
{
arr_chessboard[i][j].chess_color = pr_chess_color;
if (pr_chess_color == WHITE_CHESS_PIECES)
{
pr_chess_color = BLACK_CHESS_PIECES;
}
else if (pr_chess_color == BLACK_CHESS_PIECES)
{
pr_chess_color = WHITE_CHESS_PIECES;
}
}
}
}
return 0;
}
int z_is_ok(struct st_chess_pieces arr_chessboard[CHESSBOARD_NUMBER][CHESSBOARD_NUMBER])//判断是否赢棋,黑子赢返回1,白棋赢返回2
{
int x, y=0, old_x,old_y=0;//
int black_pieces_count=0;//黑子连子数量
int white_pieces_count=0;//白子连子数量
for (x = 0; x <= CHESSBOARD_NUMBER; x++)//左上到右下扫描
{
if (x == CHESSBOARD_NUMBER)
{
x = CHESSBOARD_NUMBER - 1;
}
old_x = x;//保存x值,因为while循环中需要改变x值
//初始化棋子连子数量为0
white_pieces_count = 0;
black_pieces_count = 0;
while (1)
{
if (arr_chessboard[x][y].chess_color == WHITE_CHESS_PIECES)//白子连子
{
white_pieces_count++;
black_pieces_count = 0;
}
if (arr_chessboard[x][y].chess_color == BLACK_CHESS_PIECES)//黑子连子
{
black_pieces_count++;
white_pieces_count = 0;
}
else if ((arr_chessboard[x][y].chess_color != WHITE_CHESS_PIECES) & (arr_chessboard[x][y].chess_color != BLACK_CHESS_PIECES))
{ black_pieces_count = 0; white_pieces_count = 0; }//既不是白子连子也不是黑子连子
if (black_pieces_count == 5)//黑子胜,返回1
{
return 1;
}
if(white_pieces_count == 5)//白子胜,返回2
{
return 2;
}
if ((y == (CHESSBOARD_NUMBER - 1)) & (x == (CHESSBOARD_NUMBER - 1)))//判断已寻找到最右下角坐标,结束循环
{
goto one;
}
if((++y>(CHESSBOARD_NUMBER-1)) | (--x<0))//x轴或y轴超出范围,结束当前扫描
{
break;
}
}
x = old_x;//还原x进while循环前的值
if (x == CHESSBOARD_NUMBER-1)
{
old_y++;
y = old_y;
}
else
{
y = 0;
}
}
one:old_x = 0;
y = CHESSBOARD_NUMBER-1;
x = 0;
while (1)//左下到右上扫描
{
if (y == 0)
{
y = 0;
}
white_pieces_count = 0;
black_pieces_count = 0;
old_y = y;
while (1)
{
if (arr_chessboard[x][y].chess_color == WHITE_CHESS_PIECES)//白子连子
{
white_pieces_count++;
black_pieces_count = 0;
}
if (arr_chessboard[x][y].chess_color == BLACK_CHESS_PIECES)//黑子连子
{
black_pieces_count++;
white_pieces_count = 0;
}
else if ((arr_chessboard[x][y].chess_color != WHITE_CHESS_PIECES) & (arr_chessboard[x][y].chess_color != BLACK_CHESS_PIECES))
{
black_pieces_count = 0; white_pieces_count = 0;
}//既不是白子连子也不是黑子连子
if (black_pieces_count == 5)//黑子胜,返回1
{
return 1;
}
if (white_pieces_count == 5)//白子胜,返回2
{
return 2;
}
if ((y == 0) & (x == (CHESSBOARD_NUMBER - 1)))//判断已寻找到最右上角坐标,结束循环
{
goto two;
}
if ((++y > (CHESSBOARD_NUMBER - 1)) | (++x >(CHESSBOARD_NUMBER - 1)))//x轴或y轴超出范围,结束当前扫描
{
break;
}
}
if (old_y == 0)
{
old_x++;
x = old_x;
y = 0;
}
else
{
x = 0;
y = --old_y;
}
}
two:
for (y = 0; y <= (CHESSBOARD_NUMBER - 1); y++)//横向扫描
{
white_pieces_count = 0;
black_pieces_count = 0;
for(x=0;x<=(CHESSBOARD_NUMBER-1);x++)
{
if (arr_chessboard[x][y].chess_color == WHITE_CHESS_PIECES)//白子连子
{
white_pieces_count++;
black_pieces_count = 0;
}
if (arr_chessboard[x][y].chess_color == BLACK_CHESS_PIECES)//黑子连子
{
black_pieces_count++;
white_pieces_count = 0;
}
else if ((arr_chessboard[x][y].chess_color != WHITE_CHESS_PIECES) & (arr_chessboard[x][y].chess_color != BLACK_CHESS_PIECES))
{
black_pieces_count = 0; white_pieces_count = 0;
}//既不是白子连子也不是黑子连子
if (black_pieces_count == 5)//黑子胜,返回1
{
return 1;
}
if (white_pieces_count == 5)//白子胜,返回2
{
return 2;
}
}
}
for (x = 0; x <= (CHESSBOARD_NUMBER - 1); x++)//竖向扫描
{
white_pieces_count = 0;
black_pieces_count = 0;
for (y = 0; y <= (CHESSBOARD_NUMBER - 1); y++)
{
if (arr_chessboard[x][y].chess_color == WHITE_CHESS_PIECES)//白子连子
{
white_pieces_count++;
black_pieces_count = 0;
}
if (arr_chessboard[x][y].chess_color == BLACK_CHESS_PIECES)//黑子连子
{
black_pieces_count++;
white_pieces_count = 0;
}
else if ((arr_chessboard[x][y].chess_color != WHITE_CHESS_PIECES) & (arr_chessboard[x][y].chess_color != BLACK_CHESS_PIECES))
{
black_pieces_count = 0; white_pieces_count = 0;
}//既不是白子连子也不是黑子连子
if (black_pieces_count == 5)//黑子胜,返回1
{
return 1;
}
if (white_pieces_count == 5)//白子胜,返回2
{
return 2;
}
}
}
return 0;
}