C语言--五子棋项目【图文详解 经典】

 今天小编带领大家学一学C语言入门必写的五子棋项目,题目非常经典,值得一学。


目录

 

一.目标效果

二.五子棋的元素

1.棋子

 2.棋盘

 三,需要准备的工具

四.具体内容

1.加载背景图片

2.画横线与竖线

3. 画小黑点

4.获取鼠标消息

 5.画棋子

6.如何判断比赛的输赢(核心)

 9.显示游戏结束的提示

 五.完整代码

 六.运行结果

​编辑果

 七.学习时的代码


一.目标效果🍗

能做出一个图形界面,能先下黑棋,后下白棋,能判断输赢,判断输赢后不会再下棋,会显示棋子赢的信息提示。

  • 背景知识(先稍微看一下)
  • 5*15条边,(15条边中间14个格子+左留白0.5+右留白0.5),一共15个格子,一个格子像素40
  • 窗口的大小 15*40=600(x)  600(y)
  • 在第4,12线交界点需要画黑点
  • 在第8线交界点需要画黑点
  • loadimage:用于从文件中读取图像。加载图片
  • putimage:显示图片
  • setlinecolor();
  • line:画线,需要两点坐标
  • setfillcolor:设置填充颜色
  • fillcircle:画填充(实心)圆,参数为坐标,半径
  • getmessage:获取鼠标消息
  • outtextxy:在指定位置(坐标)输出字符串
  •  settextcolor:设置字体颜色
  • settextstyle:设置字体样式

二.五子棋的元素🍗

1.棋子

 棋子分为黑白棋,双方对弈时要将棋子下到交叉点处。

棋盘的每一个交叉点位置设置为三种状态:

0表示没有棋子,1表示黑子,2表示白子。

定义一个全局的二维数组,int pieceArr[NUM][NUM] = { 0 };用来记录棋子的情况

int pieceArr[NUM][NUM] = { 0 };//记录15*15个棋盘的棋子情况,0表示没有棋子,1表示黑子,2表示白子

 2.棋盘🍗

 定义棋盘的线的数量与棋子个数。

#define NUM 15  //15条线
#define WIN_NUM 5//五子棋

棋盘有竖线15条,横线15条。在第4,12线交界点需要画黑点,在第8线交界点需要画黑点。

 三,需要准备的工具🍗

vs编译器是无法直接加载出图形界面,需要两个软件:

一.EasyX,图形(加载图形界面)

二.EasyX_Help( 帮助手册)

如果还不知道的小伙伴可以去看一下前篇文章,这里就不多赘述。

http://t.csdnimg.cn/0mnzJ

四.具体内容🍗

1.加载背景图片

首先要自己打开画图板,选择一种自己喜欢的颜色,涂好后保存。

保存图片。

点击五子棋项目,打开所在文件夹。并复制粘贴过去。

 然后点击查看EasyX的帮助手册

 

 

 

 最后就加载好背景图片了。


2.画横线与竖线

Draw_line();//画线

void Draw_line()
{setlinecolor(BLACK);//画竖线for (int x = 20; x < 600; x += 40)line(x, 20, x, 580);//画横线for (int y = 20; y < 600; y += 40)line(20, y, 580, y);
}

 运行结果如下:


3. 画小黑点

Draw_point();//画点

找到函数fillcircle,有三个参数,圆心坐标(x,y),半径大小。

画点
void Draw_point()
{setfillcolor(BLACK); //把线的颜色弄成黑色fillcircle(140, 140, 5), //坐标+半径fillcircle(140, 460, 5);fillcircle(460, 140, 5);fillcircle(460, 460, 5);fillcircle(300, 300, 5);
}

 效果是这样的

 


4.获取鼠标消息

 找到ExMessage,这个东西是用来保存鼠标消息的,是一个结构体。

 

还有一个getmessage,用来获取鼠标消息。

 我们再写一个死循环,用来给鼠标一直下棋,直到有一方获胜。

while (1)
{m = getmessage(EX_MOUSE);if (m.message == WM_LBUTTONDOWN) //如果访问的是鼠标向下,那么就画一个棋子{//画一个棋子//未完...}}

 那么,鼠标可以获取消息了,那么怎么画棋子呢?


 5.画棋子

要解决的问题:

  • 如何先下黑棋,然后再下白棋呢?
  • 如何把棋子下到线与线交叉的位置?而不下到其它的位置呢?
  • 如何才能再下另一颗棋子时不覆盖先前下好的棋子呢?

  • 第一个问题:

定义一个bool类型,如果是黑棋就为真

bool black = true;//黑子先下
  •  第二个问题:

一开始,我们是用像素定义图像的大小,现在我们要把他换算为下标,即一个二维数组的下标,

定义一个全局的二维数组,int pieceArr[NUM][NUM] = { 0 };用来记录棋子的情况,0表示没有棋

子,1表示黑子,2表示白子。

void Draw_piece(bool black, int x, int y)
{//计算棋盘中的坐标int i = x / 40;int j = y / 40;if (black)//黑子{setfillcolor(BLACK);pieceArr[i][j] = 1; //黑棋为1}else //白子{setfillcolor(WHITE);pieceArr[i][j] = 2; //白棋为2}fillcircle(20 + i * 40, 20 + j * 40, 15); //画一个圆(x,y,半径)
}
  • 第三个问题:

定义一个好位置函数bool NicePos(int x, int y),如果这个位置是0,那么代表没有下过棋子,可以继续下,否则就不可以。

//判断这个位置是否有其他棋子
bool NicePos(int x, int y)
{//计算棋盘中的坐标int i = x / 40;int j = y / 40;return pieceArr[i][j] == 0;
}

6.如何判断比赛的输赢(核心)⭐

定义一个Gameover函数,int GameOver(int x, int y)

如果为0,游戏继续;

如果为1,黑棋赢;

如果为2,白棋赢;

 我们可以暴力地遍历整个二维数组,看有没有5个棋子是连在一起的,如果有,那么游戏结束。这样也行,但是时间会慢一些。

我们最优的解法是

只需要判断刚才下的棋子是否为5个即可
判断行,列,45度和135度斜线

定义一个n,用来保存棋子的颜色,如果为0则游戏继续。

定义一个计数器count,如果碰到一个棋子与自己一样,那么就++。

 我们需要判断四个方向,每个方向都要用一个for循环,如果与自己一样,那么计数器++,如果计数器大于等于5,那么就返回n。

//判断游戏胜利
int GameOver(int x, int y)
{x = x / 40;//换算为下标y = y / 40;//换算为下标int n = pieceArr[x][y];//得到棋子颜色if (n == 0)return 0;int count = 0;//统计棋子的数量int i, j; //当前棋子的前面或后面,或上面或下面,或斜向上或斜向下//同行的棋子for (i = x; i >= 0 && pieceArr[i][y] == n; i--)//同行的前面有没有相同的count++;for (i = x + 1; i < NUM && pieceArr[i][y] == n; i++)//同行的后面有没有相同的count++;if (count >= WIN_NUM)return n;//同列的棋子count = 0;//重新计算for (j = y; j >= 0 && pieceArr[x][j] == n; j--)//同列的上面有没有相同的count++;for (j = y + 1; j < NUM && pieceArr[x][j] == n; j++)count++;if (count >= WIN_NUM)return n;//45度的棋子count = 0;//重新计算for (i = x, j = y; i < NUM && j >= 0 && pieceArr[i][j] == n; i++, j--)//右上count++;for (i = x - 1, j = y + 1; i >= 0 && j < NUM && pieceArr[i][j] == n; i--, j++)//左下count++;if (count >= WIN_NUM)return n;//135度的棋子count = 0;for (i = x, j = y; i >= 0 && j >= 0 && pieceArr[i][j] == n; i--, j--)//左上count++;for (i = x + 1, j = y + 1; i < NUM && j < NUM && pieceArr[i][j] == n; i++, j++)//右下count++;if (count >= WIN_NUM)return n;return 0;
}

  • 换算下标:

对x,y分别对40做取模运算就可以转换为下标了。


 9.显示游戏结束的提示

 使用这些函数函数outtextxy,settextstyle,outtextxy,具体内容读者可以自己查看手册。

while (1)
{m = getmessage(EX_MOUSE);if (m.message == WM_LBUTTONDOWN){if (NicePos(m.x, m.y)){Draw_piece(black, m.x, m.y);int n = GameOver(m.x, m.y);if (n == 1)//黑子赢{settextcolor(RED);//字体颜色settextstyle(36, 0, _T("Consolas"));//字体样式outtextxy(250, 0, _T("黑棋赢了")); //输出文字内容break;}else if (n == 2)//白子赢{settextcolor(RED);settextstyle(36, 0, _T("Consolas"));outtextxy(250, 0, _T("白棋赢了"));break;}black = !black;}}
}

 五.完整代码🍗

#define _CRT_SECURE_NO_WARNINGS//这一句必须放在第一行
#include <graphics.h>		// 引用图形库头文件
#include <conio.h>
///*
//* * 15*15条边,(15条边中间14个格子+左留白0.5+右留白0.5),一共15个格子,一个格子像素为40
//* 则窗口的大小 15*40=600(x)  600(y)
//* //在第4,12线交界点需要画黑点
在第8线交界点需要画黑点
//* loadimage:用于从文件中读取图像。加载图片
//* putimage:显示图片
//* setlinecolor();
//* line:画线,需要两点坐标
//* setfillcolor:设置填充颜色
//* fillcircle:画填充(实心)圆,参数为坐标,半径
//* getmessage:获取鼠标消息
//* outtextxy:在指定位置(坐标)输出字符串
//* settextcolor:设置字体颜色
//* settextstyle:设置字体样式
//*
//*/
#define NUM 15
#define WIN_NUM 5//五子棋int pieceArr[NUM][NUM] = { 0 };//记录15*15个棋盘的棋子情况,0表示没有棋子,1表示黑子,2表示白子void Draw_line()
{setlinecolor(BLACK);//画竖线for (int x = 20; x < 600; x += 40)line(x, 20, x, 580);//画横线for (int y = 20; y < 600; y += 40)line(20, y, 580, y);
}//画点
void Draw_point()
{setfillcolor(BLACK);fillcircle(140, 140, 5),fillcircle(140, 460, 5);fillcircle(460, 140, 5);fillcircle(460, 460, 5);fillcircle(300, 300, 5);
}void Draw_piece(bool black, int x, int y)
{//计算棋盘中的坐标int i = x / 40;int j = y / 40;if (black)//黑子{setfillcolor(BLACK);pieceArr[i][j] = 1; //黑棋为1}else //白子{setfillcolor(WHITE);pieceArr[i][j] = 2; //白棋为2}fillcircle(20 + i * 40, 20 + j * 40, 15); //画一个圆(x,y,半径)
}//判断这个位置是否有其他棋子
bool NicePos(int x, int y)
{//计算棋盘中的坐标int i = x / 40;int j = y / 40;return pieceArr[i][j] == 0;
}//0:游戏继续,1:黑子赢; 2:白子赢
//只需要判断刚才下的棋子是否为5个即可
//判断行,列,45度和135度斜线//判断游戏胜利
int GameOver(int x, int y)
{x = x / 40;//换算为下标y = y / 40;//换算为下标int n = pieceArr[x][y];//得到棋子颜色if (n == 0)return 0;int count = 0;//统计棋子的数量int i, j; //当前棋子的前面或后面,或上面或下面,或斜向上或斜向下//同行的棋子for (i = x; i >= 0 && pieceArr[i][y] == n; i--)//同行的前面有没有相同的count++;for (i = x + 1; i < NUM && pieceArr[i][y] == n; i++)//同行的后面有没有相同的count++;if (count >= WIN_NUM)return n;//同列的棋子count = 0;//重新计算for (j = y; j >= 0 && pieceArr[x][j] == n; j--)//同列的上面有没有相同的count++;for (j = y + 1; j < NUM && pieceArr[x][j] == n; j++)count++;if (count >= WIN_NUM)return n;//45度的棋子count = 0;//重新计算for (i = x, j = y; i < NUM && j >= 0 && pieceArr[i][j] == n; i++, j--)//右上count++;for (i = x - 1, j = y + 1; i >= 0 && j < NUM && pieceArr[i][j] == n; i--, j++)//左下count++;if (count >= WIN_NUM)return n;//135度的棋子count = 0;for (i = x, j = y; i >= 0 && j >= 0 && pieceArr[i][j] == n; i--, j--)//左上count++;for (i = x + 1, j = y + 1; i < NUM && j < NUM && pieceArr[i][j] == n; i++, j++)//右下count++;if (count >= WIN_NUM)return n;return 0;
}int main()
{initgraph(600, 600);	// 创建绘图窗口,大小为 600x600 像素loadimage(NULL, _T("2.png")); //加载图片Draw_line();//画线Draw_point();//画点ExMessage m;//鼠标消息 ExMessage是一个结构体bool black = true;//黑子先下while (1){m = getmessage(EX_MOUSE);if (m.message == WM_LBUTTONDOWN){if (NicePos(m.x, m.y)){Draw_piece(black, m.x, m.y);int n = GameOver(m.x, m.y);if (n == 1)//黑子赢{settextcolor(RED);//字体颜色settextstyle(36, 0, _T("Consolas"));//字体样式outtextxy(250, 0, _T("黑棋赢了")); //输出文字内容break;}else if (n == 2)//白子赢{settextcolor(RED);settextstyle(36, 0, _T("Consolas"));outtextxy(250, 0, _T("白棋赢了"));break;}black = !black;}}}_getch();				// 按任意键继续closegraph();			// 关闭绘图窗口return 0;
}

 六.运行结果🍗


 七.学习时的代码🍗

观众老爷可以先把这一段代码拿去当模板,一点一点尝试去写,错了不要紧,代码就是一点一点改出来的,表示说一下子就可以写好。失败是成功之母,错误是正确他爹。慢慢来嘛。

#include <graphics.h>		// 引用图形库头文件
#include <conio.h>#define NUM 15
#define WIN_NUM 5//五子棋int pieceArr[NUM][NUM] = { 0 };//记录15*15个棋盘的棋子情况,0表示没有棋子,1表示黑子,2表示白子//画线
void Draw_line()//画点
void Draw_point()//判断这个位置是否有其他棋子
bool NicePos(int x, int y)//判断游戏胜利
int GameOver(int x, int y)int main()
{initgraph(600,600);	// 创建绘图窗口,大小为 640x480 像素// 读取图片至绘图窗口loadimage(NULL, _T("2.png"));//画线Draw_line();//画点Draw_point();//鼠标消息ExMessage m; //结构体m ,用与存放鼠标消息//黑子先下bool black = true;//黑子先下_getch();				// 按任意键继续closegraph();			// 关闭绘图窗口return 0;
}

创作不易, 如果这份博客👍对你有帮助,可以给博主一个免费的点赞以示鼓励。
欢迎各位帅哥美女点赞👍评论⭐收藏,谢谢!!!
如果有什么疑问或不同的见解,欢迎在评论区留言哦👀。
祝各位生活愉快⭐

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/192970.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【ERROR】ERR_PNPM_NO_IMPORTER_MANIFEST_FOUND No package.json

1、报错 启动项目的时候&#xff0c;报这个错误&#xff0c;是因为根目录错误&#xff0c;查看&#xff0c;根目录是否错误。

Bobo Python 学习笔记

安装 Bobo 可以通过通常的方式安装&#xff0c;包括使用setup.py install 命令。当然&#xff0c;您可以使用Easy Install、Buildout或pip。 安装bobo Collecting boboDownloading bobo-2.4.0.tar.gz (17 kB) Collecting WebObDownloading WebOb-1.8.7-py2.py3-none-any.whl…

Python爬取股票交易数据代码示例及可视化展示。

文章目录 前言一、开发环境二、第三方模块三、爬虫案例步骤四、爬虫程序全部代码1.分析网页2.导入模块3.请求数据4.解析数据5.翻页6.保存数据 五、实现效果六、数据可视化全部代码1.导入数据2.读取数据3.可视化图表4.效果展示关于Python技术储备一、Python所有方向的学习路线二…

创建一个前后端分离项目:Vue+SpringBoot

这是一个基于SpringBootVue3的前后端分离的项目&#xff0c;麻雀虽小&#xff0c;五脏俱全&#xff0c;开箱即用&#xff01; 这先粗略描述一下它的前后端。JNPF开发平台的前端采用的是Vue.js&#xff0c;这是一种流行的前端JavaScript框架&#xff0c;用于构建用户界面。 后端…

第三方软件测试服务有哪些形式?选择时如何避雷?

高新技术的快速发展&#xff0c;人们对于软件产品越来越依赖&#xff0c;因此软件质量对于软件企业来说至关重要。产品质量的好坏需要通过检测才得知&#xff0c;软件企业为了获得更客观公正的检验结果&#xff0c;会将软件测试交由第三方软件测试服务机构进行?那么有哪些形式…

【milkv】0、duo编译环境搭建

一、开发资料整理 Docker https://hub.docker.com/repository/docker/dreamcmi/cv1800-docker/general GitHub https://github.com/milkv-duo/duo-buildroot-sdk CV181x/CV180x MMF SDK 开发文档汇总 https://developer.sophgo.com/thread/471.html cv181x芯片使用的交叉…

盘点72个ASP.NET Core源码Net爱好者不容错过

盘点72个ASP.NET Core源码Net爱好者不容错过 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 链接&#xff1a;https://pan.baidu.com/s/1nlQLLly_TqGrs5O8eOmZjA?pwd8888 提取码&#xff1a;8888 项目名称 (Chinese) 物业收费…

【git】解决git报错:ssh:connect to host github.com port 22: Connection timed out 亲测有效

如题&#xff0c;git使用中突然报错 ssh:connect to host github.com port 22: Connection timed out 通过查阅各种资料&#xff0c;得知原因可能是由于电脑的防火墙或者其他网络原因导致ssh连接方式 端口22被封锁。 解决方法 一&#xff1a;抛弃ssh连接方式&#xff0c;使…

图解系列--密码

1.概念 _1.对称密码与公钥密码 对称密码是指在加密和解密时使用同一密钥的方式。 公钥密码则是指在加密和解密时使用不同密钥的方式。因此&#xff0c;公钥密码又称为非对称密码。 _2.混合密码系统 对称密码和公钥密码结合起来的密码方式 _3.散列值 散列值就是用单向散列函数计…

使用c++程序,实现图像平移变换,图像缩放、图像裁剪、图像对角线镜像以及图像的旋转

数字图像处理–实验三A图像的基本变换 实验内容 A实验&#xff1a; &#xff08;1&#xff09;使用VC设计程序&#xff1a;实现图像平移变换&#xff0c;图像缩放、图像裁剪、图像对角线镜像。 &#xff08;2&#xff09;使用VC设计程序&#xff1a;对一幅高度与宽度均相等的…

LOWORD, HIWORD, LOBYTE, HIBYTE的解释

文章目录 实验结论 实验 int 类型大小正常为4Byte 以小端序来看 0x12345678在内存中的存储为 0x78 0x56 0x34 0x120x78在低地址&#xff0c;0x12在高地址 程序输出 #include <stdio.h> #include <string.h> #include<windows.h>int main() {int a 0x12345…

创信短信API的无代码开发集成:电商平台、CRM和用户运营

无代码开发&#xff1a;集简云与创信短信API的连接 创信短信API的无代码开发集成&#xff0c;旨在为电商平台、CRM和用户运营提供便利。作为一款超级软件连接器&#xff0c;集简云可以在无需开发&#xff0c;无需代码知识的情况下&#xff0c;轻松连接创信短信与近千款软件系统…

​Unity Vuforia 新手(图片识别)教程,后续整理 实体识别 详细流程

文章目录 前言一、Vuforia是什么&#xff1f;二、Unity导入Vuforia1.去Unity - Windows – Asset Store&#xff0c;搜vuforia engine&#xff0c;添加到我的资源2.打开package Manager&#xff0c;导入到工程中即可3.或者在vuforia engine官网下载的Unity包导入4.检查是否导入…

Git相关: 拉取、git push提交 过程遇到的错误

目录 解决git push报错error: RPC failed; HTTP 413 curl 22 关于这个问题&#xff0c;其实千万别用gitlab,因为你怎么推送 也不可能把几G的文件推上去。 error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 413 se 解决git push报错error: RPC failed;…

夯实c语言基础

题干以下关于函数的叙述中正确的是&#xff08;  d &#xff09;。   A.函数调用必须传递实参   B.函数必须要有形參   C.函数必须要有返回值   D.函数形参的类型与返回值的类型无关 题干以下程序实现&#xff0c;打印任意奇数行菱形星塔&#xff0c;请填空。 void…

Python交易-通过Financial Modeling Prep (FMP)选择行业

介绍 在您的交易旅程中,无论您是在寻找理想的股票、板块还是指标,做出明智的决策对于您的成功至关重要。然而,收集和分析所需的大量数据可能相当艰巨。财务建模准备 (FMP) API的

vue3实现数据大屏内数据向上滚动,鼠标进入停止滚动 vue3+Vue3SeamlessScroll

1.效果图 2.npm下载依赖及main.js文件配置 npm install vue3-seamless-scroll --saveimport vue3SeamlessScroll from vue3-seamless-scroll;app.use(vue3SeamlessScroll) 3.html代码 <!-- scrollFlag为true时再渲染,vue3只要涉及到传值子页面需要加flag判断&#xff0c;否…

竞赛选题 深度学习疲劳检测 驾驶行为检测 - python opencv cnn

文章目录 0 前言1 课题背景2 相关技术2.1 Dlib人脸识别库2.2 疲劳检测算法2.3 YOLOV5算法 3 效果展示3.1 眨眼3.2 打哈欠3.3 使用手机检测3.4 抽烟检测3.5 喝水检测 4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习加…

服务器常见问题排查(一)—cpu占用高、上下文频繁切换、频繁GC

一般而言cpu异常往往还是比较好定位的。原因包括业务逻辑问题(死循环)、频繁gc以及上下文切换过多。而最常见的往往是业务逻辑(或者框架逻辑)导致的&#xff0c;可以使用jstack来分析对应的堆栈情况。 使用jstack排查占用率问题 当使用jstack排查占用率问题时&#xff0c;可以…