用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';
}
相关文章:
用c语言实现简易三子棋
本篇适用于C语言初学者。 目录 完整代码: 分步介绍: 声明: 代码主体部分: 模块功能实现: 完整代码: #include<stdio.h> #include <stdlib.h> #include <time.h>#define ROW 3 #d…...
2024年华为OD机试真题-执行时长-Python-OD统一考试(C卷D卷)
2024年OD统一考试(D卷)完整题库:华为OD机试2024年最新题库(Python、JAVA、C++合集) 题目描述: 为了充分发挥GPU算力,需要尽可能多的将任务交给GPU执行,现在有一个任务数组,数组元素表示在这1秒内新增的任务个数且每秒都有新增任务,假设GPU最多一次执行n个任务,一次执…...
对未知程序所创建的 PDF 文档的折叠书签层级全展开导致丢签的一种解决方法
对需要经常查阅、或连续长时间阅读的带有折叠书签的 PDF 文档展开书签层级,提高阅览导航快捷是非常有必要的。 下面是两种常用书签层级全展开的方法 1、 FreePic2Pdf 1 - 2 - 3 - 4 - 5 - 6,先提取后回挂 2、PdgCntEditor 载入后,直接保存…...
计算机系统结构之FORK和JOIN
程序语言中用FORK语句派生并行任务,用JOIN语句对多个并发任务汇合。 FORK语句的形式为FORK m,其中m为新领程开始的标号。 JOIN语句的形式为JOIN n,其中n为并发进程的个数。 例1:给定算术表达式ZEA*B*C/DF经并行编译得到如下程序…...
Yocto - virtual/kernel介绍
在 Yocto 项目中,"virtual/kernel "是一个虚拟目标,作为 Linux 内核的抽象层。它是一种以灵活方式指定内核依赖关系的方法,允许实际的内核配方由特定构建中使用的机器配置和层决定。 下面是关于 "virtual/kerne"的含义和…...
如何在 DigitalOcean 云服务器上创建自定义品牌名称服务器
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 介绍 对于托管提供商或转售商来说,拥有自定义的名称服务器可以为客户提供更专业的外观。这消除了要求客户将其域名指向另一…...
心链6----开发主页以及后端数据插入(多线程并发)定时任务
心链 — 伙伴匹配系统 开发主页 信息搜索页修改 主页开发(直接list用户) 在后端controller层编写接口去实现显示推荐页面的功能 /*** 推荐页面* param request* return*/GetMapping("/recommend")public BaseResponse<List<User>&…...
【Linux】日志管理
一、日志进程 1、处理日志的进程 rsyslogd:系统专职日志程序 观察rsyslogd程序: ps aux | grep rsyslogd 2、常见的日志文件 1、系统主日志文件: /var/log/messages 动态查看日志文件尾部: tail -f /var/log/messages 2、安全…...
AI 绘画爆火背后:扩散模型原理及实现
节前,我们星球组织了一场算法岗技术&面试讨论会,邀请了一些互联网大厂朋友、参加社招和校招面试的同学。 针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 合集&#x…...
详解智慧互联网医院系统源码:开发医院小程序教学
本篇文章,笔者将详细介绍智慧互联网医院系统的源码结构,并提供开发医院小程序的详细教学。 一、智慧互联网医院系统概述 智慧互联网医院系统涵盖了预约挂号、在线咨询、电子病历、药品管理等多个模块。 二、系统源码结构解析 智慧互联网医院系统的源码…...
【技术实操】银河高级服务器操作系统实例分享,数据库日志文件属主不对问题分析
1. 问题现象描述 2023 年 06 月 30 日在迁移数据库过程中,遇到数据库 crash 的缺陷,原因如下:在数据库启动时候生成的一组临时文件中,有 owner 为 root 的文件, 文件权限默认为 640, 当数据库需要使用的时…...
函数的创建和调用
自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 提到函数,大家会想到数学函数吧,函数是数学最重要的一个模块,贯穿整个数学学习过程。在Python中,函数…...
数模混合芯片设计中的修调技术是什么?
一、修调目的 数模混合芯片需要修调技术主要是因为以下几个原因: 工艺偏差(Process Variations): 半导体制造过程中存在不可避免的工艺偏差,如晶体管尺寸、阈值电压、电阻和电容值等,这些参数的实际值与…...
MySQL 自定义函数(实验报告)
一、实验名称: 自定义函数 二、实验日期: 2024年 6 月 1 日 三、实验目的: 掌握MySQL自定义函数的创建及调用; 四、实验用的仪器和材料: 硬件:PC电脑一台; 配置:内存&#…...
一次职业院校漏洞挖掘
这个是之前挖掘到的漏洞,目前网站进行重构做了全新的改版,但是这个漏洞特别经典,拿出来进行分享。看到src上面的很多敏感信息泄露,所以自己也想找一个敏感信息泄露,官网如图: 发现在下面有一个数字校园入口…...
洪师傅代驾系统开发 支持公众号H5小程序APP 后端Java源码
代驾流程图 业务流程图 管理端设置 1、首页装修 2、师傅奖励配置 师傅注册后,可享受后台设置的新师傅可得的额外奖励; 例:A注册了师傅,新人奖励可享受3天,第一天的第一笔订单完成后可得正常佣金佣金*奖励比例 完成第二笔/第三笔后依次可得正常佣金佣金*奖励比例 完成的第四…...
View->Bitmap缩放到自定义ViewGroup的任意区域(Matrix方式绘制Bitmap)
Bitmap缩放和平移 加载一张Bitmap可能为宽高相同的正方形,也可能为宽高不同的矩形缩放方向可以为中心缩放,左上角缩放,右上角缩放,左下角缩放,右下角缩放Bitmap中心缩放,包含了缩放和平移两个操作…...
Centos 7部署NTP
介绍 NTP是Network Time Protocol(网络时间协议)的简称,它是用来通过互联网或局域网将计算机时钟同步到世界协调时间(UTC)的协议。 安装 # yum安装 yum install -y ntp# 离线安装 #下载地址:https://mir…...
【前缀和】42. 接雨水
本文涉及知识点 C算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 LeetCode42. 接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入&am…...
我的名字叫大数据
第1章 大家好,我叫大数据 1.1 我的家族传统:从我小小的祖先到壮大的我 1.1.1 最初的我:原始部落里的计数石头 大家好,我是你们人类文明的“老朋友”——大数据。你们知道吗?在我还没有变成你们手机、电脑里飞速跑动的那些数字前,我最初的模样可是一块块“计数石头”。…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
