用c语言实现简易三子棋

本篇适用于C语言初学者。

目录

完整代码: 

分步介绍:

声明:

代码主体部分:

模块功能实现:


完整代码: 

#include<stdio.h>
#include <stdlib.h>
#include <time.h>#define ROW 3
#define COL 3void InitBorad(char borad[ROW][COL], int row, int col);void DisplayBorad(char borad[ROW][COL], int row, int col);void PlayerMove(char borad[ROW][COL], int row, int col);void ComputerMove(char borad[ROW][COL], int row, int col);char IsWin(char borad[ROW][COL], int row, int col);void InitBorad(char borad[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){borad[i][j] = ' ';}}
}void DisplayBorad(char borad[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){printf(" %c ", borad[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 borad[ROW][COL], int row, int col)
{int x = 0;int y = 0;while (1){printf("玩家下棋:>");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){if (borad[x - 1][y - 1] == ' '){borad[x - 1][y - 1] = '*';break;}else{printf("该位置已被占有,请重新选择!\n");}}else{printf("输入错误,请重新选择!\n");}}
}void ComputerMove(char borad[ROW][COL], int row, int col)
{printf("电脑下棋:>\n");while (1){int x = rand() % row;int y = rand() % col;if (borad[x][y] == ' '){borad[x][y] = '#';break;}}
}//'*'玩家赢
//'#'电脑赢
//'C'继续游戏
//'Q'平局
//char IsWin(char borad[ROW][COL], int row, int col)
//{
//	int i = 0;
//	for (i = 0; i < row; i++)
//	{
//		if (borad[i][0] == borad[i][1] && borad[i][1] == borad[i][2] && borad[i][0] != ' ')
//			return borad[i][0];
//	}
//	for (i = 0; i < col; i++)
//	{
//		if (borad[0][i] == borad[1][i] && borad[1][i] == borad[2][i] && borad[0][i] != ' ')
//			return borad[0][i];
//	}
//	if (borad[0][0] == borad[1][1] && borad[1][1] == borad[2][2] && borad[0][0] != ' ')
//		return borad[0][0];
//	if (borad[0][2] == borad[1][1] && borad[1][1] == borad[2][0] && borad[0][2] != ' ')
//		return borad[0][2];
//	for (i = 0; i < row; i++)
//	{
//		int j = 0;
//		for (j = 0; j < col; j++)
//		{
//			if (borad[i][j] == ' ')
//				return 'C';
//		}
//	}
//	return 'Q';
//}//判断优化
char IsWin(char borad[ROW][COL], int row, int col)
{int i = 0;int flag = 1;//行for (i = 0; i < row; i++){flag = 1;int n = 0;if (borad[i][0] != ' '){while (n < row - 1){if (borad[i][n] != borad[i][n + 1]){flag = 0;break;}n++;}if (flag)return borad[i][0];}}//列for (i = 0; i < col; i++){flag = 1;int n = 0;if (borad[0][i] != ' '){while (n < col - 1){if (borad[n][i] != borad[n + 1][i]){flag = 0;break;}n++;}if (flag)return borad[0][i];}}//左对角线if (borad[0][0] != ' '){flag = 1;int n = 0;while (n < row - 1){if (borad[n][n] != borad[n + 1][n + 1]){flag = 0;break;}n++;}if (flag)return borad[0][0];}//右对角线int r = 0;int c = col - 1;if (borad[r][c] != ' '){flag = 1;while (r < row - 1){if (borad[r][c] != borad[r + 1][c - 1]){flag = 0;break;}r++;c--;}if (flag)return borad[r][c];}//继续for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){if (borad[i][j] == ' ')return 'C';}}//平局return 'Q';
}void menu()
{printf("**********************************\n");printf("**********    1.play   ***********\n");printf("**********    0.exit   ***********\n");printf("**********************************\n");
}void game()
{char borad[ROW][COL] = { 0 };char ch = 0;//初始化InitBorad(borad, ROW, COL);//打印棋盘DisplayBorad(borad, ROW, COL);//玩家下棋while (1){//玩家下棋PlayerMove(borad, ROW, COL);DisplayBorad(borad, ROW, COL);//判断ch = IsWin(borad, ROW, COL);if (ch != 'C')break;//电脑下棋ComputerMove(borad, ROW, COL);DisplayBorad(borad, ROW, COL);ch = IsWin(borad, ROW, COL);if (ch != 'C')break;}if (ch == '*')printf("玩家赢!\n");else if (ch == '#')printf("电脑赢!\n");else if (ch == '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;
}

分步介绍:

声明:

#include<stdio.h>
#include <stdlib.h>
#include <time.h>//定义表示符常量分别表示行(ROW)和列(COL)
#define ROW 3
#define COL 3
//初始化棋盘
void InitBorad(char borad[ROW][COL], int row, int col);
//打印棋盘
void DisplayBorad(char borad[ROW][COL], int row, int col);
//玩家移动
void PlayerMove(char borad[ROW][COL], int row, int col);
//电脑移动
void ComputerMove(char borad[ROW][COL], int row, int col);
//判断输赢实现
char IsWin(char borad[ROW][COL], int row, int col);

代码主体部分:

//游戏菜单
void menu()
{printf("**********************************\n");printf("**********    1.play   ***********\n");printf("**********    0.exit   ***********\n");printf("**********************************\n");
}void game()
{//定义一个模拟棋盘的二维数组char borad[ROW][COL] = { 0 };char ch = 0;//调用函数初始化棋盘(二维数组)InitBorad(borad, ROW, COL);//调用函数打印棋盘(二维数组)DisplayBorad(borad, ROW, COL);while (1){//调用函数玩家下棋PlayerMove(borad, ROW, COL);DisplayBorad(borad, ROW, COL);//进行输赢判断ch = IsWin(borad, ROW, COL);//C表示继续游戏                        if (ch != 'C')break;//调用函数电脑下棋ComputerMove(borad, ROW, COL);//进行输赢判断DisplayBorad(borad, ROW, COL);ch = IsWin(borad, ROW, COL);if (ch != 'C')break;}// * 表示玩家赢if (ch == '*')printf("玩家赢!\n");// # 表示电脑赢else if (ch == '#')printf("电脑赢!\n");//Q表示平局else if (ch == 'Q')printf("平局!\n");
}
//主函数(程序入口)
int main()
{//存储选择的变量int input = 0;//使用time()库(time.h)函数和srand()库(stdlib.h)函数确定随机数生成起点,将time()返回值强制转换成无符号整型(unsigned int)。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;
}

模块功能实现:

//利用嵌套循环实现对棋盘(二维数组)的初始化,初始化为空格
void InitBorad(char borad[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){borad[i][j] = ' ';}}
}
//利用嵌套循环实现对棋盘的打印
void DisplayBorad(char borad[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){printf(" %c ", borad[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 borad[ROW][COL], int row, int col)
{int x = 0;int y = 0;while (1){printf("玩家下棋:>");//输入想要下棋地方的坐标:行从1开始,列从1开始(数组下标从0开始,因此需要对输入数据减1)scanf("%d %d", &x, &y);//对输入信息所对应的坐标进行判断和处理if (x >= 1 && x <= row && y >= 1 && y <= col){if (borad[x - 1][y - 1] == ' '){borad[x - 1][y - 1] = '*';break;}else{printf("该位置已被占有,请重新选择!\n");}}else{printf("输入错误,请重新选择!\n");}}
}
//电脑下棋实现细节
void ComputerMove(char borad[ROW][COL], int row, int col)
{printf("电脑下棋:>\n");while (1){//代码主体部分已通过srand()设置随机数生成起点,此处调用rand()库(stdlib.h)函数生成两个随机数,分别作为二维数组的行下标和列下标int x = rand() % row;int y = rand() % col;//对坐标进行判断和处理if (borad[x][y] == ' '){borad[x][y] = '#';break;}}
}//'*'玩家赢
//'#'电脑赢
//'C'继续游戏
//'Q'平局
//此注释内容为原始判断方法实现内容
//char IsWin(char borad[ROW][COL], int row, int col)
//{
//	int i = 0;
//	for (i = 0; i < row; i++)
//	{
//		if (borad[i][0] == borad[i][1] && borad[i][1] == borad[i][2] && borad[i][0] != ' ')
//			return borad[i][0];
//	}
//	for (i = 0; i < col; i++)
//	{
//		if (borad[0][i] == borad[1][i] && borad[1][i] == borad[2][i] && borad[0][i] != ' ')
//			return borad[0][i];
//	}
//	if (borad[0][0] == borad[1][1] && borad[1][1] == borad[2][2] && borad[0][0] != ' ')
//		return borad[0][0];
//	if (borad[0][2] == borad[1][1] && borad[1][1] == borad[2][0] && borad[0][2] != ' ')
//		return borad[0][2];
//	for (i = 0; i < row; i++)
//	{
//		int j = 0;
//		for (j = 0; j < col; j++)
//		{
//			if (borad[i][j] == ' ')
//				return 'C';
//		}
//	}
//	return 'Q';
//}//判断优化
//'*'玩家赢
//'#'电脑赢
//'C'继续游戏
//'Q'平局
char IsWin(char borad[ROW][COL], int row, int col)
{int i = 0;int flag = 1;//行的判断实现//循环遍历行for (i = 0; i < row; i++){//作为实现判断依据的变量,假设游戏已经结束。flag = 1;//作为遍历一行内容的变量int n = 0;if (borad[i][0] != ' '){while (n < row - 1){if (borad[i][n] != borad[i][n + 1]){//如果本行三个落棋地方不一样,置flag变量为0,表示游戏未结束flag = 0;break;}n++;}//如果游戏结束,返回达成胜利条件坐标所存的字符作为判断玩家or电脑赢的依据if (flag)return borad[i][0];}}//列//具体实现细节同行for (i = 0; i < col; i++){flag = 1;int n = 0;if (borad[0][i] != ' '){while (n < col - 1){if (borad[n][i] != borad[n + 1][i]){flag = 0;break;}n++;}//如果游戏结束,返回达成胜利条件坐标所存的字符作为判断玩家or电脑赢的依据if (flag)return borad[0][i];}}//左对角线//左对角线规律:行加一,列加一。   剩余实现原理同行if (borad[0][0] != ' '){flag = 1;int n = 0;while (n < row - 1){if (borad[n][n] != borad[n + 1][n + 1]){flag = 0;break;}n++;}//如果游戏结束,返回达成胜利条件坐标所存的字符作为判断玩家or电脑赢的依据if (flag)return borad[0][0];}//右对角线//右对角线规律:开始时行为零(数组)列为col - 1,此后行加一,列减一,直至行为数组下标最大值或者列为0。  剩余实现原理同行int r = 0;int c = col - 1;if (borad[r][c] != ' '){flag = 1;while (r < row - 1){if (borad[r][c] != borad[r + 1][c - 1]){flag = 0;break;}r++;c--;}//如果游戏结束,返回达成胜利条件坐标所存的字符作为判断玩家or电脑赢的依据if (flag)return borad[r][c];}//继续//前面判断并未生效,因此说明此时未有赢家诞生,对数组进行遍历,看看是否还有可以落棋的地方来判断是否游戏继续或者平局for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){//如果有 ' ' 证明有地方可以落棋,返回 'C' 表示游戏继续 if (borad[i][j] == ' ')return 'C';}}//平局//如果上述判断均未生效,且遍历数组发现没有可以落棋的坐标返回'Q'表示平局return 'Q';
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

黑马程序员——Spring框架——day03

目录&#xff1a; AOP AOP简介 问题导入AOP简介和作用【理解】AOP的应用场景为什么要学AOPAOP入门案例【重点】 问题导入AOP入门案例思路分析AOP入门案例实现AOP中的核心概念AOP工作流程【理解】 问题导入AOP工作流程AOP核心概念在测试类中验证代理对象AOP切入点表达式 问题导…

【python】爬虫记录每小时金价

数据来源&#xff1a; https://www.cngold.org/img_date/ 因为这个网站是数据随时变动的&#xff0c;用requests、BeautifulSoup的方式解析html的话&#xff0c;数据的位置显示的是“--”&#xff0c;并不能取到数据。 所以采用webdriver访问网站&#xff0c;然后从界面上获取…

webserver服务器从零搭建到上线(十)|⭐️EventLoop类(二)——成员方法详解

首先&#xff0c;在阅读本章之前&#xff0c;我们需要搞清楚为什么EventLoop类这么复杂 其次&#xff0c;我们还需要再强调一次关于mainLoop唤醒subLoop的流程&#xff08;可以看完该类代码后再回顾该流程&#xff09;&#xff1a; 为什么需要唤醒 subLoop? subLoop&#xff0…

C语言 指针——函数指针的典型应用:计算定积分

目录 梯形法计算函数的定积分 函数指针的典型应用 梯形法计算函数的定积分 函数指针的典型应用 用函数指针编写计算任意函数定积分的 通用 函数

15届蓝桥杯决赛,java b组,蒟蒻赛时所写的题思路

这次题的数量是10题&#xff0c;初赛是8题&#xff0c;还多了两题&#xff0c;个人感觉java b组的题意还是比较清晰的&#xff08;不存在读不懂题的情况&#xff09;&#xff0c;但是时间感觉还是不够用&#xff0c;第4题一开始不会写&#xff0c;后面记起来写到结束也没调出来…

Vivado 比特流编译时间获取以及FPGA电压温度获取(实用)

Vivado 比特流编译时间获取以及FPGA电压温度获取 语言 &#xff1a;Verilg HDL 、VHDL EDA工具&#xff1a;ISE、Vivado Vivado 比特流编译时间获取以及FPGA电压温度获取一、引言二、 获取FPGA 当前程序的编译时间verilog中直接调用下面源语2. FPGA电压温度获取&#xff08;1&a…

深度学习中测量GPU性能的方式

在深度学习中&#xff0c;测量GPU性能是至关重要的步骤&#xff0c;尤其是在训练和推理过程中。以下是一些常见的测量GPU性能的方式和详细解释&#xff1a; 1. 运行时间&#xff08;Runtime&#xff09;测量 描述&#xff1a;运行时间测量是评估GPU性能的最直接方式&#xff…

es的总结

es的collapse es的collapse只能针对一个字段聚合&#xff08;针对大数据量去重&#xff09;&#xff0c;如果以age为聚合字段&#xff0c;则会展示第一条数据&#xff0c;如果需要展示多个字段&#xff0c;需要创建新的字段&#xff0c;如下 POST testleh/_update_by_query {…

信息与未来2015真题笔记

[信息与未来 2015] 加数 题目描述 给出一个正整数 n n n&#xff0c;在 n n n 的右边加入 ⌊ n 2 ⌋ \left\lfloor\dfrac n2\right\rfloor ⌊2n​⌋&#xff0c;然后在新数的右边 再加入 ⌊ ⌊ n 2 ⌋ 2 ⌋ \left\lfloor\dfrac{\left\lfloor\dfrac n2\right\rfloor}2\rig…

MyBatis:PostGreSQL的jsonb类型处理器

接前一篇《MyBatis Plus:自定义typeHandler类型处理器》,这里介绍PostGreSQL数据库的jsonb数据类型,以及如何实现jsonb类型处理器。 PostGreSQL:jsonb数据类型 json和jsonb之间的区别 PostgreSQL 提供存储JSON数据的两种类型:json 和 jsonb,两者之间的区别在于: js…

JVM学习-详解类加载器(一)

类加载器 类加载器是JVM执行类加载机制的前提 ClassLoader的作用 ClassLoader是Java的核心组件&#xff0c;所有的Class都是由ClassLoader进行加载的&#xff0c;ClassLoader负责通过各种方式将Class信息的二进制数据流读入JVM内部&#xff0c;转换为一个与目标类型对应的ja…

Java学习【String类详解】

Java学习【String类详解】 String的介绍及定义方式String类型的比较String类型的查找charAt()访问字符indexOf()查找下标 转化和替换数值和字符串转化大小写的转换字符串转数组格式化替换 字符串的拆分和截取split()拆分substring()截取trim()去除两边空格 StringBuilder和Stri…

苏州金龙客车为新疆哪吒车队提供车辆交车

2024年旅游旺季提前到来、时间延长&#xff0c;新疆旅游市场有望延续去年火爆态势。 近期&#xff0c;新疆哪吒运输服务有限公司&#xff08;以下简称“哪吒车队”&#xff09;订购的最新一批10辆苏州金龙海格高端旅游大巴在苏州金龙厂区正式交付。哪吒车队负责人伍亚丽笑容满…

SpringCloud学习笔记万字整理(无广版在博客)

在此感谢黑马程序员的SpringCloud课程 所有笔记、生活分享首发于个人博客 想要获得最佳的阅读体验&#xff08;无广告且清爽&#xff09;&#xff0c;请访问本篇笔记 认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐…

python的元组

元组与列表的区别 元组和列表非常相似。不同之处在于&#xff0c;外观上&#xff1a;列表是被 方括号 包裹起来的&#xff0c;而元组是被 圆括号 包裹起来的。本质上&#xff1a;列表里的元素可修改&#xff0c;元组里的元素是 不可以“增删改” 。 还有一个微妙的地方要注意…

数据分析——Excel篇

1*学习碎片知识点记录&#xff1a; CtrlshiftL 筛选 UV&#xff08;Unique visitor&#xff09;&#xff1a;是指通过互联网访问、浏览这个网页的自然人。访问网站的一台电脑客户端为一个访客。00&#xff1a;00-24&#xff1a;00相同的客户端只被计算一次&#xff0c;一天内…

MK SD NAND(贴片式SD卡)在电力AI模块中的应用案例

近期一位客户&#xff0c;在网上了解到我们SD NAND后联系到我们&#xff0c;经过一系列了解对比后&#xff0c;下单了我们的SD NAND产品。 这位客户是做电力AI模块的&#xff0c;他们的产品主要应用在电力行业。 电力AI模块是集成了人工智能技术的系统&#xff0c;专门设计用于…

fpga控制dsp6657上电启动配置

1 Verilog代码 dspboot_config.v timescale 1ns / 1ps //dsp上电启动配置 module dspboot_config (///时钟和复位input SYS_CLK_50MHz,input SYS_RST_n,//DSP启动配置output DSP_POR,output DSP_RESETFULL,output DSP_RESET,inout [12:…

微信小程序注册流程及APPID,APPSecret获取

1.注册微信小程序 注册链接&#xff1a;公众号 (qq.com) 1.1填写邮箱、密码、验证码 1.2邮箱登录点击邮件中链接激活&#xff0c;即可完成注册 1.3用户信息登记 接下来步骤&#xff0c;将用个人主题类型来进行演示 填写主体登记信息&#xff0c;使用管理员本人微信扫描二维码…

6.11 Libbpf-bootstrap(二,Minimal)

写在前面 minimal是一个很好的入门示例。可以将其视为一个简单的POC,用于尝试BPF功能。它不使用BPF CO-RE,因此可以使用较旧的内核,并且只需包含系统内核头文件即可获取内核类型定义。这不是构建生产就绪应用程序和工具的最佳方法,但对于本地实验来说已经足够了。 一,BP…