第16章 - 实战项目:猜数字游戏
嗨,朋友!我是长安。
学了这么多理论知识,是时候动手做一个完整的项目了!这一章我们要做一个经典的猜数字游戏。
这个项目会用到我们学过的很多知识:变量、函数、控制流、错误处理等。
🎯 项目目标
制作一个命令行猜数字游戏:
- 程序随机生成一个 1-100 的数字
- 玩家输入猜测的数字
- 程序提示"太大了"或"太小了"
- 玩家猜对后显示用了几次
🚀 创建项目
cargo new guessing_game
cd guessing_game
📦 添加依赖
我们需要一个随机数生成库。编辑 Cargo.toml:
[dependencies]
rand = "0.8.5"
💻 完整代码
打开 src/main.rs,替换为以下代码:
use rand::Rng;
use std::cmp::Ordering;
use std::io;
fn main() {
println!("===== 猜数字游戏 =====");
println!("我想了一个 1 到 100 之间的数字,你能猜中吗?\n");
// 生成 1-100 的随机数
let secret_number = rand::thread_rng().gen_range(1..=100);
let mut attempts = 0;
loop {
println!("请输入你的猜测:");
// 读取用户输入
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("读取输入失败");
// 将字符串转换为数字
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("❌ 请输入有效的数字!\n");
continue;
}
};
// 检查范围
if guess < 1 || guess > 100 {
println!("❌ 请输入 1 到 100 之间的数字!\n");
continue;
}
attempts += 1;
// 比较猜测和答案
match guess.cmp(&secret_number) {
Ordering::Less => println!("📉 太小了!\n"),
Ordering::Greater => println!("📈 太大了!\n"),
Ordering::Equal => {
println!("🎉 恭喜你猜对了!");
println!("答案是 {},你用了 {} 次!", secret_number, attempts);
break;
}
}
}
}
📖 代码详解
1. 导入依赖
use rand::Rng; // 随机数生成
use std::cmp::Ordering; // 比较结果的枚举
use std::io; // 输入输出
2. 生成随机数
let secret_number = rand::thread_rng().gen_range(1..=100);
rand::thread_rng():获取随机数生成器gen_range(1..=100):生成 1 到 100 的随机数(包含 100)
3. 读取用户输入
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("读取输入失败");
String::new():创建空字符串read_line():读取一行输入expect():处理可能的错误
4. 解析输入
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("❌ 请输入有效的数字!\n");
continue;
}
};
trim():去除空格和换行符parse():尝试转换为数字match:处理成功和失败两种情况
5. 比较大小
match guess.cmp(&secret_number) {
Ordering::Less => println!("📉 太小了!\n"),
Ordering::Greater => println!("📈 太大了!\n"),
Ordering::Equal => {
println!("🎉 恭喜你猜对了!");
break;
}
}
🏃 运行游戏
cargo run
游戏示例:
===== 猜数字游戏 =====
我想了一个 1 到 100 之间的数字,你能猜中吗?
请输入你的猜测:
50
📈 太大了!
请输入你的猜测:
25
📉 太小了!
请输入你的猜测:
37
📉 太小了!
请输入你的猜测:
43
🎉 恭喜你猜对了!
答案是 43,你用了 4 次!
🎨 改进建议
你可以添加这些功能:
1. 添加难度选择
println!("选择难度:1.简单(1-50) 2.中等(1-100) 3.困难(1-200)");
// 根据选择设置不同范围
2. 记录最佳成绩
let mut best_score = 100;
if attempts < best_score {
best_score = attempts;
println!("🏆 新纪录!");
}
3. 再来一局
loop {
// ... 游戏代码 ...
println!("\n再来一局吗?(y/n)");
let mut choice = String::new();
io::stdin().read_line(&mut choice).unwrap();
if choice.trim() != "y" {
println!("感谢游玩!再见!");
break;
}
}
💡 学到的知识点
通过这个项目,我们复习了:
- ✅ 使用外部 crate(
rand) - ✅ 变量和可变性(
let mut) - ✅ 循环(
loop) - ✅ 模式匹配(
match) - ✅ 错误处理(
Result) - ✅ 用户输入输出
- ✅ 字符串处理(
trim,parse)
💪 挑战任务
- 添加输入次数限制(比如最多 7 次)
- 显示猜测历史记录
- 添加提示功能(每 3 次猜测给一次提示)
- 制作双人对战模式(一人出题,一人猜)
次数限制示例
const MAX_ATTEMPTS: u32 = 7;
let mut attempts = 0;
loop {
attempts += 1;
if attempts > MAX_ATTEMPTS {
println!("💔 机会用完了!答案是 {}", secret_number);
break;
}
println!("第 {}/{} 次机会", attempts, MAX_ATTEMPTS);
// ... 其他代码 ...
}
🚀 下一步
做完这个项目后,你可以尝试:
- 美化界面(添加颜色、ASCII 艺术)
- 保存游戏记录到文件
- 制作 GUI 版本
