Rust小练习,编写井字棋
画叉画圈的游戏通常指的是 井字棋(Tic-Tac-Toe),是一个简单的两人游戏,规则如下:
游戏规则
- 棋盘:游戏在一个3x3的方格上进行。
- 玩家:有两个玩家,一个用“X”表示,另一个用“O”表示。
- 目标:玩家轮流在空格中填入自己的标记,目标是先在横向、纵向或斜向上连续放置三个相同的标记。
- 胜利条件:一旦有玩家先形成连续的三个标记,该玩家获胜。如果所有格子都填满且没有玩家获胜,则游戏平局。
示例棋盘
X | O | X
-----------O | X | O
-----------O | | X
在这个示例中,标记“X”在右列形成了三个相同的标记,因此“X”获胜。
游戏策略
虽然井字棋的规则简单,但为了增加趣味性,玩家可以在游戏中使用不同的策略,例如:
- 尽量占据中心位置,以便于创建更多的胜利路径。
- 阻止对手形成连续的三个标记。
井字棋游戏Rust示例实现代码
下面是一个简单的用 Rust 编写的井字棋(Tic-Tac-Toe)游戏示例。这个示例包括基本的游戏逻辑、玩家输入处理以及胜利条件的判断。
use std::io;#[derive(Clone, Copy, PartialEq)]
enum Player {X,O,
}#[derive(Clone)]
struct Game {board: [[Option<Player>; 3]; 3],current_player: Player,
}impl Game {fn new() -> Self {Game {board: [[None; 3]; 3],current_player: Player::X,}}// 打印棋盘fn print_board(&self) {for row in &self.board {for cell in row {let display = match cell {Some(Player::X) => " X ",Some(Player::O) => " O ",None => " . ",};print!("{}", display);}println!();}}// 玩家移动fn player_move(&mut self, row: usize, col: usize) -> bool {if self.board[row][col].is_none() {self.board[row][col] = Some(self.current_player);true} else {false}}// 检查胜利条件fn check_winner(&self) -> Option<Player> {// 检查行for row in 0..3 {if self.board[row][0].is_some()&& self.board[row][0] == self.board[row][1]&& self.board[row][1] == self.board[row][2]{return self.board[row][0];}}// 检查列for col in 0..3 {if self.board[0][col].is_some()&& self.board[0][col] == self.board[1][col]&& self.board[1][col] == self.board[2][col]{return self.board[0][col];}}// 检查对角线if self.board[0][0].is_some()&& self.board[0][0] == self.board[1][1]&& self.board[1][1] == self.board[2][2]{return self.board[0][0];}if self.board[0][2].is_some()&& self.board[0][2] == self.board[1][1]&& self.board[1][1] == self.board[2][0]{return self.board[0][2];}None}// 切换玩家fn switch_player(&mut self) {self.current_player = match self.current_player {Player::X => Player::O,Player::O => Player::X,};}// 检查平局fn is_draw(&self) -> bool {self.board.iter().all(|row| row.iter().all(|&cell| cell.is_some()))}
}fn main() {let mut game = Game::new();loop {game.print_board();println!("玩家 {:?},请输入行和列 (0-2) 用空格分隔:",game.current_player);let mut input = String::new();io::stdin().read_line(&mut input).unwrap();let coords: Vec<usize> = input.trim().split_whitespace().filter_map(|s| s.parse().ok()).collect();if coords.len() != 2 {println!("请输入两个数字!");continue;}let (row, col) = (coords[0], coords[1]);if row >= 3 || col >= 3 {println!("行和列必须在 0 到 2 之间!");continue;}if game.player_move(row, col) {if let Some(winner) = game.check_winner() {game.print_board();println!("玩家 {:?} 获胜!", winner);break;}if game.is_draw() {game.print_board();println!("游戏平局!");break;}game.switch_player();} else {println!("该位置已经被占用,请选择其他位置!");}}
}
代码说明
-
枚举和结构体:
Player
枚举表示玩家,可能是X
或O
。Game
结构体表示游戏状态,包括棋盘和当前玩家。
-
游戏初始化:
new()
方法创建一个新的游戏实例,初始化棋盘为空(None
)并将当前玩家设置为X
。
-
打印棋盘:
print_board()
方法将棋盘的状态输出到终端,未占用的位置显示为.
,玩家的标记分别显示为X
或O
。
-
玩家移动:
player_move()
方法接受行和列参数,并在指定位置放置当前玩家的标记。若该位置已被占用则返回false
。
-
胜利条件检查:
check_winner()
方法检查当前棋盘是否有玩家获胜。它检查每行、每列和两个对角线。
-
切换玩家:
switch_player()
方法在两个玩家之间切换。
-
平局检查:
is_draw()
方法检查棋盘是否已满且没有获胜者,若是则返回true
。
-
主循环:
- 在
main
函数中,程序不断循环,直到游戏结束。 - 每次循环打印当前棋盘,接收玩家输入,进行移动,检查胜利或平局,并切换玩家。
- 在
运行程序
- 依赖:这个程序不需要额外的依赖。
- 编译和运行:使用 Rust 工具链编译和运行程序。确保你已经安装了 Rust 环境。
cargo run
总结
这个简单的井字棋游戏示例展示了如何使用 Rust 进行基本的输入处理、游戏状态管理和胜利条件检查。你可以在此基础上进行扩展,例如增加图形界面、实现更复杂的 AI 玩家或优化游戏体验。希望这个示例对你有帮助!
相关文章:

Rust小练习,编写井字棋
画叉画圈的游戏通常指的是 井字棋(Tic-Tac-Toe),是一个简单的两人游戏,规则如下: 游戏规则 棋盘:游戏在一个3x3的方格上进行。玩家:有两个玩家,一个用“X”表示,另一个…...
RabbitMQ 入门(八)SpringAMQP消息转换器
一、消息转换器 Spring会把你发送的消息序列化为字节发送给MQ,接收消息的时候,还会把字节反序列化为Java对象。 只不过,默认情况下Spring采用的序列化方式是JDK序列化。众所周知,JDK序列化存在下列问题: - 数…...

【C++】一文带你深入理解C++异常机制
⭐️个人主页:小羊 ⭐️所属专栏:C 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 前言一、C语言处理错误的方式二、C异常三、异常的使用3.1 异常的抛出和捕获3.2 异常的重新抛出3.3 异常安全3.4 异常规范 四、自定义异…...
Qt之QObject
简介 QObject是qt中所有对象的基类,也是信号槽的基础 结构 #mermaid-svg-mpp2FHEcRCzUK75S {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-mpp2FHEcRCzUK75S .error-icon{fill:#552222;}#mermaid-svg-…...

鸿蒙到底是不是纯血?到底能不能走向世界?
关注卢松松,会经常给你分享一些我的经验和观点。 2016年5月鸿蒙系统开始立项。 2018年美国开始经济战争,其中一项就是制裁华为,不让华为用安卓。 2019年8月9日华为正式发布鸿蒙系统。问题就出在这里,大家可以仔细看。 安卓一…...

【Android】MVP架构
MVP架构简介 MVP(Model-View-Presenter)是一种常见的软件架构模式,尤其在Android应用开发中被广泛使用。它将应用程序分为三层:Model、View 和 Presenter,以实现职责分离,提高代码的可维护性和可测试性。 …...
Web服务器之Nginx
Nginx(发音为Engine X)是一款开源的高性能HTTP和反向代理服务器,同时也提供了IMAP/POP3/SMTP服务。由伊戈尔赛索耶夫(Igor Sysoev)为俄罗斯访问量第二的Rambler.ru站点开发,Nginx自发布以来,凭借…...

【大模型实战篇】大模型分词算法Unigram及代码示例
1. 算法原理介绍 与 BPE 分词(参考《BPE原理及代码示例》)和 WordPiece 分词(参考《WordPiece原理及代码示例》)不同,Unigram 分词方法【1】是从一个包含足够多字符串或词元的初始集合开始,迭代地删除其中的…...
Dockerfile搭建ELK
使用 Dockerfile 安装 ELK 一、引言 ELK Stack(Elasticsearch, Logstash, Kibana)是一种流行的日志管理和分析解决方案。它允许用户实时搜索、分析和可视化日志数据。通过 Docker,可以方便地部署 ELK ,快速获取一个功能齐全的日…...
在合规的地方怎么用EACO地球链兑换交换价值?
地球链EACO(EarthChain,简称$E)是一种虚拟数字资产。 目前在中国大陆,虚拟资产相关业务活动属于金融活动,包括虚拟资产的交易、兑换等操作,因此应该谨慎去寻求如何用它来交换价值。 虚拟资产交易炒作活动&…...

VS无法安装Win10SDK_10.0.2200,快捷方法
Visual Studio无法安装Win10SDK_10.0.2200,我在安装VS2019、2022提示,软件就不能编译。 因为之前安装过VS软件,重新安装软件提示“无法安装”。 原因 之前安装在D盘,现在没有D盘了 说明 因为电脑第一次安装VS,会自动安…...
github多个账号配置多个SSH秘钥
背景 对于有多个github账号的同学,需要配置多个ssh秘钥分别管理多个账号。 方法 1、生成多个SSH秘钥 # 为第一个 GitHub 账号生成密钥 ssh-keygen -t ed25519 -C "your_email_1example.com" -f ~/.ssh/id_ed25519_github_work# 为第二个 GitHub 账号生…...
静态/动态代理详解,一次性看完再也不会搞不清!
代理官方原文翻译: 给其他对象提供一个代理或者占位符,来控制对这个对象的访问。 代理最核心的思想: 在客户端和目标对象之间创建一个“中介”,用于保护目标对象和增强目标对象 静态代理: 该代理对象需要我们手动…...

Webserver(2)GCC
目录 安装GCCVScode远程连接到虚拟机编写代码gcc编译过程gcc与g的区别Xftp连接虚拟机上传文件 安装GCC sudo apt install gcc g查看版本是7.5 touch test.c创建代码 但是在虚拟机中写代码很不方便 VScode远程连接到虚拟机编写代码 gcc test.c -o app在虚拟机中用gcc编译的…...

mac电脑设置chrome浏览器语言切换为日语英语等不生效问题
在chrome中设置了语言,并且已经置顶了,但是不生效,在windows上直接有设置当前语言为chrome显示语言,但是mac上没有。 解决办法 在系统里面有一个单独给chrome设置语言的: 单独给它设定成指定的语言,然后重…...

Python中的人工智能框架与实例
在人工智能(AI)领域,Python因其简洁的语法、丰富的库和强大的社区支持,成为了最受欢迎的编程语言之一。本文将详细介绍Python中的人工智能框架,并通过具体实例展示如何使用这些框架来实现不同的人工智能应用。 一、Python中的人工智能框架 …...

论文阅读(二十六):Dual Attention Network for Scene Segmentation
文章目录 1.Introduction3.DANet3.1Position Attention Module3.2Channel Attention Module 论文:Dual Attention Network for Scene Segmentation 论文链接:Dual Attention Network for Scene Segmentation 代码链接:Github 1.Intr…...

Stack和Queue(3)
Stack和Queue(3) priority_queue的模拟实现 priority_queue.h #include <vector>namespace soobin {template<class T, class Container vector<T>>class priority_queue{public://强制生成默认构造priority_queue() default;temp…...

怎样把学生的成绩单独告知家长?
期中考试季的到来让校园里的气氛似乎也变得紧张起来。家长们开始频繁地联系老师,希望了解孩子的表现;孩子们则在考试后,绞尽脑汁地想出各种理由,以期在成绩不理想时能减轻家长的失望。老师们更是忙得不可开交,不仅要批…...
vue3父组件控制子组件表单验证及获取子组件数值方法
1、关键部分的代码如下,我努力交代清楚了,希望能让大家看懂。 <template><KeepAlive><component ref"comp" :is"compNames[steps[compIndex].comp]" /></KeepAlive><el-button click"prevBtn"…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...

【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...