C语言实现三子棋游戏(详解)
目录
引言:
1.游戏规则:
2.实现步骤:
2.1实现菜单:
2.2创建棋盘并初始化:
2.3绘制棋盘:
2.4玩家落子:
2.5电脑落子:
2.6判断胜负:
3.源码:
结语:
引言:
《三子棋》是一款古老的民间传统游戏,又被称为OOXX棋、黑白棋,井字棋,九宫棋等。游戏分为双方对战,双方依次在九宫格棋盘上摆放棋子,率先将自己的三个棋子连成一条线的一方则为胜利者。
1.游戏规则:
三子棋是一种两人对战的游戏,棋盘是一个3x3的方格矩阵。玩家和电脑轮流在空白的方格中落子,一方执X,另一方执O。当玩家在横向、纵向或对角线上连成三个相同的棋子时,该玩家获胜,反之,电脑获胜。如果棋盘填满而无法连成三子,游戏结束,双方平局。
2.实现步骤:
想要完整的实现三子棋代码,我们首先必须在脑海里构建出一个大致的框架,然后再去一步步实现它里边的细节。
- 实现进入游戏的菜单界面
- 创建棋盘并初始化
- 绘制棋盘(打印棋盘)
- 玩家落子
- 电脑落子
- 判断胜负
2.1实现菜单:
void menu()
{printf("*******************\n");printf("**** 1.play ****\n");printf("**** 0.exit ****\n");printf("*******************\n");
}
2.2创建棋盘并初始化:
首先,我们需要创建一个3x3的二维数组来表示棋盘,但考虑到这样不灵活,那么我们可以使用宏定义的方式来使我们的代码变得更加易于维护。
#define ROW 3//行
#define COL 3//列
void InitBoard(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){board[i][j] = ' ';}}
}
2.3绘制棋盘:
最终呈现在玩家眼里的棋盘应该是由分割线和空位置组成的。
void DisplayBoard(char board[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 ", board[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");}
}
2.4玩家落子:
当玩家下棋时,他眼里的坐标只有1,2,3行,而在计算机中,数组是通过下标访问的,是从0开始的,所以在写代码时应该将玩家输入的坐标减去1才合适。还应该对玩家输入的坐标进行判断看有没有越界访问,以及判断棋子有没有被占用。
void PlayerMove(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 >= 1 && y <= col){if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = 'X';break;}else{printf("坐标被占用,请重新输入!\n");}}elseprintf("坐标非法,请重新输入!\n");}
}
2.5电脑落子:
利用rand函数生成的随机数再模个行和列输入坐标实现落子,电脑落子也要判断落子点是否被占用。
void ComputerMove(char board[ROW][COL], int row, int col)
{printf("电脑下棋\n");int x = 0;int y = 0;while (1){x = rand() % row;y = rand() % col;if (board[x][y] == ' '){board[x][y] = 'O';break;}}
}
2.6判断胜负:
🎈我们规定:
- 玩家赢返回 "X"
- 电脑赢返回 "O"
- 平局返回 "Q"
- 以上三种情况都不是即游戏继续返回 "C"
//未分出胜负并且所有元素都不为空格则为平局
static int IsFull(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] == ' '){return 0;}}}return 1;
}//玩家赢 X
//电脑赢 O
//平局 Q
//游戏继续 C
char IsWin(char board[ROW][COL], int row, int col)
{int i = 0;//判断行for (i = 0; i < row; i++){if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' '){return board[i][1];}}//判断列for (i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' '){return board[1][i];}}//判断对角线if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' '){return board[1][1];}if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' '){return board[1][1];}//判断平局if (IsFull(board, row, col)){return 'Q';}return 'C';
}
3.源码:
为了让代码逻辑更清晰,更易于调试,我们可以将整个三子棋代码分为三个文件。
- 主函数(main.c):实现游戏的进入和退出功能。
- 游戏实现函数(game.c):思考游戏的逻辑并构建函数,通过调用一系列函数来实现整个游戏。
- 游戏实现头文件(game.h):定义宏并声明游戏实现函数中的各个函数。
🎈(main.c)
#include "game.h"
void menu()
{printf("*******************\n");printf("**** 1.play ****\n");printf("**** 0.exit ****\n");printf("*******************\n");
}void game()
{char ret = 0;char board[ROW][COL];//创建二位数组//开始的时候,数组的内容应该全部是空格InitBoard(board, ROW, COL);//初始化棋盘 DisplayBoard(board, ROW, COL);//打印棋盘//下棋while (1){PlayerMove(board, ROW, COL);DisplayBoard(board, ROW, COL);//判断输赢ret = IsWin(board, ROW, COL);if (ret != 'C'){break;}ComputerMove(board, ROW, COL);DisplayBoard(board, ROW, COL);//判断输赢ret = IsWin(board, ROW, COL);if (ret != 'C'){break;}}if (ret == 'X'){printf("玩家赢!\n");}else if (ret == 'O'){printf("电脑赢!\n");}else{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;
}
🎈(game.c)
#include "game.h"void InitBoard(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){board[i][j] = ' ';}}
}void DisplayBoard(char board[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 ", board[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 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 >= 1 && y <= col){if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = 'X';break;}else{printf("坐标被占用,请重新输入!\n");}}elseprintf("坐标非法,请重新输入!\n");}
}void ComputerMove(char board[ROW][COL], int row, int col)
{printf("电脑下棋\n");int x = 0;int y = 0;while (1){x = rand() % row;y = rand() % col;if (board[x][y] == ' '){board[x][y] = 'O';break;}}
}static int IsFull(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] == ' '){return 0;}}}return 1;
}//玩家赢 返回"X"
//电脑赢 返回"O"
//平局 返回"Q"
//游戏继续 返回"C"
char IsWin(char board[ROW][COL], int row, int col)
{int i = 0;//判断行for (i = 0; i < row; i++){if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' '){return board[i][1];}}//判断列for (i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' '){return board[1][i];}}//判断对角线if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' '){return board[1][1];}if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' '){return board[1][1];}//判断平局if (IsFull(board, row, col)){return 'Q';}return 'C';
}
🎈(game.h)
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>#define ROW 3//行
#define COL 3//列//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);//判断输赢
char IsWin(char board[ROW][COL], int row, int col);
结语:
通过本篇博客,我们学习了如何使用C语言实现三子棋游戏。通过实现菜单、创建棋盘并初始化棋盘、绘制棋盘、玩家落子、电脑落子、判断胜负等步骤,我们成功完成了这个有趣的项目。希望本篇博客对初学者和有一定编程经验的佬佬都能有所帮助,最后祝大家玩得愉快呀!
相关文章:

C语言实现三子棋游戏(详解)
目录 引言: 1.游戏规则: 2.实现步骤: 2.1实现菜单: 2.2创建棋盘并初始化: 2.3绘制棋盘: 2.4玩家落子: 2.5电脑落子: 2.6判断胜负: 3.源码: 结语&…...

javaee之黑马乐优商城3
异步查询工具axios(儿所以时) vue官方推荐的ajax请求框架 新增品牌页面 如何找到上面这个页面 下面这个页面里面的新增商品弹窗 上面就是请求路径与请求方式 那么请求参数是什么? brand对象,外加商品分类的id数组cids (这里其实不止就是添加…...
Pytorch intermediate(二) ResNet
实现了残差网络,残差网络结构。代码比之前复杂很多 conv3x3:将输入数据进行一次卷积,将数据转换成为,残差块需要的shape大小 ResidualBlock:残差块,也是所谓的恒等块。为什么被称为恒等块,大概…...

【2023集创赛】加速科技杯作品:高光响应的二硫化铼光电探测器
本文为2023年第七届全国大学生集成电路创新创业大赛(“集创赛”)加速科技杯西北赛区二等奖作品分享,参加极术社区的【有奖征集】分享你的2023集创赛作品,秀出作品风采,分享2023集创赛作品扩大影响力,更有丰…...

编写postcss插件,全局css文件px转vw
跟目录下创建plugins文件夹,创建postcss-px-to-viewport.ts文件 文件内代码: // postcss 的插件 vite内置了postCss插件 无需安装 import { Plugin } from postcss;interface Options {viewportWidth: number }const Options {viewportWidth: 375, // …...

精品SpringCloud的B2C模式在线学习网微服务分布式
《[含文档PPT源码等]精品基于SpringCloud实现的B2C模式在线学习网站-微服务-分布式》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等 软件开发环境及开发工具: 开发语言:Java 框架:springcloud JDK版本…...

解决vue项目导出当前页Table为Excel
解决vue项目中导出当前页表格为Excel表格的方案 用到的技术: Vue2Element-uifile-saverxlsx 1、创建vue项目,安装element-ui 2、创建一个组件,组件内放入表格,和导出按钮 <template><div><!-- 导出的按钮 -->…...

C++设计模式_04_Strategy 策略模式
接上篇,本篇将会介绍C设计模式中的Strategy 策略模式,和上篇模板方法Template Method一样,仍属于“组件协作”模式,它与Template Method有着异曲同工之妙。 文章目录 1. 动机( Motivation)2. 代码演示Stra…...
目标检测YOLO实战应用案例100讲-基于YOLOv3多模块融合的遥感目标检测(中)
目录 2.2.3 YOLO 2.3 目标检测算法分析 2.3.1 目标检测结果评价指标...
element 表格fixed列高度无法100%
下文提到的滚动条皆为横向滚动条错误方法(旧方法,点击查看旧博客) 一下代码虽然能解决fixed列高度无法100%问题,但是会出现fixed列下面的滚动条无法被点击的问题(被fixed列遮挡),所以该方法并不…...

【接口自动化测试】Eolink Apilkit 安装部署,支持 Windows、Mac、Linux 等系统
Eolink Apikit 有三种客户端,可以依据自己的情况选择。三种客户端的数据是共用的,因此可以随时切换不同的客户端。 我们推荐使用新推出的 Apikit PC 客户端,PC 端拥有线上产品所有的功能,并且针对本地测试、自动化测试以及使用体…...

解决sass问题:npm ERR! node-sass@9.0.0 postinstall: `node scripts/build.js`
目录 一、遇到问题 解决办法 二、 再次遇到问题 解决办法 题外话 一、遇到问题 1.运行这个项目的适合,遇到了没有sass的问题 解决办法 然后就用命令下载sass npm install node-sass 二、 再次遇到问题 2.下载sass的时候又发现了一个这样的问题 npm ER…...

Python技巧---tqdm库的使用
文章目录 一、tqdm基本知识二、在pytorch中使用tqdm 提示:以下是本篇文章正文内容,下面案例可供参考 一、tqdm基本知识 “tqdm” 是一个 Python 库,用于在命令行界面中创建进度条。 基本使用如下: from tqdm import tqdm impor…...

linux-线程条件变量(cond)
概述 与互斥锁不同,条件变量是用来等待而不是用来上锁的。条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。通常条件变量和互斥锁同时使用 。 条件变量使我们可以睡眠等待某种条件出现。条件变量是利用线程间共享的全局变量进行同步的一种机制&a…...
面试算法6:排序数组中的两个数字之和
题目 输入一个递增排序的数组和一个值k,请问如何在数组中找出两个和为k的数字并返回它们的下标?假设数组中存在且只存在一对符合条件的数字,同时一个数字不能使用两次。例如,输入数组[1,2,4,6&…...

【智能家居-大模型】构建未来,聆思大模型智能家居交互解决方案正式发布
LISTENAI 近日,国内11家大模型陆续通过《生成式人工智能服务管理暂行办法》备案,多家大模型产品已正式开放,激发了新一轮大模型热潮。大模型在自然语言理解方面的巨大突破,实现了认知智能的技术跃迁,带来了时代的智慧…...

通讯网关软件002——利用CommGate X2HTTP-U实现HTTP访问OPC UA Server
本文介绍利用CommGate X2HTTP-U实现HTTP访问OPC UA Server。CommGate X2HTTP是宁波科安网信开发的网关软件,软件可以登录到网信智汇(wangxinzhihui.com)下载。 【案例】如下图所示,实现上位机通过HTTP来获取OPC UA Server的数据。 【解决方案】设置网关机…...

模拟经营类游戏是怎么开发的?
模拟经营类游戏开发是一个充满挑战但也充满乐趣的领域。下面是一些步骤和关键考虑因素,可以帮助您开始开发自己的模拟经营游戏: 明确游戏概念: 确定游戏开发的主题和类型,例如城市建设、农场经营、餐厅经营等。 制定一个引人入胜…...

基于JAVA+SSM+微信小程序+MySql的图书捐赠管理系统设计与实现
✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目背景介绍: 在当今社会࿰…...

软件设计模式系列之六——单例模式
1 模式的定义 单例模式(Singleton Pattern)是一种常见的创建型设计模式,其主要目的是确保一个类只有一个实例,并提供一个全局访问点来获取该实例。这意味着无论何时何地,只要需要该类的实例,都会返回同一个…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...