用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 最初的我:原始部落里的计数石头 大家好,我是你们人类文明的“老朋友”——大数据。你们知道吗?在我还没有变成你们手机、电脑里飞速跑动的那些数字前,我最初的模样可是一块块“计数石头”。…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
