C语言:三子棋小游戏

简介:

目标很简单:实现一个 三子棋小游戏。三子棋大家都玩过,规则就不提及了。本博文中实现的三子棋在对局中,电脑落子是随机的,不具有智能性,玩家的落子位置使用键盘输入坐标。下面开始详细介绍如何实现一个简单的三子棋游戏。

步骤一:制定框架

想要实现一个小游戏,第一件事就是制定框架,那么制定框架是什么意思?怎么制定框架?

#include"chess.h"
int main()
{
	int n = 0;
	do
	{
		menu();
		printf("input:\n");
		scanf("%d", &n);
		switch(n)
		{
		case 1:
			game();
			break;
		case 0:
			printf("exit\n");
			break;
		default:
			printf("input error,input again:\n");
			break;
		}
	} while(n);
	return 0;
}

这里的menu函数只是一个打印函数,定义如下:

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

将main函数写全就是制定了一个完整的框架,只要我们输入1,就会进入game函数(之后实现)进行游戏,输入0就会退出游戏,结束程序,输入其他数会让我们重新输入。整个过程就是这么简单。我们只需要实现了game的过程,整个游戏就制作完成了。

那么game函数怎么实现呢?

步骤二:实现game函数

 我们在做一个项目的时候,需要把函数的声明放在头文件里,函数的定义放在源文件里,但是具体情况可以根据个人偏好来,我个人是喜欢把主函数里会用到的函数声明放进头文件里,定义放在源文件里。如果在函数的定义中需要实现另外一个函数,就在另外一个函数的声明和定义就都放在源文件里。

要实现game函数,我们需要先将game的流程想清楚:

我们默认玩家先下棋,玩家输入一个合法坐标,然后电脑在下棋。并且每当玩家或者电脑下棋之后需要判断对局是否结束,如果结束,那么最后落子的一方胜利。另外,在玩家或者电脑下棋之后我们需要将棋盘和棋子打印出来。

void game()
{
	char pieces[ROW][COL] = { 0 };
	piecesInit(pieces, ROW, COL);
	board(pieces, ROW, COL);
	while (1)
	{
		system("cls");
		board(pieces, ROW, COL);
		printf("player move!\n");
		playerMove(pieces, ROW, COL);
		system("cls");
		board(pieces,ROW,COL);
		if (judge(pieces, ROW, COL))
		{
			printf("you win\n");
			break;
		}
		printf("computer move!\n");
		computerMove(pieces, ROW, COL);
		Sleep(1000);
		system("cls");
		board(pieces, ROW, COL);
		if (judge(pieces, ROW, COL))
		{
			printf("you lose\n");
			break;
		}
	}
}

pieces二维数组是用来储存棋子位置信息的,玩家的棋子是星号,电脑的棋子是井号

下面对game函数中用到的函数进行解释:

piecesInit:将pieces初始化,使得每一个元素都是空格,这样初始状态就不会打印出棋子

board:传入pieces数组,将棋盘和棋子一并打印

playerMove:玩家下棋,将pieces中的一个空格元素变为星号

computerMoe:电脑下棋,将pieces中的一个空格元素变为井号

judge:返回值是int,如果对局结束了就返回1,未结束返回0

这样整个game的流程就形成了

步骤三:实现game函数中的各个函数

void board(char pieces[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		printf(" %c | %c | %c \n",pieces[i][0],pieces[i][1],pieces[i][2]);
		if (i < row - 1)
		{
			printf("---|---|---\n");
		}
	}
}//如果不理解,可以在自己的电脑上把棋盘敲出来,就会明白board函数的原理,不敲出来不可能搞明白
void playerMove(char pieces[ROW][COL],int row,int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("x:\n");
		scanf("%d", &x);
		printf("y:\n");
		scanf("%d", &y);
		x--;//用户输入的起始位置是1,而数组下标起始位置是0
		y--;
		if (x < 0 || x>2 || y < 0 || y>2 || pieces[x][y] != ' ')//判断是否非法
			printf("error,again\n");
		else
		break;//正确输入,退出循环
	}
	pieces[x][y] = '*';
}
void computerMove(char pieces[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % 3;//取0到2的一个数
		y = rand() % 3;
		if (x >= 0 && x <= 2 && y >= 0 && y <= 2 && pieces[x][y] == ' ')//如果位置合法
		{
			pieces[x][y] = '#';
			break;
		}
	}
}
int judge(char pieces[ROW][COL], int row, int col)
{
	//判断是否有一行三个棋子一样
	for (int i = 0; i < row; i++)
	{
		int sum = pieces[i][0] + pieces[i][1] + pieces[i][2];
		if (sum == 3 * '*' || sum == 3 * '#')
			return 1;
	}
	//判断是否有一列三个棋子一样
	for (int j = 0; j < col; j++)
	{
		int sum = pieces[0][j] + pieces[1][j] + pieces[2][j];
		if (sum == 3 * '*' || sum == 3 * '#')
			return 1;
	}
    //判断两个对角线是否有三个棋子一样
	int sum1 = pieces[0][0] + pieces[1][1] + pieces[2][2];
	int sum2 = pieces[0][2] + pieces[1][1] + pieces[2][0];
	if (sum1 == 3 * '*' || sum1 == 3 * '#' || sum2 == 3 * '*' || sum2 == 3 * '#')
		return 1;
	return 0;
}

这样就实现了一个简单的三子棋,看看效果如何:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于RabbitMQ的模拟消息队列之二---创建项目及核心类

一、创建项目 创建一个SpringBoot项目&#xff0c;环境&#xff1a;JDK8&#xff0c;添加依赖&#xff1a;Spring Web、MyBatis FrameWork(最主要&#xff09; 二、创建核心类 1.项目分层 2.核心类 在mqserver包中添加一个包&#xff0c;名字为core&#xff0c;表示核心类…

前端Vue自定义得分构成水平柱形图组件 可用于系统专业门类得分评估分析

引入Vue自定义得分构成水平柱形图组件&#xff1a;cc-horBarChart 随着技术的发展&#xff0c;传统的开发方式使得系统的复杂度越来越高&#xff0c;一个小小的改动或小功能的增加可能会导致整体逻辑的修改&#xff0c;造成牵一发而动全身的情况。为了解决这个问题&#xff0c…

设计模式系列-创建者模式

一、上篇回顾 上篇我们主要讲述了抽象工厂模式和工厂模式。并且分析了该模式的应用场景和一些优缺点&#xff0c;并且给出了一些实现的思路和方案,我们现在来回顾一下&#xff1a; 抽象工厂模式&#xff1a;一个工厂负责所有类型对象的创建&#xff0c;支持无缝的新增新的类型对…

centos安装jdk-8u371-linux-x64.tar.gz包

java -version //查看jdk版本 rpm -qa | grep jdk 删除带有"openjdk"字样的jdk 例: rpm -e --nodeps java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.x86_64 下载该版本的jdk(jdk-8u371-linux-x64.tar.gz) (https://www.oracle.com/java/technologies/javase/javase8u2…

linux 内存一致性

linux 出现内存一致性的场景 1、编译器优化 &#xff0c;代码上下没有关联的时候&#xff0c;因为编译优化&#xff0c;会有执行执行顺序不一致的问题&#xff08;多核单核都会出现&#xff09; 2、多核cpu乱序执行&#xff0c;cpu的乱序执行导致内存不一致&#xff08;多核出…

MATLAB制图代码【第二版】

MATLAB制图代码【第二版】 文档描述 Code describtion: This code is version 2 used for processing the data from the simulation and experiment. Time : 2023.9.3 Author: PEZHANG 这是在第一版基础上&#xff0c;迭代出的第二版MATLAB制图代码&#xff0c;第二版的特点是…

kvm 虚拟机添加网卡方法

找到kvm虚拟机的配置文件 虚拟机名称.xml kvm虚拟机配置文件默认路径&#xff1a;/etc/libvirt/qemu/ 先停kvm虚拟机 virsh shutdown 虚拟机名称 修改kvm虚拟机配置文件 virsh edit 虚拟机名称 在kvm虚拟机里面配置新增接口如下内容&#xff1a; <interface typebridg…

时序预测 | MATLAB实现CNN-GRU卷积门控循环单元时间序列预测(风电功率预测)

时序预测 | MATLAB实现CNN-GRU卷积门控循环单元时间序列预测&#xff08;风电功率预测&#xff09; 目录 时序预测 | MATLAB实现CNN-GRU卷积门控循环单元时间序列预测&#xff08;风电功率预测&#xff09;预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.时序预测 | MA…

裸露土方智能识别算法 python

裸露土方智能识别算法通过opencvpython网络模型框架算法&#xff0c;裸露土方智能识别算法能够准确识别现场土堆的裸露情况&#xff0c;并对超过40%部分裸露的土堆进行抓拍预警。此次算法用到的Python是一种由Guido van Rossum开发的通用编程语言&#xff0c;它很快就变得非常流…

Unexpected mutation of “xxxx“ prop

原因 是因为子级修改了父级的数据&#xff0c;所以eslint执行的时候报了这个错 修复方式 1 如果是弹窗等组件&#xff0c;可以根据功能进行修改&#xff0c;比如我这块用的 element ui 的 dialog&#xff0c;便可以改成这样 使用 model-value 代替 修复方式 2 新建子组件…

Java网络编程-Socket实现数据通信

文章目录 前言网络编程三要素IP地址和端口号传输协议Socket 使用Scoket实现网络通信TCPTCP通信-发送方TCP通信-接收方结果 UDPUDP通信-发送方UDP通信-接收方结果 总结 前言 本文主要是为下一篇Websockt做铺垫&#xff0c;大家了解socket的一些实现。 网络编程三要素 网络编程…

将符号分隔的文本文件txt转换为excel的实现

文本文件如下&#xff1a; 现在不好处理&#xff0c;打算将其转换为excel&#xff0c;其中通过冒号分割&#xff1a;line.split(":") main方法如下&#xff1a; public static void main(String[] args) {String textFilePath "D:\\zoom\\期刊\\J_Medline\\J_…

在Windows 10上部署ChatGLM2-6B:掌握信息时代的智能对话

在Windows 10上部署ChatGLM2-6B&#xff1a;掌握信息时代的智能对话 硬件环境ChatGLM2-6B的量化模型最低GPU配置说明准备工作ChatGLM2-6B安装部署ChatGLM2-6B运行模式解决问题总结 随着当代科技的快速发展&#xff0c;我们进入了一个数字化时代&#xff0c;其中信息以前所未有的…

大语言模型之七- Llama-2单GPU微调SFT

&#xff08;T4 16G&#xff09;模型预训练colab脚本在github主页面。详见Finetuning_LLama_2_0_on_Colab_with_1_GPU.ipynb 在上一篇博客提到两种改进预训练模型性能的方法Retrieval-Augmented Generation (RAG) 或者 finetuning。本篇博客过一下模型微调。 微调&#xff1a…

【大数据模型】让chatgpt为开发增速(开发专用提示词)

汝之观览&#xff0c;吾之幸也&#xff01;本文主要聊聊怎样才能更好的使用提示词&#xff0c;给开发提速&#xff0c;大大缩减我们的开发时间&#xff0c;比如在开发中使用生成表结构脚本的提示词&#xff0c;生成代码的提示词等等。 一、准备 本文主要根据Claude进行演示&am…

成集云 | 多维表格自动化管理jira Server项目 | 解决方案

源系统成集云目标系统 方案介绍 基于成集云集成平台&#xff0c;在多维表格中的需求任务信息自动创建、更新同步至 Jira Server 的指定项目中&#xff0c;实现多维表格中一表管理 Jira Server 中的项目进度。 维格表是一种新一代的团队数据协作和项目管理工具&…

hadoop学习:mapreduce入门案例四:partitioner 和 combiner

先简单介绍一下partitioner 和 combiner Partitioner类 用于在Map端对key进行分区 默认使用的是HashPartitioner 获取key的哈希值使用key的哈希值对Reduce任务数求模决定每条记录应该送到哪个Reducer处理自定义Partitioner 继承抽象类Partitioner&#xff0c;重写getPartiti…

C++算法 —— 动态规划(1)斐波那契数列模型

文章目录 1、动规思路简介2、第N个泰波那契数列3、三步问题4、使用最小花费爬楼梯5、解码方法6、动规分析总结 1、动规思路简介 动规的思路有五个步骤&#xff0c;且最好画图来理解细节&#xff0c;不要怕麻烦。当你开始画图&#xff0c;仔细阅读题时&#xff0c;学习中的沉浸…

简明易懂:Python中的分支与循环

文章目录 前言分支结构if 语句&#xff1a;单一条件判断else语句&#xff1a;提供备选方案elif 语句&#xff1a;多条件判断嵌套的分支结构&#xff1a;复杂条件逻辑 循环结构for循环&#xff1a;遍历序列range()函数与for循环while循环&#xff1a;条件重复循环控制&#xff1…

day-01 Docker

一、docker简介 Docker 是一种开源的容器化平台&#xff0c;它可以帮助开发人员将应用程序及其依赖项打包成一个独立的、可移植的容器&#xff0c;而无需担心环境差异和依赖问题。通过使用 Docker&#xff0c;您可以更轻松地创建、分发和运行应用程序&#xff0c;无论是在开发、…