三子棋(人机对战)

2023-11-17

目录

整体思路:

头文件如下:

为什么要使用头文件呢?

头文件的使用:

游戏主函数如下:

功能实现如下:

注意:


整体思路:

1.创建一个二维数组

2.初始化二维数组

3.打印棋盘

4.玩家下棋且打印棋盘

5.电脑下棋且打印棋盘

6.判断输赢


头文件如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<time.h>
#include<stdlib.h>

#define ROW 3
#define COL 3

//声明函数
void init_board(char board[ROW][COL], int row, int col);
void print_board(char board[ROW][COL], int row, int col);
void player_move(char board[ROW][COL], int row,int col);
void computer_move(char board[ROW][COL], int row, int col);
char is_win(char board[ROW][COL], int row, int col);

为什么要使用头文件呢?

单纯的使用源文件,组织项目结构的时候,项目越大越复杂的时候,维护成本会变得越来越高

.h:头文件,组织项目结构的时候,减少大型项目的维护成本.h头文件基本都是要被多个源文件包含

例如:

以上我们在头文件中用#define的方式定义了数组(即棋盘)的行和列,

那么,在我们需要修改棋盘大小的时候,只需要对头文件中define定义的数值修改即可,大大降低了我们项目的维护成本

头文件的使用:

1.C头文件

2.所有变量的声明

3.所有函数的声明

4.#define,类型typedef、struct


游戏主函数如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include"test.h"

void menu()
{
	printf("***********************************\n");
	printf("******    欢迎来到三子棋    *******\n");
	printf("*******    1.play 0.exit    *******\n");
	printf("***********************************\n");
}

void game()
{
	//创建一个二维数组
	char board[ROW][COL] = { 0 };
	//对数组进行初始化
	init_board(board, ROW, COL);
	//打印棋盘
	print_board(board, ROW, COL);
	while (1)
	{
		//玩家下棋
		player_move(board, ROW, COL);
		print_board(board, ROW, COL);
		//判断输赢还是继续
		char ret = is_win(board,ROW,COL);
		if (ret != 'C')
		{
			break;
		}
		//电脑下棋
		computer_move(board, ROW, COL);
		print_board(board, ROW, COL);
		//判断输赢还是继续
		ret = is_win(board,ROW,COL);
		if (ret != 'C')
		{
			break;
		}
	}
	if (is_win(board, ROW, COL) == '*')
	{
		printf("玩家获胜\n");
	}
	if (is_win(board, ROW, COL) == '#')
	{
		printf("电脑获胜\n");
	}
	if (is_win(board, ROW, COL) == 'Q')
	{
		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");
			break;
		default:
			printf("输入错误!\n");
			break;
		}
	} while (input);
	return 0;
}

功能实现如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include"test.h"
//初始化棋盘
void init_board(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}
//打印棋盘
void print_board(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
			{
				printf("|");
			}
		}
		printf("\n");
		if (i < row - 1)
		{
			for (int k = 0; k < row; k++)
			{
				printf("---");
				if (k < row - 1)
				{
					printf("|");
				}
			}
			printf("\n");
		}
	}
}
//玩家下棋
void player_move(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 <= col && y >= 1)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("请重新输入\n");
			}
		}
		else
		{
			printf("请重新输入:>\n");
		}
	}
}
//电脑下棋
void computer_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("本回合电脑下棋!\n");
	while (1)
	{
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

static int is_full(char board[ROW][COL], int x, int y)
{
	for (int i = 0; i < x; i++)
	{
		for (int j = 0; j < y; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}
//判断输赢还是继续
char is_win(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
		{
			return board[1][i];
		}
	}
	for (int i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
		{
			return board[i][0];
		}
	}
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')    //主对角线三个棋子一样
	{
		return board[1][1];
	}
	else if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')      //辅对角线三个棋子一样
	{
		return board[1][1];
	}
	else if (is_full(board, row, col))
	{
		return 'Q';
	}
	else
	{
		return 'C';
	}
}

注意:

在定义is_full函数的时候,使用了static关键字

static修饰函数,该函数只能在本文件内被访问;不能在外部其他文件直接访问,可以被间接访问

可以理解为这是我们内部的一个函数,不需要被外界看到,所以用static修饰

可以将我们的函数很好的保护起来

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

三子棋(人机对战) 的相关文章

  • linux 内核同步互斥技术之cache 伪共享和隐含内存屏障

    隐含内存屏障 内核的有些函数隐含内存屏障 1 获取和释放函数 2 中断禁止函数 1 获取和释放函数 获取 acquire 函数包括如下 1 获取锁的函数 锁包括自旋锁 读写自旋锁 互斥锁 信号量和读写信号量 2 smp load acqui
  • linux ARM64 处理器内存屏障

    一 内存类型 ARMv8架构将系统中所有的内存 按照它们的特性 划分成两种 即普通内存和设备内存 并且它们是互斥的 也就是说系统中的某段内存要么是普通内存 要么是设备内存 不能都是 1 普通内存 Normal Memory 普通内存的特性是
  • 串口流控(CTS/RTS)使用详解

    1 流控概念 在两个设备正常通信时 由于处理速度不同 就存在这样一个问题 有的快 有的慢 在某些情况下 就可能导致丢失数据的情况 如台式机与单片机之间的通讯 接收端数据缓冲区已满 则此时继续发送来的数据就会丢失 流控制能解决这个问题 当接收
  • 如何在 shell 脚本中检测 BSD 与 GNU 版本的日期

    我正在编写一个需要执行一些日期字符串操作的 shell 脚本 该脚本应该跨尽可能多的 nix 变体工作 因此我需要处理机器可能具有 BSD 或 GNU 版本的 date 的情况 测试操作系统类型的最优雅的方法是什么 以便我可以发送正确的日期
  • PATH_MAX和NAME_MAX之间是什么关系,如何获取?

    In limits h 并且在 POSIX 联机帮助页的各个地方都引用了PATH MAX and NAME MAX 这些相互之间有何关系 他们的官方文档在哪里 如何在 C Python 和 GNU shell 环境的运行时和 相关 编译时获
  • GNU sed - 查找或替换空格或新行。为什么这不起作用? v3.02 与 v4.2

    C crp cnp gt sed V GNU sed version 3 02 Copyright C 1998 Free Software Foundation Inc C crp cnp gt type f f a a a a a a
  • BMS开发之面向对象思想(adbms1818)

    借鉴adbms1818的底层驱动代码 前言 adbms1818的主要用途就是不同种类的寄存器里面存储不同的数据 程序员需要通过特定的协议往寄存器里面写入或者读出数据 1 定义一个结构体 里面存储了adbms1818的所有寄存器的信息 然后我
  • 如何让配置脚本检查依赖关系

    我使用 autoconf 生成了一个配置脚本来构建我的项目 除非我没有安装一些所需的库 否则它工作正常 当缺少某些文件时 Make 返回错误 但我认为应该由配置脚本实际检查它 所以我的问题是 如何修改 autoconf 生成的脚本来寻找依赖
  • 【C语言】数组

    一维数组的创建和初始化 数组是一组相同类型元素的集合 数组的创建 数组的创建方式 type t arr name const n type t 是指数组的元素类型 const n 是一个常量表达式 用来指定数组的大小 数组创建的实例 数组创
  • 牛客字符串

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 例如 随着人工智能的不断发展 机器学习这门
  • sed 使用:预期上下文地址

    我用sedmacOS 上的命令包含以下文本 cat pets txt This is my cat my cat s name is betty This is your dog your dog s name is frank This
  • 华为OD机试真题-API集群负载统计-Java-OD统一考试(C卷)

    题目描述 某个产品的RESTful API集合部署在服务器集群的多个节点上 近期对客户端访问日志进行了采集 需要统计各个API的访问频次 根据热点信息在服务器节点之间做负载均衡 现在需要实现热点信息统计查询功能 RESTful API的由多
  • 用栈实现队列(OJ中报错的处理)

    用栈实现队列 ERROR AddressSanitizer myQueueFree函数中栈的释放处现了问题 没有调用StackDestory而是直接free了 这个是栈初始化时 capacity与malloc申请的空间大小没有匹配 请你仅使
  • grep 是如何工作的?

    我想了解如何grep works 当我说grep hello does grep获取 2 个参数 1 要搜索的字符串 即 hello 和 2 路径 或者shell是否转换 变成某事grep可以理解 哪里可以得到源代码grep 我遇到了这个G
  • 在 Linux 上获取机器 ID 的最佳方法?

    获取唯一机器 ID 的最佳实践方法是什么GNU Linux for i386建筑学 除了这个还有什么好的办法吗mac地址 根据您的内核 DMI 信息可能可以通过 sysfs 获得 尝试一下 cat sys class dmi id boar
  • grep 正则表达式 空白行为

    我有一个文本文件 其中包含以下内容 12 34 EUR 5 67 EUR EUR 之前有一个空格 我忽略了 0 XX EUR 我试过 grep 1 9 0 9 0 9 2 sEUR gt didn t match grep 1 9 0 9
  • 链接器输入文件未使用的 c++ g++ make 文件

    我无法弄清楚是什么导致了我在制作项目时不断遇到的错误 i686 apple darwin11 llvm g 4 2 lncurses linker input file unused because linking not done 我的
  • 比较 timespec 值

    比较两个 timespec 值以查看哪个先发生的最佳方法是什么 下面这句话有什么问题吗 bool BThenA timespec a timespec b Returns true if b happened first b will be
  • 无法在 R 中安装插入符号包(在我的 Linux 机器中)

    我在尝试在 R 中安装插入符号包时遇到以下错误 g error tmp Rtmp2Tos7n R INSTALL2e6e30153a74 nloptr nlopt 2 4 2 lib libnlopt cxx a No such file
  • Makefile 和通配符

    好吧 这是我当前的 makefile 设置 有一些文件名为public01 c public02 c等等 我正在尝试使用以下方法为每个人制作目标文件public o带有通配符的标签 public o public c hashtable h

随机推荐

  • vue常用标签

    一 内容绑定 1 v text 会替换掉html的内容 eg p p 2 插值表达式占位内容 放在html中 eg p username p 3 v html 可将html内容渲染到页面 v text和 不支持 eg div div con
  • 用于通过声波捕获显示视觉,触觉和音频的全息显示(A volumetric display for visual, tactile and audio presentation using acous)

    Ryuji Hirayama Diego Martinez Plasencia Nobuyuki Masuda Sriram Subramanian 2019年1月31日接收 2019年8月15日收录 2019年11月13日网上公开 摘要
  • java token redis生成算法_java秒杀系列(1)- 秒杀方案总体思路

    前言 首先 要明确一点 高并发场景下系统的瓶颈出现在哪里 其实主要就是数据库 那么就要想办法为数据库做层层防护 减轻数据库的压力 一 简单图示 我用一个比较简单直观的图来表达大概的处理思路 二 生产环境中秒杀抢购的解决方案 1 前端 1 动
  • Qt自定义滑动条

    最近要用到滑动条 Qt自带的QSlider虽然能满足需求 但是操作起来有很多不舒服的地方 于是在它的基础上改了改 分享给大家使用 先放效果图 在QSlider的基础上 改变了样式 绘制了刻度 增加了取整功能 只需要微调就能适应各种需求 头文
  • JavaWeb12(实现基础分页&模糊查询的分页)

    目录 一 效果预览 编辑 二 实现基本分页 2 1 分页sql 每页3条 取第二页 由于伪列不能作用与大于符号也不能作用于between and 因此需要将伪列 gt 名列 2 2 万能公式 2 3 首页 上一页 下一页实现 前端代码 2
  • [论文阅读笔记36]CASREL代码运行记录

    论文阅读笔记33 CASREL 基于标注与bert的实体与关系抽取 https blog csdn net ld326 article details 116465089 总的来说 文档都还是写得很好的 按文档 readme md 来就行
  • 必备技能22: 安装VISIO时,出现64、32版本冲突

    问题描述 安装visio时 遇到如下错误 安装错误 无法安装 64 位版本的 Office 因为在您的 PC 上找到了以下 32 位程序 Office 16 Click to Run Extensibility Component 请卸载所
  • Python制作【大麦网】抢票程序,看演唱会再也不怕没票了

    前言 大麦网 是中国综合类现场娱乐票务营销平台 业务覆盖演唱会 话剧 音乐剧 体育赛事等领域 但是因为票数有限 还有黄牛们不能丢了饭碗 所以导致了 很多人都抢不到票 那么 今天带大家用Python来制作一个自动抢票的脚本小程序 知识点 面向
  • linux安装mysql5.7

    Linux下安装Mysql5 7 超详细完整教程 以及云mysql连接 linux mysql5 7 清香可口柑的博客 CSDN博客 grant all privileges on to root identified by 123456
  • 无人机数据集调研

    最近在研究无人机检测相关领域的内容 因此对目前开源的无人机数据集做一个整理 目录 无人机数据集 一 VisDrone2019 二 UAVDT 无人机数据集 一 VisDrone2019 数据集下载地址 比赛官网 VisDrone2019数据
  • 1分钟免费开通IDaaS云服务

    2020 Zero trust 零信任 持续火热 零信任不仅仅是技术 更是理念的转变 会成为未来十年主流的网络安全架构 企业如何快速构建自己的零信任 SDP防护架构 背景 国内现状 大多数企业尚未建立企业的身份认证和授权中心 能够管理企业内
  • 获取 gps信息_ROS传感器之GPS简介

    一 传感器分类 在自动驾驶或者机器人领域 传感器的使用按照测量对象划分 可分为两大类 一类是测量自身状态 另一类测量环境状态 前者主要包含GPS IMU和编码器 后者主要有激光雷达 毫米波雷达和相机 这里的状态主要是指位置和速度 有些传感器
  • android 登陆界面

    LoginActivity java package com example ruian import android app Activity import android app AlertDialog import android c
  • 用python将结果存进csv文件中

    def writeCsv File species row File species out open data test csv a newline csv writer csv writer out dialect excel csv
  • 代码走查和代码审查_这是经过1000多次代码审查后我学到的东西

    代码走查和代码审查 这个故事最初发表在我的博客上 如果您对这种内容感兴趣 请随时签出并订阅 在过去的三年中 我已经审查了1000多个请求 合并 请求 在那段时间里 我学到了很多东西 主要是关于如何不审阅代码 如何减轻过程的痛苦 使高质量的代
  • python字典中的值只能是字符串类型_python字典key不能是可以是啥类型

    python中字典的key不能是可变类型 字典可存储任意类型对象 其中值可以取任何数据类型 但键必须是不可变的 如字符串 数字或元组 语法格式 d key1 value1 key2 value2 字典是另一种可变容器模型 且可存储任意类型对
  • 神经搜索有多能?

    原文 Alex C G 译文 Piper Hu 本文阅读时长约为5分钟 神经搜索 是数据处理上非常新颖的一个话题 也是Jina AI目前着重关注的方向 可是到底神经搜索是什么 它能解决什么问题 与现在开发者们使用的搜索系统搭建又有什么不一样
  • javaScript节流与防抖

    一 节流 throttle 用来实现阻止在短时间内重复多次触发同一个函数 主要用途 防止使用脚本循环触发网络请求的函数的恶意行为 确保请求的真实性 当然也包括其他阻止高频触发行为的应用 实现原理图 代码实现 1 节流函数 2 functio
  • python中xpath解析网页html文档

    1 首先安装xpath解析工具第三方库 pip install i https pypi tuna tsinghua edu cn simple lxml 2 选取节点 选取未知节点 选取若干路径 举例说明 谓语用来查找某个特定的节点或者包
  • 三子棋(人机对战)

    目录 整体思路 头文件如下 为什么要使用头文件呢 头文件的使用 游戏主函数如下 功能实现如下 注意 整体思路 1 创建一个二维数组 2 初始化二维数组 3 打印棋盘 4 玩家下棋且打印棋盘 5 电脑下棋且打印棋盘 6 判断输赢 头文件如下