用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 最初的我:原始部落里的计数石头 大家好,我是你们人类文明的“老朋友”——大数据。你们知道吗?在我还没有变成你们手机、电脑里飞速跑动的那些数字前,我最初的模样可是一块块“计数石头”。…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...