C语言实现“井字棋”游戏(三子棋)人机对弈

2023-05-16

井字棋游戏:即三子棋,英文名叫Tic-Tac-Tic,是一种在3*3格子上进行的连珠游戏,和五子棋比较类似,由于棋盘一般不画边线框,格线排成井字故得名。

题目分析 :

要完成该游戏的编写,我们需要先分析出完成整个游戏过程都需要干什么?

1.首先,需要定义出一个3*3的棋盘,根据相关知识,我们可以以二维数组的方式将棋盘表示出来;

2.棋盘定义出来后,需要将棋盘初始化,将3*3二维数组的每一个位置初始化为‘ ’(空格);

3.有了棋盘,我们就可以开始进行下棋了,首先要确定是玩家先下还是电脑先下。在这里我们规定玩家先下且玩家的下棋方式为‘x’,电脑下棋方式为‘o’;

4.每一次下完棋后需要进行检测,判断该下棋位置是否合法、判断是否胜利等等。

根据上述分析,可以大致定义出以下函数窗口:

void InitGame();//初始化游戏(棋盘)
void PrintChess();//输出棋盘
void PlayerMove();//玩家下棋
void ComputerMove();//电脑下棋
char CheckGameOver();//判断游戏是否结束(玩家胜/电脑胜/和棋)

初始化棋盘:将3*3的二维数组棋盘的每个位置初始化为‘ ’

void InitGame()
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
			chess_board[i][j] = ' ';
	}
}

输出棋盘: 输出棋盘时,棋盘的风格可以根据自己的喜好来设计

void PrintfChess()//输出棋盘,棋盘的设计可以根据自己的喜好设计
{
	for (int i = 0; i < ROW; i++)
	{
		printf("| %c | %c | %c |\n", chess_board[i][0], chess_board[i][1], chess_board[i][2]);
		if (i < ROW - 1)
			printf("|---|---|---|\n");
	}
}

玩家下棋: 玩家输入下棋位置后,需要判断该位置是否合法、输入位置是否已被占用

void PlayerMove()//玩家下棋
{
	printf("玩家落子.\n");
	int row, col;
	while (1)
	{
		printf("请输入一组坐标(下棋位置):>");
		scanf("%d %d", &row, &col);
		//检查坐标的有效性
		if (row < 0 || row > ROW || col < 0 || col > COL)
		{
			printf("输入非法,请重新输入...");
			continue;
		}
		if (chess_board[row][col] != ' ')
		{
			printf("输入的位置已被占用,请重新输入...");
			continue;
		}
		chess_board[row][col] = 'x';//x代表玩家下的棋
		break;
	}
}

电脑下棋: 电脑下棋时,下棋的位置利用srand函数随机产生

void ComputerMove()//电脑下棋
{
	srand(time(0));
	while (1)
	{
		int row = rand() % ROW;
		int col = rand() % COL;
		if (chess_board[row][col] != ' ')
		{
			continue;
		}
		chess_board[row][col] = 'o';//o代表电脑下的棋
		break;
	}
}

检查棋盘 :在检测棋盘时,分别判断行、列、对角线,在这里我规定:

'x'代表玩家赢   'o'代表电脑赢   'h'代表和棋   'c'代表继续

char CheckGameOver()//检测游戏是否结束
{
	//检查行
	for (int i = 0; i < ROW; i++)
	{
		if (chess_board[i][0] != ' '
			&& chess_board[i][0] == chess_board[i][1]
			&& chess_board[i][0] == chess_board[i][2]
			)
			return chess_board[i][0];
	}
	//检查列
	for (int j = 0; j < COL; j++)
	{
		if (chess_board[0][j] != ' '
			&& chess_board[0][j] == chess_board[1][j]
			&& chess_board[0][j] == chess_board[2][j]
			)
			return chess_board[0][j];
	}
	//检查对角线
	if (chess_board[0][0] != ' '
		&& chess_board[0][0] == chess_board[1][1]
		&& chess_board[0][0] == chess_board[2][2]
		)
		return chess_board[0][0];
	if (chess_board[0][2] != ' '
		&& chess_board[0][2] == chess_board[1][1]
		&& chess_board[0][2] == chess_board[2][0]
		)
		return chess_board[0][2];
	//判断是否和棋
	if (ChessFull())
		return 'h';
	return 'c';
}

至此,主要的功能函数均已编写完毕,整个程序的流程如下所示:

1.初始化棋盘;

2.输出棋盘;

3.玩家下棋;

4.检测棋盘;

5.电脑下棋;

6.检测棋盘

代码如下: 

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <time.h>
#include <stdbool.h>
#include <stdlib.h>

#define START 1
#define QUIT  0
#define ROW   3
#define COL   3

static char chess_board[ROW][COL];//定义棋盘

void StartGame();
void InitGame();
void PrintfChess();
void PlayerMove();
void ComputerMove();
char CheckGameOver();
bool ChessFull();

int main(int argc, char* argv[])
{
	int select = 1;
	while (select)
	{
		printf("*********************\n");
		printf("* [1] Start Game    *\n");
		printf("* [2] Over  Game    *\n");
		printf("*********************\n");
		printf("请选择:>");
		scanf_s("%d", &select);

		if (select == QUIT)
			break;
		if (select != START)
		{
			printf("输入有错,请重新输入.....\n");
			continue;
		}
		StartGame();
	}
	printf("GoodBye.....");
	return 0;
}

void StartGame()
{
	char winner;
	//1 初始化游戏(棋盘)
	InitGame();
	//2 进入游戏
	while (1)
	{
		//3 输出棋盘
		PrintfChess();
		//4玩家下棋
		PlayerMove();
		//5检查结果
		winner = CheckGameOver();
		if (winner != 'c')
			break;
		
		//6电脑下棋
		ComputerMove();
		//7检查结果
		CheckGameOver();
		winner = CheckGameOver();
		if (winner != 'c')
			break;
	}
	if (winner == 'x')
		printf("玩家赢.\n");
	if (winner == 'o')
		printf("电脑赢.\n");
	if (winner == 'h')
		printf("和棋.\n");
}

void InitGame()
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
			chess_board[i][j] = ' ';
	}
}

void PrintfChess()//输出棋盘,棋盘的设计可以根据自己的喜好设计
{
	for (int i = 0; i < ROW; i++)
	{
		printf("| %c | %c | %c |\n", chess_board[i][0], chess_board[i][1], chess_board[i][2]);
		if (i < ROW - 1)
			printf("|---|---|---|\n");
	}
}

void PlayerMove()//玩家下棋
{
	printf("玩家落子.\n");
	int row, col;
	while (1)
	{
		printf("请输入一组坐标(下棋位置):>");
		scanf("%d %d", &row, &col);
		//检查坐标的有效性
		if (row < 0 || row > ROW || col < 0 || col > COL)
		{
			printf("输入非法,请重新输入...");
			continue;
		}
		if (chess_board[row][col] != ' ')
		{
			printf("输入的位置已被占用,请重新输入...");
			continue;
		}
		chess_board[row][col] = 'x';//x代表玩家下的棋
		break;
	}
}

void ComputerMove()//电脑下棋
{
	srand(time(0));
	while (1)
	{
		int row = rand() % ROW;
		int col = rand() % COL;
		if (chess_board[row][col] != ' ')
		{
			continue;
		}
		chess_board[row][col] = 'o';//o代表电脑下的棋
		break;
	}
}
/*
* 'x'代表玩家赢
* 'o'代表电脑赢
* 'h'代表和棋
* 'c'代表继续
*/
char CheckGameOver()//检测游戏是否结束
{
	//检查行
	for (int i = 0; i < ROW; i++)
	{
		if (chess_board[i][0] != ' '
			&& chess_board[i][0] == chess_board[i][1]
			&& chess_board[i][0] == chess_board[i][2]
			)
			return chess_board[i][0];
	}
	//检查列
	for (int j = 0; j < COL; j++)
	{
		if (chess_board[0][j] != ' '
			&& chess_board[0][j] == chess_board[1][j]
			&& chess_board[0][j] == chess_board[2][j]
			)
			return chess_board[0][j];
	}
	//检查对角线
	if (chess_board[0][0] != ' '
		&& chess_board[0][0] == chess_board[1][1]
		&& chess_board[0][0] == chess_board[2][2]
		)
		return chess_board[0][0];
	if (chess_board[0][2] != ' '
		&& chess_board[0][2] == chess_board[1][1]
		&& chess_board[0][2] == chess_board[2][0]
		)
		return chess_board[0][2];
	//判断是否和棋
	if (ChessFull())
		return 'h';
	return 'c';
}
bool ChessFull()
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			if (chess_board[i][j] == ' ')
				return false;
		}
	}
	return true;
}

运行测试图: 

 

 程序的运行界面我们还可以利用system("cls")对界面进行优化,这样可以使界面更加美观。

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

C语言实现“井字棋”游戏(三子棋)人机对弈 的相关文章

  • 【C、C++系列-1】C语言实现:寻找[1,100]之间的素数

    C C 43 43 系列 1 C语言实现 xff1a 寻找 1 100 之间的素数 1 问题 C语言实现 xff1a 寻找 1 100 之间的素数 2 实现代码 span class token comment 寻找 1 100 之间的素数
  • C语言实现strlen()函数

    方式一 xff1a span class token macro property span class token directive keyword define span CRT SECURE NO WARNINGS span spa
  • C语言实现strcmp()函数

    span class token macro property span class token directive keyword define span CRT SECURE NO WARNINGS span span class to
  • 选择排序算法(C语言实现)

    include lt stdio h gt void choice int a int n int i j temp for i 61 0 i lt n 1 i 43 43 for j 61 i 43 1 j lt n j 43 43 if
  • 使用汇编语言与C语言实现LED1/LED2/LED3三盏灯点亮

    汇编语言代码段 text global start start LED13 INIT LED1 3点灯 RCC章节 64 1 设置GPIO始终使能 通过RCC AHB4ENSRTR寄存器设置0x50000A28 4 61 1 ldr r0
  • (c语言实现)数据结构链表oj题(2)

    前言 x1f388 个人主页 x1f388 初阶牛 x1f43b 推荐专栏 x1f354 x1f35f x1f32f C语言进阶 x1f511 个人信条 x1f335 知行合一 x1f349 本篇简介 gt 分析力扣中有关链表的部分题目 目
  • 用c语言实现 将src指向的字符串追加到dest指向字符串的后面

    实现char my strcat char dest char src 函数 返回 xff1a dest字符串的地址 功能 xff1a 将src指向的字符串追加到dest指向字符串的后面 例如 xff1a char dest 10 61 3
  • 中序计算式的计算器模型C语言实现

    span class token macro property span class token directive keyword include span span class token string lt stdio h gt sp
  • C语言实现16进制数与10进制数的转化

    C语言实现16进制数与10进制数的转化 这里有两种情况 xff1a 第一种情况 xff1a 如果我得到的是一个16进制数 xff0c 我通过肉眼看到的就是16进制显示 xff08 这里看到的肯定打印结果 xff09 xff0c 比如85 x
  • 用C语言实现websocket服务器

    Websocket Echo Server Demo 背景 嵌入式设备的应用开发大都依靠C语言来完成 xff0c 我去研究如何用C语言实现websocket服务器也是为了在嵌入式设备中实现一个ip camera的功能 xff0c 用户通过网
  • 一篇文章带你搞懂扫雷小游戏(c语言实现)

    目录 前言 1 游戏设计逻辑 2 游戏思考及实现过程 2 1符号与棋盘的建立 2 2棋盘的初始化与打印 2 3布置雷 2 4 排查雷并设置结束标志 3 代码展示 test c game c game h 前言 扫雷是一款经典的小游戏 xff
  • C 语言实现 FTP 服务器

    这个有专门的课程讲解我看到 xff0c 百度也能搜到不少相关的 我觉得你可以去把这个弄懂
  • TCP通信模型(C语言实现)

    大家好 xff0c 我是练习编程时长两年半的个人练习生昆工第一ikun xff0c 今天我们来分享TCP通信模型 xff0c 并且用C语言实现它 目录 一 我们将实现三个示例功能 xff1a 二 TCP服务器搭建流程 xff08 1 xff
  • 使用Verilog HDL语言实现4位超前进位加法器

    一 1位半加器的实现 1 1 原理 半加器由两个一位输入相加 xff0c 输出一个结果位和进位 xff0c 没有进位输入的加法器电路 1 2 真值表 1 3 逻辑表达式 S 61 A B C 61 A amp B 1 4 Verilog 实
  • C语言实现UDP通信

    UDP通信 UDP是一种无连接的尽最大努力交付的不可靠连接 xff0c 通信之前无需先建立连接 xff0c 自然而然 xff0c 通信之后也就无需再释放连接 通信的套接字 UDP所采用的通信接口与前面讲过的TCP通信接口相同 xff0c 只
  • C++/C语言实现HTTP的GET和POST请求

    阅读目录 HTTP请求和IP TCP 实现GET请求 实现POST请求 xff1a 参考 xff1a 回到顶部 HTTP请求和IP TCP 所谓的HTTP协议是基于IP TCP协议的 xff0c 所以要获取远端的html数据只要创建sock
  • c语言实现strcat函数

    char strcat char strDestination const char strSource 一 函数介绍 作用 xff1a 连接字符串的函数 xff0c 函数返回指针 xff0c 两个参数都是指针 xff0c 第一个参数所指向
  • C++:C语言实现HTTP的GET和POST请求

    https www cnblogs com diligenceday p 6255788 html
  • C语言实现TCP服务器与客户端通信

    以上是TCP通信客户端与服务器实现通信的基本原理流程图 1 客户端的实现 xff08 4个步骤 xff09 1 1创建socket对象 1 2请求连接 1 3发送数据 1 4关闭套接字 include lt stdio h gt inclu
  • 二叉树递归遍历(C语言实现)

    span class token macro property span class token directive hash span span class token directive keyword include span spa

随机推荐

  • Qt项目实战:愤怒的小鸟(联机版)

    前言 本文章会详细介绍难点的内容 xff0c 不附带全部源码 xff0c 会将关键代码进行展示 因为只有截图 xff0c 这里在每一个动作和界面都添加了音效与BGM 同时附加了CG展示 素材和音效全部放在下面了 xff0c 需要可自行提取
  • Ubuntu中安装openCV时Cmake问题解决

    1 执行Cmake的语句指令 sudo cmake D CMAKE BUILD TYPE 61 Release D CMAKE INSTALL PREFIX 61 usr local 2 当执行完上述指令后遇见以下问题解决策略 问题1 xf
  • 使用 RGB-D 相机(Astra)实现 YOLO v3 实时目标检测

    设备和环境 xff1a 奥比中光RGB D相机 xff08 Astra xff09 xff1b Ubuntu16 04 首先 xff0c 先将自己的RGB D相机的环境与依赖构建好 xff0c 然后进行以下步骤构建darknet ros 1
  • Arduion应用U8g2库实现字符滚动效果

    由于U8g2库中没有可以位移的函数 xff0c 所以简单编写了一个可以实现字符滚动的代码 主要是为了记录一下自己学习Arduion的过程 算是一个记事本吧 xff01 当然如果你对于这方面有所需求 xff0c 可以拿去使用 主要是利用显示器
  • C语言老鼠走迷宫(单路径)算法详细讲解

    最近在学习C语言的一些经典算法 xff0c 其中遇到了一点困难 xff0c 导致卡进度了 琢磨了很久 xff0c 在绘制流程图时 xff0c 突然灵感大开理解了 xff0c 老鼠走迷宫算法的奇妙 所以写了这个 xff0c 一来是方便以后右和
  • 关于二分搜索法条件判断的研究

    最近在写二分搜索法时 xff0c 发现了几个现象 xff0c 在不同的条件设定之下 xff0c 系统会出现几种bug xff1a 1 当搜索的值 lt 最小值 时系统都会一直在循环内执行 2 当搜索的值 gt 最大值 时系统都会一直在循环内
  • C++ 库函数<string>示例

    最近在学C 43 43 自己整理了一部分C 43 43 库函数 lt string gt 的一些 函数 主要都是C 43 43 的 想到以后可能会用到 所以打算记录一下 方便自己也方便了大家 在啃这些函数的时候有很多借鉴之处 xff0c 在
  • 两台电脑间的串口通信

    目录 一 准备工作 二 实验过程 三 实验结果 一 准备工作 1 两台笔记本电脑 2 2个usb转串口模块 3 杜邦线若干 4 秒表 二 实验过程 两个串口线分别连接两台电脑 连线方式 xff1a 3V3 3V3 xff0c GND GND
  • c++ primer plus学习笔记(1)——基础知识

    本人还有一星期要开始期末考试了 xff0c 复习c 43 43 时顺便挖个坑 xff0c 之后会详细更新 目录 1 初识源代码 1 1 c 43 43 程序的产生 1 2 代码例 1 3 标记 空白 2 简单数据类型 2 1 变量名 2 2
  • C语言:sizeof和strlen计算字符串大小

    大家清楚 sizeof 和 strlen 的区别吗 xff1f sizeof是运算符 xff0c 确定的是字符所占空间大小 xff0c 参数可以有数组 指针 类型 对象 函数等 strlen是C语言的标准库函数 xff0c 确定是字符串的大
  • Python--爬虫--requests进阶,cookie/session模拟登录

    目录 一 原理 二 实际操作 三 结果 四 问题与总结 一 原理 以下内容为使用requests库发送请求 xff0c 使用cookie session模拟登录 xff08 并且登录时只需输入账号与密码 xff09 我们在使用搜索引擎访问网
  • linux系统移植U-boot与kernel的搭载流程(交互模式下)

    Linux系统移植四大部分 xff1a 搭建交叉开发环境 bootloader的选择和移植 本文选用bootloader下的U boot uImage的配置 编译与移植 根文件系统的制作 全部已完成 xff0c 本文只讲解 如何搭载这些东西
  • FreeRTOS任务创建、删除| FreeRTOS三

    目录 一 FreeRTOS任务创建与删除有关函数 1 1 创建 删除任务的API函数 1 1 1 动态创建任务 1 1 2 静态创建任务 1 1 3 删除任务 二 FreeRTOS任务创建与删除 xff08 动态方法 xff09 2 1 实
  • (学习)基于STM32的串口通信打印数据(HAL库+CubeMX)

    当我们在进行开发的时候 xff0c 通常需要将一些参数进行调整来达到效果 xff0c 这个时候就需要将单片机上的信息通过串口通信传送到PC机上来直观显示 一 基本的专有名词和原理介绍 USART xff1a 只能异步通信 USART xff
  • ROS通信——C++实现

    一 普通话题通信 创建功能包 xff1a catkin create pkg package roscpp rospy std msgs 创建发布者 xff1a include 34 ros ros h 34 include 34 std
  • ROS使用Python编写的步骤

    第一步 xff1a 和C 43 43 编写一样 xff0c 配置好工作空间 第二步 xff1a 在功能包下面建立一个scripts文件夹 第三步 xff1a 在scripts文件里面建立一个 py文件 第四步 编写python文件 注意 x
  • window的QT作为TCP客户端,ubuntu的python作为TCP服务端

    客户端 pro文件加入 QT 43 61 network mainwindow h ifndef MAINWINDOW H define MAINWINDOW H include lt QMainWindow gt include lt Q
  • RoboCom机器人大赛使用yolov5抽取20个随机图片进行人群识别

    目录 1 原理 2 思维流程 2 1 进行yolov5的环境搭建 2 1 1 在Linux的ubuntu环境anaconda的安装 2 1 2 Vscode的安装和配置 2 1 3 Github上面yolov5文件的下载 2 1 4 使用A
  • C语言实现字符串逆序、倒置字符串(字符串逆序问题的升级)

    一 字符串逆序 问题描述 xff1a 输入一个字符串str xff0c 将其内容颠倒过来 xff0c 并输出 数据范围0 lt len str lt 10000 输入描述 xff1a 输入一个字符串 xff0c 可以有空格 输出描述 xff
  • C语言实现“井字棋”游戏(三子棋)人机对弈

    井字棋游戏 xff1a 即三子棋 xff0c 英文名叫Tic Tac Tic xff0c 是一种在3 3格子上进行的连珠游戏 xff0c 和五子棋比较类似 xff0c 由于棋盘一般不画边线框 xff0c 格线排成井字故得名 题目分析 xff