基于C语言的趣味游戏之五子棋

目录

 

趣味五子棋游戏

 第一步

text.c文件 

 第二步

game.h文件

第三步

初始化

 打印棋盘

玩家输入 

电脑输入

判断输赢 

game.c


趣味五子棋游戏

 第一步

先写菜单,然后在主函数里调用,由于这是一个可以重复的游戏所以将do while循环里调用menu函数。

  1. 当我们键盘输入1时开启游戏,调用game()函数。由于我们是一个五子棋游戏,那么可能需要一个5x5大小的棋盘,所以我们要定义一个字符型的棋盘char board[ROW][COL];
  2. 定义好棋盘之后就初始化棋盘,在game.c文件里初始化。
  3. 初始化完之后就要打印棋盘。
  4. 然后就是让玩家落子,在判输赢,接着电脑落子,接着判输赢,这是一个循环的操作,所以需要一个while循环让这个操作循环起来。

text.c文件 

//text.c文件
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"

//五子棋

//菜单
void menu()
{
	printf("***********************\n");
	printf("******   1 paly  ******\n");
	printf("******   0 exit  ******\n");
	printf("***********************\n");
}
void game()
{
	char board[ROW][COL];
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印棋盘
	displayBoard(board, ROW, COL);
	char ret = 0;
	while(1)
	{
		//玩家下棋
		playermove(board, ROW, COL);
		//打印棋盘
		displayBoard(board, ROW, COL);
		//判断输赢
		ret = inwin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		//电脑下棋
		computermove(board, ROW, COL);
		//打印棋盘
		displayBoard(board, ROW, COL);
		//判断输赢
		ret = inwin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}

	if(ret=='*')
	{
		printf("玩家赢了\n");
	}else if(ret=='#')
	{
		printf("电脑赢了\n");
	}
	else {
		printf("平局\n");
	}
	
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch(input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
		default:
			printf("请输入正确的数字\n");
			break;
		}
		


	} while (input);
	return 0;
}

 第二步

是去头文件里去声明函数以及将一些公共的头文件包含起来。在一些大型的开发都是声明和函数实现分离的。

game.h文件

#pragma once
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<time.h>
#include"game.h"


#define ROW 5
#define COL 5
//初始化棋盘
void InitBoard(char borad[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 inwin(char board[ROW][COL], int row, int col);

第三步

 去game.c文件里去实现函数的相关功能。

初始化

初始化棋盘,就是将5x5的数组具象化,将他形成5x5的空格。当用户在相应的坐标里输入时,就将对应的空格替换成特定的符号。

 打印棋盘

//初始化棋盘
void InitBoard(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++)
		{
			board[i][j] = ' ';
		}
	}
}

对于打印棋盘,我们可以观察一下棋盘,可以将棋盘划分成两个部分一个是要输入数值部分,一个是分割部分

这里绿色部分为数值部分是用户和电脑输入坐标的部分,数值部分由  空格 | 空格 | 空格组成

红色部分是分割部分,由 ..... | ..... | ..... 组成 。

在代码实现的时候可以分两部分,数值部分,循环打印数值board[i][j];在少打一列的 | 。

分割部分可以先循环打印虚线 .......,在少打一列 | 。

//打印棋盘
void displayBoard(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++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		if(i<row-1)
		{
			for (j = 0; j < col; j++)
			{
				printf("...");
				if (j < col - 1)
					printf("|");
			}
			
		}
		printf("\n");
			
	}
}

玩家输入 

 由于数组的下标是从0开始到n-1的,但是玩家是不会考虑这些的,所以玩家的输入的下标,应该在要减一才是棋盘的下标

首先要判空,看玩家输入的下标是否不合法,收否不为空格,不为空格就是这个下标已经被占用了。

 最后在合法的下标下,将玩家输入的下标位置用 ‘ * ’替换空格。

//玩家下棋
void playermove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家下棋\n");

	while (1)
	{
		printf("输入你要下的坐标: ");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("该子已被下过\n");
			}
		}
		else {
			printf("该坐标非法,请换坐标\n");
		}
	}
}

电脑输入

 我们设计电脑输入为随机的输入,用到了随机函数rand,用rand去%模row,col是为了随机值是在小于row和col的情况下。但是别忘了,在用rand之前要先使用srand随机数种子,为了确保随机数种子的唯一性,我们将随机数种子放在test.c文件的main()函数里,确保随机数种子只被调用一次

将电脑输入的合法下标下,用#号去替换原有的空格。

//电脑随机下棋
void computermove(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋\n");
	int x = 0;
	int y = 0;
	while(1)
	{
		x = rand() % row;
		y = rand() % col;
		if(board[x][y]==' ')
		{
			board[x ][y ] = '#';
			break;
		}
	}

}

判断输赢 

 玩过五子棋的都知道,五子棋只有在五个棋子连在一起的情况才会赢。所以我们分三种情况。

第一种,用一个循环,判断所以行是否出现一样的情况。

第二种,所有列是否出现一样的情况。

第三种,正负对角线有没有出现一样的情况。

最后用他们一样的情况的一个点作为返回条件去判断谁赢了。

如果返回 * 则玩家赢;如果返回 # 则电脑赢了。如果返回Q则平局。

//判平局
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 inwin(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for(i=0;i<row;i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2]&& board[i][2] == board[i][3]&&board[i][3] == board[i][4]&& board[i][0] !=' ')
		{
			return board[i][0];
		}
	}
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][1] && board[2][i] == board[3][i] && board[3][i] == board[4][i] && board[0][i] != ' ')
		{
			return board[0][i];
		}
	}
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] == board[3][3] &&board[3][3] == board[4][4] && board[1][1] != ' ')
	{
		return board[0][0];
	}

	if (board[0][4] == board[1][3] && board[1][3] == board[2][2] && board[2][2] == board[3][1]&&board[3][1] == board[4][0] && board[0][4] != ' ')
	{
		return board[0][4];
	}
	//判断平局
	if (IsFull(board, row, col))
	{
		return 'Q';
	}

	return 'C';
}

game.c

//game.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
//初始化棋盘
void InitBoard(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++)
		{
			board[i][j] = ' ';
		}
	}
}
//打印棋盘
void displayBoard(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++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		if(i<row-1)
		{
			for (j = 0; j < col; j++)
			{
				printf("...");
				if (j < col - 1)
					printf("|");
			}
			
		}
		printf("\n");
			
	}
}
//玩家下棋
void playermove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家下棋\n");

	while (1)
	{
		printf("输入你要下的坐标: ");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && 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)
{
	printf("电脑下棋\n");
	int x = 0;
	int y = 0;
	while(1)
	{
		x = rand() % row;
		y = rand() % col;
		if(board[x][y]==' ')
		{
			board[x ][y ] = '#';
			break;
		}
	}

}
//判平局
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 inwin(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for(i=0;i<row;i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2]&& board[i][2] == board[i][3]&&board[i][3] == board[i][4]&& board[i][0] !=' ')
		{
			return board[i][0];
		}
	}
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][1] && board[2][i] == board[3][i] && board[3][i] == board[4][i] && board[0][i] != ' ')
		{
			return board[0][i];
		}
	}
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] == board[3][3] &&board[3][3] == board[4][4] && board[1][1] != ' ')
	{
		return board[0][0];
	}

	if (board[0][4] == board[1][3] && board[1][3] == board[2][2] && board[2][2] == board[3][1]&&board[3][1] == board[4][0] && board[0][4] != ' ')
	{
		return board[0][4];
	}
	//判断平局
	if (IsFull(board, row, col))
	{
		return 'Q';
	}

	return 'C';
}


代码压缩包

https://download.csdn.net/download/qq_62830324/88779627icon-default.png?t=N7T8https://download.csdn.net/download/qq_62830324/88779627 

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

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

相关文章

《WebKit技术内幕》学习之十五(2):Web前端的未来

2 嵌入式应用模式 2.1 嵌入式模式 读者可能会奇怪本章重点表达的是Web应用和Web运行平台&#xff0c;为什么会介绍嵌入式模式&#xff08;Embedded Mode&#xff09;呢&#xff1f;这是因为很多Web运行平台是基于嵌入式模式的接口开发出来的&#xff0c;所以这里先解释一下什…

keepalived+nginx双主热备(有问题私信)

keepalivednginx双主热备 前言keepalivednginx双主热备keepalivednginx双主热备部署安装nginx安装keepalived修改master节点的keepalived配置文件 修改backup节点的keeepalived配置文件配置keepalived主备配置keepalived双主热备 前言 有关keepalived和nginx的一些工作原理&am…

uniapp封装公共的方法或者数据请求方法

仅供自己参考&#xff0c;不是每个页面都用到这个方法&#xff0c;所以我直接在用到的页面引用该公用方法&#xff1a; 1、新建一个util.js文件 export const address function(options){return new Promise((resolve,reject)>{uni.request({url:"https://x.cxniu.…

matlab对负数开立方根得到虚数的解决方案

问题描述&#xff1a;在matlab中&#xff0c;对负数开立方根&#xff0c;不出意外你将得到虚数。 例如 − 27 3 \sqrt[3]{-27} 3−27 ​&#xff0c;我们知道其实数解是-3&#xff0c;但在matlab中的计算结果如下&#xff1a; 问题原因&#xff1a;matlab中的立方根运算是在…

【JAVA面试精选篇-初生牛犊不怕虎】

文章目录 🌽 简介🧺 线程池🌄 Redis⏰ JVM🚛 数据结构🍎 Mysql🍡 结语🌽 简介 海阔凭鱼跃,天高任鸟飞! 学习不要盲目,让大脑舒服的方式吸收知识!!! 本人马上离开济南,回泰安发展,为了积极准备面试,目前在梳理一些知识点,同时希望能够帮助到需要的人… …

libjsoncpp 的编译和交叉编译

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

【现代密码学基础】详解完美安全与香农定理

目录 一. 介绍 二. 完美安全的密钥与消息空间 三. 完美安全的密钥长度 四. 最优的完美安全方案 五. 香农定理 &#xff08;1&#xff09;理论分析 &#xff08;2&#xff09;严格的正向证明 &#xff08;3&#xff09;严格的反向证明 六. 小结 一. 介绍 一次一密方案…

【常用工具】7-Zip 解/压缩软件——基本使用方法

在实际日常工作或项目中&#xff0c;经常会遇到需要在window操作系统上压缩文件&#xff0c;在Linux操作系统上解压缩的场景&#xff0c;一款实用的压缩软件迫在眉睫&#xff0c;经过实际使用总结&#xff0c;7-Zip可以很好的解决很多压缩和解压缩问题&#xff0c;其基本使用方…

【音视频原理】音频编解码原理 ③ ( 音频 比特率 / 码率 | 音频 帧 / 帧长 | 音频 帧 采样排列方式 - 交错模式 和 非交错模式 )

文章目录 一、音频 比特率 / 码率1、音频 比特率2、音频 比特率 案例3、音频 码率4、音频 码率相关因素5、常见的 音频 码率6、视频码率 - 仅做参考 二、音频 帧 / 帧长1、音频帧2、音频 帧长度 三、音频 帧 采样排列方式 - 交错模式 和 非交错模式1、交错模式2、非交错模式 一…

精品基于Uniapp+springboot助农管理系统App农产品积分购物商城

《[含文档PPT源码等]精品基于Uniappspringboot助农管理系统App》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;Java 后台框架&#xff1a;springboot、ssm 安卓…

spring-boot redis stream消息队列demo-及死信简单处理

Redis stream 是 Redis 5 引入的一种新的数据结构&#xff0c;它是一个高性能、高可靠性的消息队列&#xff0c;主要用于异步消息处理和流式数据处理。在此之前&#xff0c;想要使用 Redis 实现消息队列&#xff0c;通常可以使用例如&#xff1a;列表&#xff0c;有序集合、发布…

Leetcode刷题笔记题解(C++):1114. 按序打印(多线程)

思路&#xff1a; 保证A,B,C三个线程的顺序不会变&#xff0c;即优先级顺序的问题 A,B需要资源1&#xff0c;B,C需要资源2 A先占用资源1和资源2&#xff0c;A线程完了之后释放资源1不释放资源2&#xff0c;然后B线程占用资源1&#xff0c;A线程完了之后释放资源1和资源2&…

28个炫酷的纯CSS特效动画示例(含源代码)

CSS是网页的三驾马车之一&#xff0c;是对页面布局的总管家&#xff0c;2024年了&#xff0c;这里列出28个超级炫酷的纯CSS动画示例&#xff0c;让您的网站更加炫目多彩。 文章目录 1. 涌动的弹簧效果2. 超逼真的3D篮球弹跳&#xff0c;含挤压弹起模态3. 鼠标放div上&#xff0…

Cesium加载地图-高德影像

废话不多说&#xff0c;直接上代码 整体代码 <template><div id"cesiumContainer" style"height: 100vh;"></div><div id"toolbar" style"position: fixed;top:20px;left:220px;"><el-breadcrumb><…

PyTorch 中的nn.Conv2d 类

nn.Conv2d 是 PyTorch 中的一个类&#xff0c;代表二维卷积层&#xff08;2D Convolution Layer&#xff09;。这个类广泛用于构建卷积神经网络&#xff08;CNN&#xff09;&#xff0c;特别是在处理图像数据时。 基本概念 卷积: 在神经网络的上下文中&#xff0c;卷积是一种特…

xshell无法连接linux,查询本机ip时出现<NO-CARRIER,BROADCAST,MULTICAST,UP>

在用xshell连接虚拟机VMware中的linux时&#xff0c;发现昨天还能连通的&#xff0c;今天连接不了了 我寻思应该是网卡配置出问题了&#xff0c;就去终端ip addr试了一下&#xff0c;果然发现问题&#xff0c;ip 查看网卡ens33就发现出现ens33:<NO-CARRIER,BROADCAST,MULTI…

自然语言处理:transfomer架构

介绍 transfomer是自然语言处理中的一个重要神经网络结构&#xff0c;算是在传统RNN和LSTM上的一个升级&#xff0c;接下来让我们来看看它有处理语言序列上有哪些特殊之处 模型整体架构 原论文中模型的整体架构如下&#xff0c;接下来我们将层层解析各层的作用和代码实现 该…

java中aes加密解密工具类

java中aes加密解密工具类 字符串&#xff1a;{“DATA”:{“SJH”:“17600024168”,“DLZH”:“91510104MA67FPXR5T”,“DLMM”:“jhdz123456”,“DLSF”:“5”,“NSRSBH”:“91510104MA67FPXR5T”},“JRSF”:“23”} 加密后&#xff1a;y4mzmi3jta22aXeIPfEdzu8sgA9uy3OevaIY…

LSTM的多变量时间序列预测(北京PM2.5预测)

参考博客 文章目录 LSTM简介数据集简介数据预处理多元LSTM预测模型数据准备&#xff1a;定义和拟合模型评估模型 训练多个滞后时间步 LSTM简介 LSTM&#xff08;Long Short-Term Memory&#xff09;是一种特殊类型的循环神经网络&#xff08;RNN&#xff09;&#xff0c;它在处…

LeetCode:1706. 球会落何处(Java 模拟)

目录 1706. 球会落何处 题目描述&#xff1a; 实现代码与解析&#xff1a; 原理思路&#xff1a; 1706. 球会落何处 题目描述&#xff1a; 用一个大小为 m x n 的二维网格 grid 表示一个箱子。你有 n 颗球。箱子的顶部和底部都是开着的。 箱子中的每个单元格都有一个对角线…