Windows编程——API双人五子棋

Posted ViKyanite.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Windows编程——API双人五子棋相关的知识,希望对你有一定的参考价值。

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

 

以上是关于Windows编程——API双人五子棋的主要内容,如果未能解决你的问题,请参考以下文章

Verilog基于FPGA的五子棋小游戏(VGA显示双人对战胜负判别附完整代码)

双人组队作业:五子棋

双人五子棋对战(需要EasyX图像库)

基于SpringBoot+MyBatis 五子棋双人对战

双人小游戏—五子棋(c语言)

Java五子棋课程设计