【精选】适合初学者小游戏井字棋(三子棋)(C语言),Easyx图形库应用+源代码分享

简介: 【精选】井字棋(三子棋,C语言)

【精选】井字棋(三子棋,C语言)


游戏展示(点击链接)

三子棋程序视频展示


一、项目环境

1.Visual Studio 2022
2.安装easyx图形库,可以调用头文件

include<easyx.h>


简单介绍一下easyx图形库

EasyX库是一个基于C语言的图形界面库,可以用于Windows操作系统下的图形界面应用程序开发。该库提供了一些易于使用的图形绘制函数和简单的事件处理功能,可以帮助开发者快速地创建各种图形应用程序,如游戏、图形编辑器等。
EasyX库提供了丰富的绘图功能,如直线、矩形、圆形、椭圆、多边形等基本形状的绘制,同时还支持图片、文字、音频等多种媒体资源的加载和处理。此外,EasyX库还支持鼠标、键盘等多种事件的处理,可以让用户与应用程序进行交互。
EasyX库的另一个特点是易于学习和使用。它提供了简单的API,使得初学者也可以轻松地入门,并且具有丰富的在线文档和示例程序,帮助开发者快速地学习和理解如何使用这个库。除此之外,EasyX库还可以和Visual Studio等常见的集成开发环境进行配合使用,使得开发工作更加高效。
总之,EasyX库是一款简单易用、功能强大的图形界面库,适用于初学者和有一定编程基础的开发者,可以用于快速开发各种图形应用程序。


Easyx图形库

点击跳转到easyx图形库下载官网


二、游戏规则介绍

井字棋是一种简单的二人棋类游戏,通常在3x3的棋盘上进行,其中一方执X,另一方执O。游戏的目标是在棋盘上先将自己的符号排成一条直线,横线、竖线或斜线即可获胜。
具体游戏规则如下:
1、玩家与电脑轮流下棋,先手执O,后手执X;
2、玩家在空位上下棋,不能在已经有棋子的位置下;
3、当任意一方在棋盘上成功排成三个相同的符号直线时,该方获胜;
4、如果棋盘被下满但是没有任何一方成功排成一条直线,则平局。


三、运行效果展示

Step1:获胜
请添加图片描述
Step2:失败
请添加图片描述
Step3:平局
请添加图片描述


四、项目介绍

三子棋是一种经典的棋类游戏,玩家通过在棋盘上落子,以先在横、竖、斜线上连成三个相同棋子为胜利条件。为了让更多的人了解和体验三子棋的乐趣,本文使用C语言和EASYX图形库开发了一款三子棋项目。


五、项目源代码分享

井字棋游戏代码如下:

#include<stdio.h>
#include<easyx.h>
#include<graphics.h>
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include<iostream>
#include<Windows.h>
using namespace std;
int jingziqi(int &kk)
{
    //画格子
    setlinestyle(PS_SOLID, 4);
    setlinecolor(BLACK);
    //横线
    line(-300, 298, 300, 298);
    line(-300, 100, 300, 100);
    line(-300, -100, 300, -100);
    line(-300, -298, 300, -298);
    //竖线
    line(-298, 300, -298, -300);
    line(-100, 300, -100, -300);
    line(100, 300, 100, -300);
    line(298, 300, 298, -300);
    //将格子初始化为0
    int a[3][3];
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            a[i][j] = 0;
        }
    }
    //鼠标消息——由于玩家先手标记并画圈圈
    //用1来标记圆圈
    //用2来标记叉叉
    int f = 2;
    while (1)
    {
        if (MouseHit())//判断是否有鼠标信息
        {
            MOUSEMSG msg = GetMouseMsg();//接收鼠标信息     
            printf("坐标(%d,%d)\n", msg.x, msg.y);
            switch (msg.uMsg)
            {
            case WM_LBUTTONDOWN:
                //第一行
                if (msg.x > 1 && msg.x < 199 && msg.y>1 && msg.y < 199)
                {
                    a[0][0] = 1;
                    setlinecolor(BLUE);
                    fillcircle(-200, 200, 100);
                    f = f + 1;
                    continue;
                }
                if (msg.x > 200 && msg.x < 400 && msg.y>1 && msg.y < 199)
                {
                    a[0][1] = 1;
                    setlinecolor(BLUE);
                    fillcircle(0, 200, 100);
                    f = f + 1;
                    continue;
                }
                if (msg.x > 400 && msg.x < 600 && msg.y>1 && msg.y < 199)
                {
                    a[0][2] = 1;
                    setlinecolor(BLUE);
                    fillcircle(200, 200, 100);
                    f = f + 1;
                    continue;
                }
                //第二行
                if (msg.x > 1 && msg.x < 200 && msg.y>200 && msg.y < 400)
                {
                    a[1][0] = 1;
                    setlinecolor(BLUE);
                    fillcircle(-200, 0, 100);
                    f = f + 1;
                    continue;
                }
                if (msg.x > 200 && msg.x < 400 && msg.y>200 && msg.y < 400)
                {
                    a[1][1] = 1;
                    setlinecolor(BLUE);
                    fillcircle(0, 0, 100);
                    f = f + 1;
                    continue;
                }
                if (msg.x > 400 && msg.x < 600 && msg.y>200 && msg.y < 400)
                {
                    a[1][2] = 1;
                    setlinecolor(BLUE);
                    fillcircle(200, 0, 100);
                    f = f + 1;
                    continue;
                }
                //第三行
                if (msg.x > 1 && msg.x < 200 && msg.y>400 && msg.y < 600)
                {
                    a[2][0] = 1;
                    setlinecolor(BLUE);
                    fillcircle(-200, -200, 100);
                    f = f + 1;
                    continue;
                }
                if (msg.x > 200 && msg.x < 400 && msg.y>400 && msg.y < 600)
                {
                    a[2][1] = 1;
                    setlinecolor(BLUE);
                    fillcircle(0, -200, 100);
                    f = f + 1;
                    continue;
                }
                if (msg.x > 400 && msg.x < 600 && msg.y>400 && msg.y < 600)
                {
                    a[2][2] = 1;
                    setlinecolor(BLUE);
                    fillcircle(200, -200, 100);
                    f = f + 1;
                    continue;
                }
            }
        }
        //随机画叉叉
        int x1 = -300, y1 = 300, x2 = -100, y2 = 100;//撇
        int x3 = -100, y3 = 300, x4 = -300, y4 = 100;//捺
        int i, j;
        i = rand() % 3;//取0~2的随机数
        j = rand() % 3;//取0~2的随机数
        if (a[j][i] == 0 && f % 2 != 0 && a[j][i] != 1)
        {
            a[j][i] = 2;//标记叉叉为2
            setlinecolor(RED);
            line(-300 + i * 200, 300 - j * 200, -100 + i * 200, 100 - j * 200);
            line(-100 + i * 200, 300 - j * 200, -300 + i * 200, 100 - j * 200);
            f++;
            continue;
        }
        //横向
        if (a[0][0] == 1 && a[0][1] == 1 && a[0][2] == 1)
        {
            //cout << "xiaoa wins.";
            setlinecolor(RGB(0, 240, 255));
            setlinestyle(PS_ENDCAP_ROUND, 8);
            line(-200, 200, 200, 200);
            break;
        }
        if (a[1][0] == 1 && a[1][1] == 1 && a[1][2] == 1)
        {
            //cout << "xiaoa wins.";
            setlinecolor(RGB(0, 240, 255));
            setlinestyle(PS_ENDCAP_ROUND, 8);
            line(-200, 0, 200, 0);
            break;
        }
        if (a[2][0] == 1 && a[2][1] == 1 && a[2][2] == 1)
        {
            //cout << "xiaoa wins.";
            setlinecolor(RGB(0, 240, 255));
            setlinestyle(PS_ENDCAP_ROUND, 8);
            line(-200, -200, 200, -200);
            break;
        }
        //竖向
        if (a[0][0] == 1 && a[1][0] == 1 && a[2][0] == 1)
        {
            //cout << "xiaoa wins.";
            setlinecolor(RGB(0, 240, 255));
            setlinestyle(PS_ENDCAP_ROUND, 8);
            line(-200, 200, -200, -200);
            break;
        }
        if (a[0][1] == 1 && a[1][1] == 1 && a[2][1] == 1)
        {
            //cout << "xiaoa wins.";
            setlinecolor(RGB(0, 240, 255));
            setlinestyle(PS_ENDCAP_ROUND, 8);
            line(0, 200, 0, -200);
            break;
        }
        if (a[0][2] == 1 && a[1][2] == 1 && a[2][2] == 1)
        {
            //cout << "xiaoa wins.";
            setlinecolor(RGB(0, 240, 255));
            setlinestyle(PS_ENDCAP_ROUND, 8);
            line(200, 200, 200, -200);
            break;
        }
        //斜向
        if (a[0][0] == 1 && a[1][1] == 1 && a[2][2] == 1)
        {
            //cout << "xiaoa wins.";
            setlinecolor(RGB(0, 240, 255));
            setlinestyle(PS_ENDCAP_ROUND, 8);
            line(-200, 200, 200, -200);
            break;
        }
        if (a[0][2] == 1 && a[1][1] == 1 && a[2][0] == 1)
        {
            //cout << "xiaoa wins.";
            setlinecolor(RGB(0, 240, 255));
            setlinestyle(PS_ENDCAP_ROUND, 8);
            line(-200, -200, 200, 200);
            break;
        }
        //输了
        if (a[0][0] == 2 && a[0][1] == 2 && a[0][2] == 2)
        {
            setlinecolor(RGB(0, 240, 255));
            setlinestyle(PS_ENDCAP_ROUND, 8);
            line(-200, 200, 200, 200);
            kk = 1;
            break;
        }
        if (a[1][0] == 2 && a[1][1] == 2 && a[1][2] == 2)
        {
            setlinecolor(RGB(0, 240, 255));
            setlinestyle(PS_ENDCAP_ROUND, 8);
            line(-200, 0, 200, 0);
            kk = 1;
            break;
        }
        if (a[2][0] == 2 && a[2][1] == 2 && a[2][2] == 2)
        {
            setlinecolor(RGB(0, 240, 255));
            setlinestyle(PS_ENDCAP_ROUND, 8);
            line(-200, -200, 200, -200);
            kk = 1;
            break;
        }
        //竖向
        if (a[0][0] == 2 && a[1][0] == 2 && a[2][0] == 2)
        {
            setlinecolor(RGB(0, 240, 255));
            setlinestyle(PS_ENDCAP_ROUND, 8);
            line(-200, 200, -200, -200);
            kk = 1;
            break;
        }
        if (a[0][1] == 2 && a[1][1] == 2 && a[2][1] == 2)
        {
            setlinecolor(RGB(0, 240, 255));
            setlinestyle(PS_ENDCAP_ROUND, 8);
            line(0, 200, 0, -200);
            kk = 1;
            break;
        }
        if (a[0][2] == 2 && a[1][2] == 2 && a[2][2] == 2)
        {
            setlinecolor(RGB(0, 240, 255));
            setlinestyle(PS_ENDCAP_ROUND, 8);
            line(200, 200, 200, -200);
            kk = 1;
            break;
        }
        //斜向
        if (a[0][0] == 2 && a[1][1] == 2 && a[2][2] == 2)
        {
            setlinecolor(RGB(0, 240, 255));
            setlinestyle(PS_ENDCAP_ROUND, 8);
            line(-200, 200, 200, -200);
            kk = 1;
            break;
        }
        if (a[0][2] == 2 && a[1][1] == 2 && a[2][0] == 2)
        {
            setlinecolor(RGB(0, 240, 255));
            setlinestyle(PS_ENDCAP_ROUND, 8);
            line(-200, -200, 200, 200);
            kk = 1;
            break;
        }
        //平局现象
        if (a[0][0] != 0 && a[0][1] != 0 && a[0][2] != 0 && a[1][0] != 0 && a[1][1] != 0 && a[1][2] != 0 && a[2][0] != 0 && a[2][1] != 0 && a[2][2] != 0)
        {
            kk = 2;
            break;
        }
    }
    return kk;
}
int Interactioninthecheckerswindow(int kk,int &kaishichongqi)
{
    setlinestyle(PS_ENDCAP_ROUND, 3);
    setlinecolor(BLACK);
    setfillcolor(WHITE);
    fillrectangle(-250, 80, 250, -80);

    LOGFONT fontstyle;
    gettextstyle(&fontstyle);
    fontstyle.lfQuality = ANTIALIASED_QUALITY;//抗锯齿

    setaspectratio(1, 1);

    RECT rect;
    rect.left = -250;
    rect.top = -250;
    rect.right = 250;
    rect.bottom = 250;
    settextstyle(&fontstyle);
    setbkmode(TRANSPARENT);//设置字体背景
    settextcolor(BLACK);//字体颜色
    settextstyle(45, 0, "微软雅黑");//设置字体样式
    //赢了
    if (kk == 0)
    {
        drawtext(_T("恭喜玩家成功通过第1关(*^__^*)"), &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

        //获取句柄
        HWND hnd = GetHWnd();
        //设置窗口标题
        SetWindowText(hnd, "井字棋");
        //弹出窗口
        int isok = MessageBox(hnd, "是否进入第2关", "游戏提示", MB_YESNO);
        if (isok == IDYES)
        {
            printf("你点击了YES\n");
        }
        else if (isok == IDNO)
        {
            printf("你点击了NO\n");
            closegraph();
            return 0;
        }
    }
    //输了
    if (kk == 1)
    {
        drawtext(_T("你输了是否选择重新再来!"), &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

        //获取句柄
        HWND hnd = GetHWnd();
        //设置窗口标题
        SetWindowText(hnd, "井字棋");
        //弹出窗口
        int isok = MessageBox(hnd, "是否重新开始游戏!", "游戏提示", MB_YESNO);
        if (isok == IDYES)
        {
            printf("你点击了YES\n");
            kaishichongqi = 1;
            return kaishichongqi;

        }
        else if (isok == IDNO)
        {
            printf("你点击了NO\n");
            closegraph();
            return 0;
        }
    }

    //平局现象
    if (kk == 2)
    {
        drawtext(_T("平局是否选择重新开始!"), &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

        //获取句柄
        HWND hnd = GetHWnd();
        //设置窗口标题
        SetWindowText(hnd, "井字棋");
        //弹出窗口
        int isok = MessageBox(hnd, "是否重新开始游戏!", "游戏提示", MB_YESNO);
        if (isok == IDYES)
        {
            printf("你点击了YES\n");
            kaishichongqi = 1;
            return kaishichongqi;

        }
        else if (isok == IDNO)
        {
            printf("你点击了NO\n");
            closegraph();
            return 0;
        }
    }
}
int Tickgamewindow()
{
    
    int kk = 0,kaishichongqi=0;
    initgraph(600, 600);
    setbkcolor(WHITE);
    cleardevice();
    setorigin(300, 300);
    setaspectratio(1, -1);
    jingziqi(kk);
    cout << kk;
    Interactioninthecheckerswindow(kk,kaishichongqi);
    cout << kaishichongqi << endl;
    if (kaishichongqi == 1)
    {
        Tickgamewindow();
    }

    return kk;
}
int main()
{
    Tickgamewindow();
    getchar();
    closegraph();
    return 0;
}


总结与思考

刚学完easyx库后就开始拿经典的井字棋游戏开始练习了,大概用了五六个小时左右,中途也遇到了些问题但最后都顺利的解决了。


Bug遗留问题

项目中有一处bug并未修改,感觉无伤大雅就放那了


Bug调试图如下:

请添加图片描述


如图所示:可以在原本叉叉的上面直接覆盖,就是说玩家绝对输不了,必赢的游戏。

当然想要修改也可以试着改一下文中的源代码,这个用的是二维数组写的,加了些判断条件,改也很容易把判断条件简单修改一下即可,追求完美的猿子们可以尝试一下哦🤭
相关文章
|
3天前
|
Java Unix Linux
1.3 C语言的应用范围
C语言自20世纪80年代以来一直是主流编程语言,适用于小型计算机、个人电脑及大型机。因其高效紧凑且易于修改和移植,广泛用于软件开发。尽管后来C++和JAVA流行起来,但C语言仍然是软件行业核心,并在嵌入式系统、科学编程和操作系统开发如Linux中扮演重要角色。即使到现在,掌握C语言仍是一项重要技能。不是必须得是计算机专家才能使用C语言,学习C语言同时也能学到很多C++的知识。
26 8
|
14天前
|
定位技术 API C语言
C语言——实现贪吃蛇小游戏
本文介绍了一个基于Windows控制台的贪吃蛇游戏的实现方法。首先,需调整控制台界面以便更好地显示游戏。接着,文章详细描述了如何使用Win32 API函数如`COORD`、`GetStdHandle`、`GetConsoleCursorInfo`等来控制控制台的光标和窗口属性。此外,还介绍了如何利用`GetAsyncKeyState`函数实现键盘监听功能。文中还涉及了`&lt;locale.h&gt;`库的使用,以支持本地化字符显示。
31 1
C语言——实现贪吃蛇小游戏
|
14天前
|
存储 安全 算法
C 语言——实现扫雷小游戏
本文介绍了使用二维数组创建棋盘并实现扫雷游戏的方法。首先,通过初始化数组创建一个9x9的棋盘,并添加行列标识以便操作。接着,利用随机数在棋盘上布置雷。最后,通过判断玩家输入的坐标来实现扫雷功能,包括显示雷的数量和处理游戏胜利或失败的情况。文中提供了完整的代码实现。
36 1
C 语言——实现扫雷小游戏
|
26天前
|
存储 C语言
数据结构基础详解(C语言): 树与二叉树的应用_哈夫曼树与哈夫曼曼编码_并查集_二叉排序树_平衡二叉树
本文详细介绍了树与二叉树的应用,涵盖哈夫曼树与哈夫曼编码、并查集以及二叉排序树等内容。首先讲解了哈夫曼树的构造方法及其在数据压缩中的应用;接着介绍了并查集的基本概念、存储结构及优化方法;随后探讨了二叉排序树的定义、查找、插入和删除操作;最后阐述了平衡二叉树的概念及其在保证树平衡状态下的插入和删除操作。通过本文,读者可以全面了解树与二叉树在实际问题中的应用技巧和优化策略。
|
1月前
|
存储 安全 C语言
C语言 二级指针应用场景
本文介绍了二级指针在 C 语言中的应用,
|
2月前
|
C语言
C语言中的math库概述
C语言中的math库概述
|
2月前
|
程序员 C语言
位操作在C语言中的解析与应用
位操作在C语言中的解析与应用
75 0
|
2月前
|
程序员 编译器 C语言
C语言中的预处理指令及其实际应用
C语言中的预处理指令及其实际应用
62 0
|
2月前
|
存储 Serverless C语言
C语言中的标准库函数
C语言中的标准库函数
31 0
|
2月前
|
API 开发工具 C语言
C语言与图形界面:利用GTK+、Qt等库创建GUI应用。
C语言与图形界面:利用GTK+、Qt等库创建GUI应用。
83 0
下一篇
无影云桌面