三子棋【C语言实现】

2023-11-05

三子棋

让我们一起用C语言来玩一场三子棋的游戏吧



前言

三子棋怎么实现呢?
我们首先要想原理有大致思路,然后我们才能着手实现。例如要打印棋盘,怎么样把棋下到棋盘里面,怎么样判断输赢,Let’s go!


一、基本步骤

  1. 菜单界面选择开始或者退出游戏。
  2. 创建棋盘并初始化。
  3. 打印棋盘。
  4. 玩家落子(通过输入行列坐标的方式来落子),'#’表示玩家落子。
  5. 判定胜负关系(输,赢,和棋)。
  6. 如未分胜负继续执行。
  7. 电脑落子(随机位置落子) ,'#’表示电脑落子。
  8. 判定胜负关系。
  9. 如未分胜负回到 4 继续执行,如果胜负已分则打印结果结束游戏,返回菜单界面。

二、具体实现

1.菜单界面

在开始游玩前,我们要准备一个界面,清晰的告诉玩家应该如何操作,因此我们可以得知菜单界面必须执行一次,而且为了满足可以重复游玩,所以我们这里使用do{}while()循环
1.开始游戏 0.退出游戏

代码如下:

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

2.创建棋盘

我们知道棋盘是一个二维平面,我们可以通过坐标来实现将玩家所下的棋子存储起来,这时候二维数组便是最好的选择

代码如下:

#define ROW 3
#define COL 3
char board[ROW][COL] = { 0 };

3.棋盘初始化

我们要实现类似下图的一个棋盘,我们可以观察我们可以先在二维数组中储存空格,这也就能解释为什么我们在上一步定义的时候定义的是char类型的二维数组。
在这里插入图片描述

代码如下

//初始化棋盘
void Initboard(char board[3][3],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] = ' ';
		}
	}

}

4.打印棋盘

只有在打印棋盘后,玩家才知道在何处落子,而且在电脑落子也要让玩家看到,我们将在多处看到打印出来的界面,这就解释了这里使用函数的好处;
玩家是在下棋所以要让这个二维数组打印成为一个棋盘。

代码如下:

//打印棋盘
void PrintBoard(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");
		for (j = 0; j < col; j++){
			if (i < row - 1){
				printf("---");
				if (j<col-1)
				printf("|");
			}
		}
		printf("\n");

	}
}

运行结果:

在这里插入图片描述

5.玩家落子

我们可以根据玩家所输入的坐标来确定所储存的位置,但是我们需注意以下几点:
1、玩家输入的需时有效坐标;
2、已落子坐标不能在落子;
3、如果坐标有误需要重新输入;

代码如下:

//玩家下棋
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){
		//玩家会认为坐标从1开始,所以我们这里x,y各自减一
			if (board[x - 1][y - 1] == ' '){
				board[x-1][y-1] = '*';
				break;
			}
			else{
				printf("坐标被占用,你是故意找茬是不\n");
			}

		}
		else{
			printf("非法输入,请重新键入;\n");
		}
	}
}

6.电脑落子

这里简单一点,我们让电脑随机落子,但是仍是有规则的随机,仍要注意落子范围是否有效,坐标位置是否已被占用。

代码如下:

//电脑下棋
void ComputerBoard(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;
		}
	}
}

7.判断输赢

我们可以想到每次落子都会有四种状态:玩家获胜,电脑获胜,平局,继续游戏;我们可以在主函数内通过判断输赢函数返回值来决定此时的状态:
约定返回结果的含义:
(1)‘*’ 表示玩家获胜
(2)‘#’ 表示电脑获胜
(3)’ C’ 表示胜负未分,继续游戏
(4) ‘Q’ 表示和棋
1.判定是否和棋
(1)调用isFull函数。
(2)如果数组中有元素为’ ‘,那么没满,返回0。如果全不为’ ',满了,返回1。
(3)如果棋盘满了未分出胜负,和棋。
2.判定电脑玩家胜利
(1)判定所有的行
(2)判定所有的列
(3)判定两条对角线

代码如下:

// 满了就返回1
//不满  返回0
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)
{
	//行
	int i = 0;
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
		{
			return board[i][1];//
		}
	}

	//列
	int j = 0;
	for (j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
		{
			return board[1][j];
		}
	}
	//对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}

	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}

	//没有人赢,就要平局
	if (IsFull(board, row, col))
	{
		return 'Q';
	}

	//游戏继续
	return 'C';
}

8.运行演示

1、玩家获胜

在这里插入图片描述

2、电脑获胜

在这里插入图片描述

3、和棋

在这里插入图片描述


三、完整代码

#include"game.h"
void menu(){
	printf("************************************\n");
	printf("**********1.play    0.exit**********\n");
	printf("************************************\n");

}
void game(){
	char board[ROW][COL] = { 0 };
	char ret;
	//初始化
	Initboard(board,ROW,COL);
	PrintBoard(board, ROW, COL);
	//玩家下棋
	while (1){
		PlayerMove(board, ROW, COL);
		PrintBoard(board, ROW, COL);
		//判断输赢
		ret = Iswin(board, ROW, COL);
		if ('*'==ret){
			printf("玩家获胜\n");
			PrintBoard(board, ROW, COL);
			break;
		}
		else{
			if ('Q' == ret){
				printf("平局\n");
				PrintBoard(board, ROW, COL);
				break;
			}
		}
		;
		ComputerBoard(board, ROW, COL);
		PrintBoard(board, ROW, COL);
		//判断输赢
		ret = Iswin(board, ROW, COL);
		char ret = Iswin(board, ROW, COL);
		if ('#' == ret){
			printf("电脑胜利\n" );
			PrintBoard(board, ROW, COL);
			break;
		}
		else{ if ('Q' == ret){
			printf("平局\n");
			PrintBoard(board, ROW, COL);
			break;
		}
		}

	}

}
int main(){
	srand((unsigned int)time(NULL));//设置随机数起点
	int input = 0;
	do{
		menu();
		printf("请输入接下来您要进行的操作>");
		scanf("%d", &input);
		switch (input){
		case 1:
			printf("开始游戏\n");
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:printf("选择错误,请从新输入:\n");
			break;
		}

	} while (input);
	return 0;
}
#include"game.h"
//初始化棋盘
void Initboard(char board[3][3],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 PrintBoard(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");
		for (j = 0; j < col; j++){
			if (i < row - 1){
				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 ComputerBoard(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;
		}
	}
}
// 满了就返回1
//不满  返回0
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)
{
	//行
	int i = 0;
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
		{
			return board[i][1];//
		}
	}

	//列
	int j = 0;
	for (j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
		{
			return board[1][j];
		}
	}
	//对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}

	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}

	//没有人赢,就要平局
	if (IsFull(board, row, col))
	{
		return 'Q';
	}

	//游戏继续
	return 'C';
}
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define ROW 3
#define COL 3

//初始化棋盘
void Initboard(char board[ROW][COL],int row,int col);

//打印棋盘
void PrintBoard(char board[ROW][COL], int row, int col);

//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);

//电脑下棋
void ComputerBoard(char board[ROW][COL], int row, int col);

//判断输赢
char Iswin(char board[ROW][COL], int row, int col);

总结

以上就是我们三子棋的实现,我们只要有了数组,函数的知识就能实现这样一个简单的小游戏,但是有很多我们需要注意的细节。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

三子棋【C语言实现】 的相关文章

随机推荐

  • Idea快捷键大全(Windows)

    一 知道类名查找类 1 Ctrl Shift Alt N 2 双击Shift 二 查找类中所有方法 Ctrl F12 三 快速查找类或方法在整个项目中的位置 按住Ctrl键再点击类或方法会出现所有用到过的文件对象
  • Map集合案例-统计投票人数

    需求 某个班级80名学生 现在需要组成秋游活动 班长提供了四个景点依次是 A B C D 每个学生只能选择一个景点 请统计出最终哪个景点想去的人数最多 利用Map集合进行统计 A06 HashMapDemo2 java package da
  • MySQL主从复制搭建步骤详解

    MySQL主从复制搭建步骤详解 1 简介 MySQL主从复制是一种数据库高可用性的解决方案 通过将数据从一个MySQL主服务器同步到一个或多个从服务器来提高数据库的可用性和性能 本文将详细介绍如何搭建MySQL主从复制环境 2 环境准备 在
  • linux下Nerdtree安装方法

    目录 1 下载Nerdtree 2 linux下安装 3 成功享受吧 1 下载Nerdtree 百度网盘下载 地址为链接 百度网盘 请输入提取码 提取码 07e3 来自百度网盘超级会员V4的分享 github方式下载 地址为 https g
  • 字符串 去掉空格 C++

    去掉空格 时间限制 1Sec 内存限制 128MB 提交 5807 解决 3117 题目描述 读入一些字符串 将其中的空格去掉 输入 输入为多行 每行为一个字符串 字符串只由字母 数字和空格组成 长度不超过80 输入以 End of fil
  • 【五、反向代理及其相关配置】

    文章目录 反向代理及其相关配置 1 反向代理 2 正向代理 3 网关 4 Nginx做反向代理的缺点 5 反向代理配置 1 跳转到外网网站上 2 跳转到本机服务器上 反向代理及其相关配置 1 反向代理 服务器提供的代理为反向代理 原理 当用
  • 网络安全(黑客)自学的误区

    一 自学网络安全学习的误区和陷阱 1 不要试图先成为一名程序员 以编程为基础的学习 再开始学习 我在之前的回答中 我都一再强调不要以编程为基础再开始学习网络安全 一般来说 学习编程不但学习周期长 而且实际向安全过渡后可用到的关键知识并不多
  • Trie树【数组实现】

    全文目录 Trie的表现形式 数组实现 Trie 树 代码 Trie的表现形式 Trie树主要用来实现字符串的存储和快速查找 其表现形式类似一颗多叉树 每个节点表示字符串的一个字符 由于可能会存在类似 abc 和 abcde 这样的数据 所
  • 大数据和人工智能到底是什么关系

    大数据和人工智能的关系 首先要说什么是大数据 这些年来 大数据先是被神化 继而又被妖魔化 到了今天 其实谁也不知道别人所谓的大数据指的是什么 有时候大数据的定义里既有平台 硬件 又有分析技术 但为了说清楚大数据和人工智能的关系 我们还是回归
  • 下一波加密浪潮:站在风口上的“NFT”!

    如果说2020是区块链的 Defi 大火年 流动性挖矿让不少用户和平台完美体验了一场红利盛宴 那么2021则杀出的黑马 NFT 升级为主角 拉开了表演的序幕 不少项目和用户目光纷纷投向这一赛道 试图寻找新的财富机遇 NFT定义 它究竟是什么
  • 特征脸EigenFace、Fisher脸FisherFace、LBP直方图LBPHFace

    在最新版的2 4 2中 文档的更新也是一大亮点 refrence manual扩充了200多页的内容 添加了contrib部分的文档 contrib就是指OpenCV中新添加的模块 但又不是很稳定 可以认为是一个雏形的部分 这次结合refm
  • 【NLP】使用 PyTorch 通过 Hugging Face 使用 BERT 和 Transformers 进行情感分析

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • Android 项目必备(十二)--> APP 底部导航栏最佳实践

    文章目录 简介 TabLayout Fragment 1 效果图 2 布局文件 3 代码 BottomNavigationView Fragment 1 效果图 2 布局文件 3 main bottom navigation xml 4 代
  • Python实现拉格朗日插值法填补缺失值

    s为列向量 n为被插值的位置 k为取前后的数据个数 默认为5 from scipy interpolate import lagrange 导入拉格朗日插值函数 def ployinterp column s n k 5 y s iloc
  • 每日技巧(word条形图更改横坐标)

    问题 在工作中 遇到条形图需要更改纵坐标的数据 那该如何解决这个问题呢 解决方案 右键 选中编辑数据中的在Excel中编数据 D 点击完成后会出现 如下图的Excel的表格 数据编辑完成后 则横坐标则会改变 如下图 今日小技巧到此为止
  • 消息队列 RabbitMQ入门:Linux(Docker)中安装和卸载RabbitMQ服务

    文章目录 前言 一 Linux中安装RabbitMQ 下载Erlang 下载RabbitMQ 进入Linux进行安装 启动RabbitMQ 二 RabbitMQ Web管理页面 安装RabbitMQ Web管理页面 访问管理页面 三 使用D
  • 协同过滤算法_《推荐系统实践》3.基于物品的协同过滤算法

    基于物品的协同过滤算法 item based collaborative filtering 以下简称ItemCF 算法思想 给用户推荐那些和他们之前喜欢的物品相似的物品 不过 ItemCF算法并不利用物品的内容属性计算物品之间的相似度 它
  • android二级菜单ui,Android UI 之实现多级树形列表TreeView示例

    所谓TreeView就是在Windows中常见的多级列表树 在Android中系统只默认提供了ListView和ExpandableListView两种列表 最多只支持到二级列表的实现 所以如果想要实现三级和更多层次的列表 就需要我们自己来
  • python pandas使用pipe管道增强代码可读性

    pandas dataframe的pipe文档链接 https pandas pydata org docs reference api pandas DataFrame pipe html 使用pipe可以像水流一样 有顺序的执行data
  • 三子棋【C语言实现】

    三子棋 让我们一起用C语言来玩一场三子棋的游戏吧 文章目录 三子棋 前言 一 基本步骤 二 具体实现 1 菜单界面 2 创建棋盘 3 棋盘初始化 4 打印棋盘 5 玩家落子 6 电脑落子 7 判断输赢 8 运行演示 1 玩家获胜 2 电脑获