C语言实现三子棋游戏(可以改变为四子棋或者多子棋版)

目录

游戏介绍

游戏框架

游戏基本逻辑的介绍

游戏具体功能实现

初始化棋盘

打印棋盘

玩家下棋

电脑下棋

判断输赢

行和列:

对角线:

平局:

游戏继续:

游戏完整代码

test.c

game.c

game.h


游戏介绍

三子棋游戏或者说是井字棋游戏,相信大家都玩过,一般的流程就是在一个棋盘上,玩家下棋之后,电脑下棋,然后判断输赢,如果没输没赢,就再玩家下棋,电脑下棋。

游戏框架

对于这个小游戏来说,代码量还算少量,所以我们可以分为三个文件来写,养成好习惯,方便以后在公司好合作,所以我们就 test.c   game.c   game.h 三个文件:

test.c:用来写游戏的基本逻辑,包含打印菜单,游戏逻辑的展现。

game.c:最核心的代码部分,用来写游戏逻辑的实现,这部分一般不给别人看。

game.h:包含代码需要的头文件,函数定义,常量等。

游戏基本逻辑的介绍

我们首先要给玩家一个菜单,玩家才能选择是否开始游戏。我们需要上来就打印菜单,玩家再选择,所以我们使用do while 循环,在这个循环里需要一个选择语句,所以基本逻辑就是这样:

菜单:

这里玩家输入1 或者 0 ,就很妙,while循环()里放 input,输入1 就又开始循环,输出菜单,输入0 就结束循环了,退出游戏。

游戏具体功能实现

初始化棋盘

我们发现棋盘有行和列,这与我们的二维数组很相符,所以我们就定义一个二维数组来当棋盘

记住这个定义常量,这样我们就可以很方便的改变成多子棋之类的。

初始化棋盘只需要把二维数组里全部设为空格就行。

打印棋盘

我们的棋盘长什么样的:

所以我们需要打印这些分隔符。

玩家下棋

需要注意的点是:

1. 我们数组的下标是从0开始的,但是玩家下棋的话,他可能不知道下标从0开始,所以我们就需要自己操作一下。

2. 玩家下棋的坐标必须在棋盘内才能下,并且下的坐标必须没有棋子才行,所以需要判断。

电脑下棋

我们的电脑随机下棋,所以用rand 和 srand 函数。

判断输赢

判断输赢是这里比较复杂的地方,我们游戏有四种状态:1.玩家赢游戏结束 2.电脑赢游戏结束 3.游戏平局游戏结束 4. 游戏继续。 我们每次玩家下棋和电脑下棋都需要判断输赢,所以我们的函数返回:

行和列:

我们的输赢就是一行或者一列一样的就是谁赢了,有一行,一列的判断。例如:在一行中判断,要相互两个之间是一样的并且不是空格,那么flag就加一,只要flag 等于col -1 就说明赢了。

对角线:

除了行和列,我们还有对角线的判断:

看图我们就可以寻找到两条对角线的规律,依次写我们的代码。

平局:

我们遍历数组的所有元素如果有一个空格就不会平局,当一个也没有了就平局。

游戏继续:

如果以上都不是,就直接游戏继续。

特别提示:我们四种情况的返回字符也非常巧妙,当我们玩家赢和电脑赢的时返回的是他们下的棋子,这样我们就可以减少一些代码量了,不用单独判断一行或者一列是谁赢了。

游戏完整代码

test.c

#include"game.h"void meun()
{printf("********************\n");printf("****   1.  play  ***\n");printf("****   0.  exit  ***\n");printf("********************\n");
}void play()
{char ret = 0;//判断输赢的字符char board[ROW][COL];//初始化棋盘InitBoard(board, ROW, COL);//打印棋盘DisplayBoard(board, ROW, COL);while (1){//玩家下棋PlayerMove(board, ROW, COL);system("cls");//清空屏幕DisplayBoard(board, ROW, COL);ret = IsWin(board, ROW, COL);if (ret != 'A'){break;}//电脑下棋ComputerMove(board, ROW, COL);system("cls");printf("电脑下完棋了,该你了\n");DisplayBoard(board, ROW, COL);ret = IsWin(board, ROW, COL);if (ret != 'A'){break;}}if (ret == '*'){printf("玩家获胜\n");}else if (ret == '#'){printf("电脑获胜\n");}else{printf("平局\n");}
}int main()
{int input = 0;srand((unsigned int)time(NULL));do{meun();printf("请输入:");scanf("%d", &input);switch (input){case 1:play();break;case 0:printf("退出游戏\n");break;default:printf("输入错误,请重新输入\n");break;}} while (input);
}

game.c

#include"game.h"void InitBoard(char board[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){board[i][j] = ' ';}}
}void DisplayBoard(char board[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){//打印数据printf(" %c ", board[i][j]);if (j < col - 1){printf("|");}}printf("\n");//打印分隔符if (i < row - 1){for (int h = 0; h < col; h++){printf("---");if (h < col - 1){printf("|");}}}printf("\n");}
}void PlayerMove(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;while (1){printf("玩家输入坐标:");scanf("%d %d", &x, &y);if (x > 0 && x <= row && y > 0 && y <= col){if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}else{printf("这个位置已被下了,重新输入\n");}}else{printf("坐标非法,请重新输入\n");}}
}void ComputerMove(char board[ROW][COL], int row, int col)
{//随机下棋while (1){int x = rand() % row;int y = rand() % col;if (board[x][y] == ' '){board[x][y] = '#';break;}}
}//对角线1
int Catercorner_diagonal_1(char board[ROW][COL], int row, int col)
{int flag = 0;for (int i = 0; i < row - 1; i++){if (board[i][i] == board[i + 1][i + 1] && board[i][i] != ' '){flag++;}}return flag;
}
//对角线2
int Catercorner_diagonal_2(char board[ROW][COL], int row, int col)
{int flag = 0;for (int i = 0; i < row - 1; i++){int j = col - 1;if (board[i][j] == board[i + 1][j - 1] && board[i][j] != ' '){flag++;}j--;}return flag;
}static int IsFull(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] == ' ')return 0;}}return 1;
}char IsWin(char board[ROW][COL], int row, int col)
{//判断行for (int i = 0; i < row ; i++){int j = 0;int flag = 0;//计算一行是否一样的标志for (j = 0; j < col - 1; j++){if (board[i][j] == board[i][j + 1]  && board[i][j] != ' '){flag++;}}if (flag == col - 1){return board[i][j];}}//判断列for (int j = 0; j < col; j++){int i = 0;int flag = 0;//计算一列是否一样的标志for (i = 0; i < row - 1; i++){if (board[i][j] == board[i + 1][j] && board[i][j] != ' '){flag++;}}if (flag == row - 1){return board[i][j];}}//判断对角线if (Catercorner_diagonal_1(board, ROW, COL) == row - 1){return board[0][0];}if (Catercorner_diagonal_2(board, ROW, COL) == row - 1){return board[0][col];}//判断平局if (IsFull(board, row, col)){return 'Q';}return 'A';
}

game.h

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<Windows.h>#define COL 3 //列
#define ROW 3 //行//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);//判断输赢
char IsWin(char board[ROW][COL], int row, int col);
//玩家赢 返回*
//电脑赢 返回#
//平局  返回Q
//游戏继续 返回A

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

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

相关文章

浏览器不兼容的问题和通用解决方案

大家好&#xff0c;我是咕噜铁蛋&#xff0c;今天我想和大家聊聊一个在我们日常上网过程中经常遇到的问题——浏览器不兼容。这个问题看似微小&#xff0c;但却常常让我们在浏览网页、使用在线应用时感到困扰。接下来&#xff0c;我将详细分析浏览器不兼容的原因&#xff0c;并…

[lesson48]同名覆盖引发的问题

同名覆盖引发的问题 父子间的赋值兼容 子类对象可以当做父类对象使用(兼容性) 子类对象可以直接赋值给父类对象(<font color>兼容性)子类对象可以直接初始化父类对象父类指针可以直接指向子类对象父类引用可以直接引用子类对象 当使用父类指针(引用)指向子类对象时 子类…

30 消息队列

原理 操作系统可以通过页表映射在共享区创建一块共享内存&#xff0c;也可以申请一个队列。A进程和B进程可以向这个队列发送数据块&#xff0c;两个进程接收数据块来通信 函数 申请数据块 参数中的key来自于ftok函数 删除消息队列 同样消息队列也有数据结构管理&#xff…

数值分析复习:Richardson外推和Romberg算法

文章目录 Richardson外推Romberg&#xff08;龙贝格&#xff09;算法 本篇文章适合个人复习翻阅&#xff0c;不建议新手入门使用 本专栏&#xff1a;数值分析复习 的前置知识主要有&#xff1a;数学分析、高等代数、泛函分析 本节继续考虑数值积分问题 Richardson外推 命题&a…

解决在linux中执行tailscale up却不弹出验证网址【Tailscale】【Linux】

文章目录 问题解决提醒 问题 最近有远程办公需求&#xff0c;需要连接内网服务器&#xff0c;又不太想用todesk&#xff0c;于是找到一个安全免费可用的Tailscale Best VPN Service for Secure Networks&#xff0c;在windows中顺利注册账号后&#xff0c;登陆了我的windows …

上位机图像处理和嵌入式模块部署(树莓派4b进行驱动的编写)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 树莓派4b上面还支持驱动代码的编写&#xff0c;这是我没有想到的。这里驱动&#xff0c;更多的是一种框架的编写&#xff0c;不一定是编写真正的驱…

20240422,C++文件操作

停电一天之后&#xff0c;今天还有什么理由不学习呜呜……还是没怎么学习 一&#xff0c;文件操作 文件操作可以将数据持久化&#xff0c;对文件操作时须包含头文件<fstream> 两种文件类型&#xff1a;文本文件&#xff1a;文件以文本的ASCII码形式存储&#xff1b;二进…

【Vue3】$subscribe订阅与反应

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

超越OpenAI,谷歌重磅发布从大模型蒸馏的编码器Gecko

引言&#xff1a;介绍文本嵌入模型的重要性和挑战 文本嵌入模型在自然语言处理&#xff08;NLP&#xff09;领域扮演着至关重要的角色。它们将文本转换为密集的向量表示&#xff0c;使得语义相似的文本在嵌入空间中彼此靠近。这些嵌入被广泛应用于各种下游任务&#xff0c;包括…

VideoComposer: Compositional Video Synthesis with Motion Controllability

decompose videos into three distinct types of conditions: textual conditions, spatial conditions, temperal conditions 条件的内容&#xff1a; a. textual condition: coarse grained visual content and motions, 使用openclip vit-H/14的text encoder b. spatial co…

Splashtop 将在 NAB 展会上推出音视频剪辑增强功能

加利福尼亚州拉斯维加斯 Splashtop 在简化随处办公远程解决方案领域处于领先地位&#xff0c;在今年举行的 NAB 展会上将推出 Enterprise 解决方案的高级性能功能&#xff0c;均面向广播和媒体工作者而设计。 Splashtop Enterprise 经过优化&#xff0c;可为执行视频剪辑、唇…

Excel文件解析--超大Excel文件读写

使用POI写入 当我们想在Excel文件中写入100w条数据时&#xff0c;我们用普通的XSSFWorkbook对象写入时会发现&#xff0c;只有在将100w条数据全部加载入内存后才会用write()方法统一写入&#xff0c;这样效率很低&#xff0c;所以我们引入了SXSSFWorkbook进行超大Excel文件的读…

java开发之路——node.js安装

1. 安装node.js 最新Node.js安装详细教程及node.js配置 (1)默认的全局的安装路径和缓存路径 npm安装模块或库(可以统称为包)常用的两种命令形式&#xff1a; 本地安装(local)&#xff1a;npm install 名称全局安装(global)&#xff1a;npm install 名称 -g本地安装和全局安装…

【Leetcode】string类刷题

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;Leetcode刷题 目录 1.仅反转字母2.字符串中第一个唯一字符3.验证回文串4.字符串相加5.反转字符串I I6.反转字符串中的单词III7.字符串相乘8.把字符串转换为整数 1.仅反转字母 题目链接&#xff1a;…

一篇文章带您了解面向对象(java)

1.简单理解面向过程编程和面向对象编程 面向过程编程&#xff1a;开发一个一个的方法&#xff0c;有数据需要处理&#xff0c;我们就可以调用方法来处理。 package com.web.quictstart;public class demo1 {public static void main(String[] args) {totalScore("张三&q…

mac上VMware fusion net模式无法正常使用的问题

更新时间&#xff1a;2024年04月22日21:39:04 1. 问题 环境&#xff1a; intel芯片的macbook pro VMware fusion 13.5.1 无法将“Ethernet0”连接到虚拟网络“/dev/vmnet8”。在这里显示这个之后&#xff0c;应该是vmnet8的网段发生了冲突&#xff0c;所以导致无法正常使用…

前端开发攻略---拖动归类,将元素拖拽到相应位置

1、演示 2、代码 <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport" content"widthdevice-…

2024年Q1季度平板电视行业线上市场销售数据分析

Q1季度平板电视线上市场表现不如预期。 根据鲸参谋数据显示&#xff0c;2024年1月至3月线上电商平台&#xff08;京东天猫淘宝&#xff09;平板电视累计销量约360万件&#xff0c;环比下降12%&#xff0c;同比下降30%&#xff1b;累计销售额约99亿元&#xff0c;环比下降28%&a…

学习STM32第十七天

备份域详解 一、简介 在参考手册的电源控制章节&#xff0c;提到了备份域&#xff0c;BKPR是在RTC外设中用到&#xff0c;包含20个备份数据寄存器&#xff08;80字节&#xff09;&#xff0c;备份域包括4KB的备份SRAM&#xff0c;以32位、16位或8位模式寻址&#xff0c;在VBAT…

C++初阶学习第二弹——C++入门(下)

C入门&#xff08;上&#xff09;&#xff1a;C初阶学习第一弹——C入门&#xff08;上&#xff09;-CSDN博客 目录 一、引用 1.1 引用的实质 1.2 引用的用法 二、函数重载 三、内敛函数 四、auto关键字 五、总结 前言&#xff1a; 在上面一章我们已经讲解了C的一些基本…