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

原文地址:https://www.cnblogs.com/Vikyanite/p/12641146.html

时间: 2024-08-30 05:18:01

【Windows编程——API】双人五子棋的相关文章

【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, L

【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, L

【Windows编程——API】静态菜单

//windows.h文件中包含应用程序中所需的数据类型和数据结构的定义 #include <windows.h> #include <stdlib.h> #include <time.h> #include "menu_1.h" #include <math.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//窗口函数说明 //---------以下初始化窗口类------

设置windows窗口ICON 【windows 编程】【API】【原创】

1. ICON介绍 最近开始接触windows 编程,因此将自己所接触的一些零散的知识进行整理并记录.本文主要介绍了如何更改windows对话框窗口的ICON图标.这里首先介绍一下windows ICON定义.在我们使用的windows APP上,一般都存在两个ICON.一个是打开APP后显示与左上角的小的图标文件(SMALL ICON)以及按下Alt+Tab切换窗口时显示的一个大的图标文件(BIG ICON).以windows自带的记事本程序为例,小的图标文件如下图1所示: 图1 记事本程序的

【Windows编程】系列第十篇:文本插入符

大家知道,在使用微软的编程环境创建工程时会让你选择是控制台模式还是Windows应用程序.如果选择控制台的console模式,就会在运行时出现一个黑洞洞的字符模式窗口,里面就有等待输入一闪一闪的插入符.输入光标从DOS时代就存在,但是在Win32中赋予了更强大的功能.下图就是Windows的CMD窗口,其中的输入点就是插入光标: 要注意的是这里的插入符或插入光标并不是Windows中另外一个"光标",这里是指示插入字符的位置,而不是用于鼠标,手写输入等可以定位.移动的光标(Cursor

【Windows编程】系列第九篇:剪贴板使用

 上一篇我们学习了常见的通用对话框,本篇来了解剪贴板的使用,它常用于复制粘贴功能. 剪贴板是Windows最早就加入的功能,由于该功能非常实用,我们几乎每天都会使用到.通过剪贴板,我们就可以将数据从一个应用程序传递到另一个应用程序,是一种简单的进程间通信. 许多文档处理软件都有复制.剪切.粘贴功能,这些都是用Windows剪贴板实现的,当然我们也可以在我们的程序中实现自己的剪贴板功能,本篇我们就来实现自己的剪贴板.使用剪贴板时,都是先把源数据先传到剪贴板上,再在需要的时候从剪贴板传输到目的处

【Windows编程】系列第二篇:Windows SDK创建基本控件

在Win32 SDK环境下,怎么来创建常用的那些基本控件呢?我们知道如果用MFC,简单的拖放即可完成大多数控件的创建,但是我们既然是用Windows SDK API编程,当然是从根上解决这个问题,实际上MFC的下层也是通过这些API完成的. 实际上控件也是窗口,只不过是被微软预先创建好的一种窗口类,比如button就是一个类名为“BUTTON”的类.既然控件实际上是窗口,当然也是用CreateWindow或者CreateWindowEx这个函数来完成的,第二个函数除了多一个扩展风格之外,其他完全

Win32 Windows编程 十

一 Windows绘图 1 图形绘制 1.1 图形绘制的方式 获取到绘图的句柄,设备描述符(DC),使用相应的绘图API,在设备上绘制图形 1.2 颜色 RGB,每种颜色8位,共24位颜色 32位颜色:颜色数量24为颜色,多出的8位表示灰度. 16位:颜色数量是2的16次方. Win32下,颜色的定义使用 COLORREF.RGB的宏定义颜色 COLORREF nColor = RGB( 0, 0, 0 );  黑色 COLORREF nColor = RGB( 255, 255, 255 );

操作系统,windows编程,网络,socket

首发:个人博客,更新&纠错&回复 之前关于c/s的一篇博文只记了思路没记代码,而且表达不清晰,事后看不知所云,这个习惯要改. 这十几天学了点关于操作系统.windows编程和网络,主要看的书有以下几本,都没看完或者只看了一点,记下书名先:<现代操作系统><深入解析windows操作系统><windows程序设计><c#入门经典><wpf编程宝典><图解tcp/ip>另外<tcp/ip详解><java网