双人五子棋
//windows.h文件中包含应用程序中所需的数据类型和数据结构的定义 #include <windows.h> #include <stdlib.h> #include <time.h> #include <string.h> #include <stdio.h> #include <math.h> #define PI acos(-1) LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//窗口函数说明 //---------以下初始化窗口类-------------- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdLine,int nCmdShow) { HWND hwnd; MSG Msg; WNDCLASS wndclass; char lpszClassName[] = "窗口"; //窗口类名 char lpszTitle[] = "[Vic.]To your major, I'm minor."; //窗口标题名 //窗口类的定义 wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; //窗口类型为默认类型 wndclass.lpfnWndProc = WndProc; //窗口处理函数为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 = lpszClassName; //窗口类名为“窗口示例” //-----------以下进行窗口类的注册 if (!RegisterClass(&wndclass))//如果注册失败则发出警吿声音 { MessageBeep (0); return FALSE; } //创建窗口 hwnd = CreateWindow( lpszClassName, //窗口类名 lpszTitle, //窗口实例的标题名 WS_OVERLAPPEDWINDOW, //窗口 的风格 CW_USEDEFAULT, CW_USEDEFAULT, //窗口左上角坐标为默认值 CW_USEDEFAULT, CW_USEDEFAULT, //窗口的髙和宽为默认值 NULL, //此窗口无父窗口 NULL, //此窗口无主菜单 hInstance, //创建此窗口应用程序的当前句柄 NULL //不使用该值 ); ShowWindow( hwnd, nCmdShow); //显示窗口 UpdateWindow(hwnd); //绘制用户区 while( GetMessage(&Msg, NULL, 0, 0)) //消息循环 { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; //程序终止时将信息返回系统 } int state[15][15]; //棋盘状态数组 0代表没有 int Winner = 0; //胜者 -1代表黑 1代表白色 0代表没有 void CheckWinner(int mx,int my, int color) { TCHAR win[20]; int a, b; int xD = mx-4,xU=mx+4,yD=my-4, yU=my+4; if (mx - 4 < 0) xD = 0; if (mx + 4 > 14) xU = 14; if (my - 4 < 0) yD = 0; if (my + 4 > 14) yU = 14; for (a=xD;a<=xU;a++)//判断横 { if(state[a][my]==color&&state[a+1][my]==color&&state[a+2][my]==color&&state[a+3][my]==color&&state[a+4][my]==color) { Winner = color; return ; } } for(b=yD;b<=yU;b++)//判断竖 { if(state[mx][b]==color&&state[mx][b+1]==color&&state[mx][b+2]==color&&state[mx][b+3]==color&&state[mx][b+4]==color) { Winner = color; return ; } } for(a=xD,b=yD;a<=xU;a++,b++)//判断右斜 { if(state[a][b]==color&&state[a+1][b+1]==color&&state[a+2][b+2]==color&&state[a+3][b+3]==color&&state[a+4][b+4]==color) { Winner = color; return ; } } for(a=xD,b=yU;a<=xU;a++,b--)//判断左斜 { if(state[a][b]==color&&state[a+1][b-1]==color&&state[a+2][b-2]==color&&state[a+3][b-3]==color&&state[a+4][b-4]==color) { Winner = color; return ; } } } LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { HDC hDC, hdc_old; HBITMAP hBmp, hBkBmp; RECT rect; HBRUSH hBrush; PAINTSTRUCT Ps; TEXTMETRIC tm; HFONT hf; HCURSOR hCursor; HPEN hPen; SIZE Sz; int i, j; static int x, y; static int zColor = -1; // -1代表黑 1代表白色 static bool isEnd = false, isRestart = false; int r = 5; int R = 12; COLORREF color[3] = {RGB(255,0,0), RGB(0,255,0), RGB(0,0,255)}; switch(message) { case WM_MOUSEMOVE: x = LOWORD(lParam); y = HIWORD(lParam); InvalidateRect(hWnd, NULL,1); return 0; case WM_LBUTTONDOWN: if (!Winner) { if (x <= 535 && x >= 85 && y <= 535 && y >= 85) { //判断鼠标在哪个落子区 for (i = 0; i < 450; i+=30) if (x >=100+i-30+15 && x <= 100+i+15) break; for (j = 0; j < 450; j+=30) if (y >=100+j-30+15 && y <= 100+j+15) break; if (state[i/30][j/30]) return 0; state[i/30][j/30] = zColor; zColor = -zColor; } CheckWinner(i/30, j/30, -zColor); } else { if (x <= 410 && x >= 210 && y <= 300 && y >= 250) isRestart = true; if (x <= 410 && x >= 210 && y <= 370 && y >= 320) isEnd = true; } InvalidateRect(hWnd, NULL,1); return 0; case WM_LBUTTONUP: return 0; case WM_ERASEBKGND: return 1; case WM_PAINT: hdc_old = BeginPaint(hWnd, &Ps); hDC = CreateCompatibleDC(hdc_old); GetClientRect(hWnd,&rect); hBmp = CreateCompatibleBitmap(hdc_old,rect.right,rect.bottom); SelectObject(hDC,hBmp); hPen = CreatePen(PS_SOLID, 1, RGB(255,255,255)); SelectObject(hDC, hPen); Rectangle(hDC, rect.left, rect.top, rect.right, rect.bottom); DeleteObject(hPen); //画棋盘的格子 hPen = CreatePen(PS_SOLID, 1, RGB(0,0,0)); SelectObject(hDC, hPen); Rectangle(hDC, 100, 100, 520, 520); for (i = 0; i < 420; i+=30) MoveToEx(hDC, 100,i+100,NULL),LineTo(hDC, 520, i+100); for (i = 0; i < 420; i+=30) MoveToEx(hDC, i+100,100,NULL), LineTo(hDC, i+100, 520); //画棋盘上的小圆点 hBrush = CreateSolidBrush(RGB(0,0,0)); SelectObject(hDC, hBrush); Ellipse(hDC, 190-r, 190-r, 190+r, 190+r); Ellipse(hDC, 430-r, 430-r, 430+r, 430+r); Ellipse(hDC, 310-r, 310-r, 310+r, 310+r); Ellipse(hDC, 190-r, 430-r, 190+r, 430+r); Ellipse(hDC, 430-r, 190-r, 430+r, 190+r); DeleteObject(hPen); DeleteObject(hBrush); //画棋盘上的棋子 for (i = 0; i < 15; i++) { for (j = 0; j < 15; j++) { if (state[i][j] == -1) { hBrush = CreateSolidBrush(RGB(0,0,0)); SelectObject(hDC, hBrush); Ellipse(hDC, i*30+100-R, j*30+100-R, i*30+100+R, j*30+100+R); DeleteObject(hBrush); } else if (state[i][j] == 1) { hBrush = CreateSolidBrush(RGB(255,255,255)); SelectObject(hDC, hBrush); Ellipse(hDC, i*30+100-R, j*30+100-R, i*30+100+R, j*30+100+R); DeleteObject(hBrush); } } } //判断是否有人获胜 if (Winner) { hPen = CreatePen(PS_SOLID, 10, RGB(0,0,0)); hBrush = CreateSolidBrush(RGB(255,255,255)); SelectObject(hDC, hBrush); SelectObject(hDC, hPen); Rectangle(hDC, 190, 160, 430, 460); DeleteObject(hBrush); DeleteObject(hPen); hf = CreateFont( //创建自定义字体 40, //字体的高度 0, //由系统根据高宽比选取字体最佳宽度值 0, //文本的倾斜度为0,表示水平 0, //字体的倾斜度为0 FW_HEAVY, //字体的粗度,FW_HEAVY为最粗 0, //非斜体字 0, //无下划线 0, //无删除线 ANSI_CHARSET, //表示所用的字符集为ANSI_CHARSET OUT_DEFAULT_PRECIS, //输出精度为缺省精度 CLIP_DEFAULT_PRECIS, //剪裁精度为缺省精度 DEFAULT_QUALITY, //输出质量为缺省值 DEFAULT_PITCH |FF_DONTCARE, //字间距和字体系列使用缺省值 "粗体字"); //字体名称 SelectObject(hDC, hf); //将自定义字体绑定 if (Winner == 1) { hPen = CreatePen(PS_SOLID, 10, RGB(0,0,0)); SelectObject(hDC, hPen); TextOut(hDC, 230, 180, "白棋获胜!", strlen("白棋获胜!")); DeleteObject(hPen); } else { hPen = CreatePen(PS_SOLID, 10, RGB(0,0,0)); SelectObject(hDC, hPen); TextOut(hDC, 230, 180, "黑棋获胜!", strlen("黑棋获胜!")); DeleteObject(hPen); } hPen = CreatePen(PS_SOLID, 5, RGB(0,0,0)); hBrush = CreateSolidBrush(RGB(255,255,255)); SelectObject(hDC, hBrush); SelectObject(hDC, hPen); if (x <= 410 && x >= 210 && y <= 300 && y >= 250) { SetTextColor(hDC, RGB(255,0,0)); hCursor = LoadCursor(NULL, IDC_HAND); SetCursor(hCursor); } else SetTextColor(hDC, RGB(0,0,0)); Rectangle(hDC, 210, 250, 410, 300); TextOut(hDC, 235, 255, "重新开始", strlen("重新开始")); if (x <= 410 && x >= 210 && y <= 370 && y >= 320) { SetTextColor(hDC, RGB(255,0,0)); hCursor = LoadCursor(NULL, IDC_HAND); SetCursor(hCursor); } else SetTextColor(hDC, RGB(0,0,0)); Rectangle(hDC, 210, 320, 410, 370); TextOut(hDC, 235, 325, "退出游戏", strlen("退出游戏")); DeleteObject(hBrush); DeleteObject(hPen); DeleteObject(hf); } else { //画红色选择区 if (x <= 535 && x >= 85 && y <= 535 && y >= 85) { //判断鼠标在哪个落子区 for (i = 0; i < 450; i+=30) if (x >=100+i-30+15 && x <= 100+i+15) break; for (j = 0; j < 450; j+=30) if (y >=100+j-30+15 && y <= 100+j+15) break; if (state[i/30][j/30]) { hCursor = LoadCursor(NULL, IDC_NO); SetCursor(hCursor); } else { hCursor = LoadCursor(NULL, IDC_HAND); SetCursor(hCursor); hPen = CreatePen(PS_SOLID, 2, RGB(255,0,0)); SelectObject(hDC, hPen); MoveToEx(hDC, 100+i-10, 100+j-15, NULL); LineTo(hDC, 100+i-15, 100+j-15); LineTo(hDC, 100+i-15, 100+j-10); MoveToEx(hDC, 100+i+10, 100+j+15, NULL); LineTo(hDC, 100+i+15, 100+j+15); LineTo(hDC, 100+i+15, 100+j+10); MoveToEx(hDC, 100+i+10, 100+j-15, NULL); LineTo(hDC, 100+i+15, 100+j-15); LineTo(hDC, 100+i+15, 100+j-10); MoveToEx(hDC, 100+i-10, 100+j+15, NULL); LineTo(hDC, 100+i-15, 100+j+15); LineTo(hDC, 100+i-15, 100+j+10); DeleteObject(hPen); } } } if (isRestart) { Winner = 0; memset(state, 0, sizeof(state)); isRestart = false; isEnd = false; zColor = -1; } BitBlt(hdc_old,0,0,rect.right,rect.bottom,hDC,0,0,SRCCOPY); DeleteObject(hBmp); DeleteDC(hDC); ReleaseDC(hWnd, hDC); //释放 EndPaint(hWnd, &Ps); //结束缓制 // if (!isEnd) return 0; case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc(hWnd,message,wParam,lParam); } return 0; }