C语言入门级小游戏——三子棋

news/2024/11/24 2:05:49/

文章目录

  • 游戏文件的创建
  • 游戏菜单
  • 重头戏,游戏正式开始
    • 棋盘的创建
      • 数据清空
      • 打印棋盘
    • 玩家下棋
    • 电脑下棋
    • 输赢的判断
      • 1.赢
      • 2.平局,游戏继续
  • 代码展示

今天我们写一个小游戏——三子棋来增加我们对编程的兴趣,
希望这篇文章对友友们有帮助!在这里插入图片描述

游戏文件的创建

这里我们需要是三个文件
test.c —— 游戏的测试
game.h —— 游戏函数的声明
game.c —— 游戏函数的实现

游戏菜单

游戏菜单,就像名字一样,是为了方便我们对游戏进行选择。
这里我们创建一个 函数menu 来引导我们开始游戏。
menu函数的功能
1.游戏的开始
2.游戏的退出
3.当选择错误时,重新选择

void menu()
{//目录printf("*******************************\n");printf("************* 1.play **********\n");printf("************* 0.exit **********\n");printf("*******************************\n");
}

重头戏,游戏正式开始

棋盘的创建

数据清空

1.游戏在运行的过程中需要存储数据,因此我们可以创建3*3的二维数组
数组a[3][3]来存储数据。
2.这个棋盘刚打印出来的时候什么都没有,因此没下棋之前数组中存放空格。
这里我们创建一个 Initboard 函数 来把空格放到我们的数组中去。在这里插入图片描述

`//初始化棋盘为空格
void Initboard(char a[m][n], int X, int Y)
{int i = 0;int j = 0;for (i = 0; i < X; i++){for (j = 0; j < Y; j++){a[i][j] = ' ';}}
}

`

打印棋盘

然后我们需要把棋盘给打印出来,给玩家进一步游戏。
这里我们创建一个 Displayboad****函数 把我们的棋盘打印出来。

 void Displayboad(char a[m][n], int X, int Y)
{int i = 0;int j = 0;for (i = 0; i < X; i++){ //打印数据for (j = 0; j < Y; j++){printf(" %c ", a[i][j]);if (j < Y-1)printf("|");}printf("\n");//打印分割线if (i < X-1)printf("-----------\n");}
}

在这里插入图片描述
注:如果未来我们的数组要变成 55,88 的呢,我们发现代码到处都要改,因此我们发现
这里我们可以定义宏,在头文件game.h 中进行宏定义。行用 m 表示,列用 n 表示
在这里插入图片描述

玩家下棋

玩家下棋时我们需要注意:
1.玩家的落子位置-1是我们数组的下标。
2.判读玩家输入的位置是否已有落子。
3.判断玩家输入的位置是否正确。
这里我们创建一个Playermove*函数来实现我们的玩家下棋
在这里插入图片描述

  void Playermove(char a[m][n], int X, int Y){int i = 0;int j = 0;printf("玩家下棋>\n");printf("请输入下棋坐标,中间使用空格>\n");while (1){scanf("%d %d", &i, &j);if (i > 0 && i <= X   && j>0 && j <=Y){if (a[i - 1][j - 1] == ' '){a[i-1][j-1] = '*';break;}elseprintf("坐标被占用,不能落子,请重新输入\n");}else{printf("输入错误,请重新输入\n");}}}

在这里插入图片描述

电脑下棋

想要完成电脑下棋,我们需要生成随机数。
生成随机数我们需要调用 rand() 函数,而使用rand函数我们又要调用函数 srand((unsignedint)time(NULL)) 这个函数只需要调用一次,我们可以把他放到主函数中
这里我们需要调用这两个头文件
1.<stdlib.h>
2.<time.h>

电脑下棋时需要注意:
1.生成的随机数小于m,n
i = rand() % X;
j = rand() % Y;

2.判断电脑下的位置是否为空
这里我们创建一个Computermovie
函数
来实现我们的玩家下棋
在这里插入图片描述

 void Computermovie(char a[m][n], int X, int  Y){int i = 0;int j = 0;printf("电脑下棋\n");while (1){i = rand() % X;j = rand() % Y;if (a[i][j] == ' '){a[i][j] = '#';break;}}}int Isfull(char a[m][n], int X, int Y){int i = 0;int j = 0;for (i = 0; i < X; i++){for (j = 0; j < Y; j++){if (a[i][j] != ' ')return  1;}}return 0;}

在这里插入图片描述

输赢的判断

在我们下棋过程中,每下一次棋我们都要进行输赢的判断。
判断要返回四种不同的状态
玩家赢 --> ’ * ’
电脑赢 --> ‘#’
平局 --> ‘Q’
游戏继续 --> ‘C’
这里我们创建一个Iswin函数来实现我们的输赢判断
因为每下一次棋我们就要进行输赢的判断,所以函数的位置如下
在这里插入图片描述
在这里插入图片描述
在输赢判断的时候可能出现以下三种情况

1.赢

在赢的时候我们需要注意
1.判断行
2.判断列
3.判断对角线

char  Iswin(char a[m][n], int X, int  Y){int i = 0;for (i = 0; i < X; i++){if (a[i][0] == a[i][1] && a[i][1] == a[i][2] && a[i][1]!=' ')return a[i][0];}for (i = 0; i < X; i++){if (a[0][i] == a[1][i] && a[1][i] == a[2][i] && a[2][i] != ' ')return a[1][i];}if (a[0][0] == a[1][1] && a[1][1] == a[2][2] && a[2][2] != ' ')return a[0][0];if (a[0][2] == a[1][1] && a[1][1] == a[2][0] && a[1][1] != ' ')return a[1][1];
}

2.平局,游戏继续

平局判断的时候我们创建一个函数Isfull,
如果棋盘满了,又没有分出输赢,则为平局
如果棋盘没满,又没有分出输赢,则继续游戏

int Isfull(char a[m][n], int X, int Y){int i = 0;int j = 0;for (i = 0; i < X; i++){for (j = 0; j < Y; j++){if (a[i][j] == ' ')return  0}}return 1;}

注:函数返回1,则为平局,向game函数返回Q
函数返回0,则继续游戏,向game函数返回C在这里插入图片描述

 if (Isfull(a, m,n ) == 1){return 'Q';}elsereturn 'C';

代码展示

game.h —— 游戏函数的声明

#define  _CRT_SECURE_NO_WARNINGS
#define m 3
#define n 3
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void Initboard(char a[m][n], int X, int Y);
void Displayboad(char a[m][n], int X, int Y);
void Playermove(char a[m][n], int X, int Y);
void Computermovie(char a[m][n], int X, int  Y);

game.c —— 游戏函数的实现

#define  _CRT_SECURE_NO_WARNINGS
#include"game.h"
//数据清空
void Initboard(char a[m][n], int X, int Y)
{int i = 0;int j = 0;for (i = 0; i < X; i++){for (j = 0; j < Y; j++){a[i][j] = ' ';}}
}
//打印棋盘void Displayboad(char a[m][n], int X, int Y)
{int i = 0;int j = 0;for (i = 0; i < X; i++){ //打印数据for (j = 0; j < Y; j++){printf(" %c ", a[i][j]);if (j < Y-1)printf("|");}printf("\n");//打印分割线if (i < X-1)printf("-----------\n");}
}//玩家下棋void Playermove(char a[m][n], int X, int Y){int i = 0;int j = 0;printf("玩家下棋>\n");printf("请输入下棋坐标,中间使用空格>\n");while (1){scanf("%d %d", &i, &j);if (i > 0 && i <= X   && j>0 && j <=Y){if (a[i - 1][j - 1] == ' '){a[i-1][j-1] = '*';break;}elseprintf("坐标被占用,不能落子,请重新输入\n");}else{printf("输入错误,请重新输入\n");}}}//电脑下棋void Computermovie(char a[m][n], int X, int  Y){int i = 0;int j = 0;printf("电脑下棋\n");while (1){i = rand() % X;j = rand() % Y;if (a[i][j] == ' '){a[i][j] = '#';break;}}}//平局判断函数int Isfull(char a[m][n], int X, int Y){int i = 0;int j = 0;for (i = 0; i < X; i++){for (j = 0; j < Y; j++){if (a[i][j] == ' ')return  0;}}return 1;}char  Iswin(char a[m][n], int X, int  Y){//赢int i = 0;for (i = 0; i < X; i++){if (a[i][0] == a[i][1] && a[i][1] == a[i][2] && a[i][1]!=' ')return a[i][0];}for (i = 0; i < X; i++){if (a[0][i] == a[1][i] && a[1][i] == a[2][i] && a[2][i] != ' ')return a[1][i];}if (a[0][0] == a[1][1] && a[1][1] == a[2][2] && a[2][2] != ' ')return a[0][0];if (a[0][2] == a[1][1] && a[1][1] == a[2][0] && a[1][1] != ' ')return a[1][1];//平局判断if (Isfull(a, m,n ) == 1){return 'Q';}else//继续游戏return 'C';

game.c —— 游戏函数的实现

#define  _CRT_SECURE_NO_WARNINGS
#include"game.h"
void menu()
{//目录printf("*******************************\n");printf("************* 1.play **********\n");printf("************* 0.exit **********\n");printf("*******************************\n");
}void game()
{char k = 0;char a[m][n] = { 0 };Initboard(a, m, n);Displayboad(`c
a, m, n);while (1){//玩家下棋Playermove(a, m,n);//打印棋盘Displayboad(a, m,n);//判断输赢k=Iswin(a,m,n);if (k == '*'){printf("玩家赢\n");break;}//电脑下棋Computermovie(a,m,n);//打印棋盘Displayboad(a,m,n);//判断输赢k = Iswin(a, m, n);if (k == '*'){printf("玩家赢\n");break;}if (k == '#'){printf("电脑赢\n");break;}if (k == 'Q'){printf("平局\n");break;}if (k == 'C')printf("继续游戏\n");}}
int main()
{int input = 0;srand((unsigned int)time(NULL));;menu();do{printf("请选择:>");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏");break;default:printf("选择错误,请重新选择");break;}} while (1);return 0;
}

在这里插入图片描述


http://www.ppmy.cn/news/76859.html

相关文章

聚焦金融行业网络安全|安全狗亮相知虎科技生态大会

5月18日&#xff0c;知虎科技生态大会在上海顺利举办。作为国内云原生安全领导厂商&#xff0c;安全狗也受邀出席此次活动。 据悉&#xff0c;此次大会邀请了来自国内顶级安全厂商的安全专家介绍从网络安全、应用安全、业务安全、数据安全、资金安全、通信安全等六个方面全方位…

C++继承技术

方法覆盖 virtual关键字 只有在基类中声明为 virtual 的方法才能被派生类正确覆盖。关键字位于方法声明的开头&#xff0c;如下面的 Base 的修改版本所示&#xff1a; class Base {public:virtual void someMethod() {}protected:int m_protectedInt { 0 };private:int m_pr…

BigDecimal加减乘除计算

1、BigDecimal概述 Java在java.math包中提供的API类BigDecimal&#xff0c;用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数&#xff0c;但在实际应用中&#xff0c;可能需要对更大或者更小的数进行运算和处理。一般情况下&#xff0c;对于…

[Tool]ansible与playbook简介

文章目录 ansible安装配置ansible.cfg 命令与模块相关模块setup模块 playbookFacts基本语法变量变量作用域逻辑控制语句重用标签lookup访问数据过滤器filter条件测试 lineinfile模块role ansible是基于Python开发的自动化运维工具&#xff0c;集合了众多运维工具&#xff08;pu…

Linkerd部署模式

per-host linkerd作为独立进程运行在每台机器(物理机/虚拟机)上,服务所有运行在该机器的服务实例。 各个服务产生的流量都需要经过Linkerd,然后转发到目标服务 sidecar linkerd和服务部署在一起,每个服务配套自己的linkerd 一台机器上可能同时存在多个linkerd进程 per…

CISC和RISC的比较

指令系统的发展朝向两种截然不同的方向&#xff0c;一种是增强原有指令的功能&#xff0c;设置更为复杂的新指令实现软件功能的硬化&#xff0c;这类机器称为复杂指令系统计算机(CISC),典型的有采用X86架构的计算机&#xff1b;另一种是减少指令种类和简化指令功能&#xff0c;…

设计模式初探----单例模式

概述 单例模式&#xff1a;保证类的实例化对象仅有一个&#xff0c;并提供一个访问他的全局访问点 应用场景 表示文件系统的类&#xff0c;一个操作系统一定是只有一个文件系统&#xff0c;因此文件系统的类的实例有且仅有一个。打印机打印程序的实例&#xff0c;一台计算机…

【微博-自定义Cell-创建子控件 Objective-C语言】

一、自定义Cell 1.既然我们要自定义Cell,这个自定义Cell,属于MVC哪个部分, 这个Cell类,属于MVC哪个部分, Model、Controller、还是View, View吧, 所以说,应该在这里去新建一个类, 在这里去新建一个类,右键,New File,