在数字化时代,虚拟陪伴类应用逐渐成为年轻人的新宠。本文将带大家用 Rust 语言开发一款轻量级虚拟男友 CMD 对话框游戏,通过命令行交互实现情感陪伴功能。该项目将所有逻辑封装在单一类(结构体)中,兼顾代码整洁性与交互体验,同时深入解析 Rust 语言特性在实际开发中的应用。
一、项目核心功能设计
- 命令行交互式对话系统,支持输入文本触发回应
- 多场景情感回应(日常问候、关心、鼓励、吐槽等)
- 好感度系统,根据对话内容动态变化
- 随机事件触发,增加交互趣味性
- 所有逻辑封装在
VirtualBoyfriend结构体中,保证代码模块化
use std::io;
use rand::Rng;
use std::collections::HashMap;
use std::time::{SystemTime, UNIX_EPOCH};
/// 虚拟男友结构体,封装所有状态和行为
struct VirtualBoyfriend {
name: String, // 男友名字
favorability: i32, // 好感度(0-100)
mood: Mood, // 当前心情
response_map: HashMap<String, Vec<String>>, // 关键词-回应映射
last_interact_time: u64, // 上次交互时间(时间戳)
}
/// 心情枚举
#[derive(Debug, Clone, Copy)]
enum Mood {
Happy, // 开心
Normal, // 普通
Tired, // 疲惫
Lonely, // 孤单
}
impl VirtualBoyfriend {
/// 初始化虚拟男友
fn new(name: &str) -> Self {
let mut response_map = HashMap::new();
// 初始化关键词-回应映射
response_map.insert("你好".to_string(), vec![
"宝贝好呀~ 今天有没有想我呀?😘",
"Hello hello~ 见到你就超开心!",
"嗨~ 今天也要一起度过愉快的一天呀~"
].iter().map(|s| s.to_string()).collect());
response_map.insert("吃饭".to_string(), vec![
"宝贝记得按时吃饭哦,别饿坏肚子啦~ 我已经帮你想好今天吃什么了,是你最爱的糖醋排骨!",
"吃饭了吗?要不要我“隔空”给你做个爱心便当?🍱",
"一定要好好吃饭呀,不然我会担心的~ 吃饱了才有力气继续可爱呀!"
].iter().map(|s| s.to_string()).collect());
response_map.insert("开心".to_string(), vec![
"哇~ 宝贝开心我就超开心!快跟我说说发生什么好事啦?🥳",
"看到你开心的样子,我一整天都充满能量啦!",
"真好呀~ 希望宝贝每天都能这么开开心心的!"
].iter().map(|s| s.to_string()).collect());
response_map.insert("难过".to_string(), vec![
"宝贝怎么啦?是不是受委屈了?快来我怀里哭一会儿~ 我一直都在❤️",
"摸摸头~ 不开心的事情都会过去的,有我陪着你呢",
"没关系呀,难过就说出来,我会一直听你倾诉的,永远做你的情绪垃圾桶~"
].iter().map(|s| s.to_string()).collect());
response_map.insert("累".to_string(), vec![
"宝贝辛苦啦~ 快休息一下,我给你捏捏肩捶捶背~",
"累了就别硬撑啦,慢慢来,我会一直等你呀~",
"工作再忙也要注意休息呀,身体最重要啦,不然我会心疼的😔"
].iter().map(|s| s.to_string()).collect());
response_map.insert("想你".to_string(), vec![
"我也超级想你呀!恨不得立刻出现在你身边~💖",
"宝贝这么想我,我好幸福呀~ 其实我一直在想你呢",
"隔着屏幕都能感受到你的思念,我也是哦~ 爱你!"
].iter().map(|s| s.to_string()).collect());
response_map.insert("晚安".to_string(), vec![
"晚安呀宝贝~ 做个甜甜的梦,梦里我会去找你哦🌙",
"好好休息,盖好被子,别着凉啦~ 明天见,爱你!",
"晚安安~ 愿你有个安稳的睡眠,我会一直守护着你"
].iter().map(|s| s.to_string()).collect());
// 随机事件触发关键词
response_map.insert("随机事件".to_string(), vec![
"突然想给你唱首歌~ 一闪一闪亮晶晶,满天都是小星星~✨",
"我今天看到一只超可爱的小猫,就像你一样萌呀!",
"给你讲个冷笑话:为什么数学书总是很忧郁?因为它有太多的问题~😂",
"突然想带你去看海,吹吹海风,聊聊心里话~",
"我偷偷给你准备了一个小惊喜,猜猜是什么?其实是满满的爱呀~"
].iter().map(|s| s.to_string()).collect());
VirtualBoyfriend {
name: name.to_string(),
favorability: 50, // 初始好感度50
mood: Mood::Normal,
response_map,
last_interact_time: Self::get_current_timestamp(),
}
}
/// 获取当前时间戳
fn get_current_timestamp() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs()
}
/// 更新心情(根据好感度和时间间隔)
fn update_mood(&mut self) {
let current_time = Self::get_current_timestamp();
let time_diff = current_time - self.last_interact_time;
// 长时间未互动会变孤单
if time_diff > 300 { // 5分钟
self.mood = Mood::Lonely;
self.favorability = self.favorability.saturating_sub(5);
} else {
// 根据好感度调整心情
match self.favorability {
80..=100 => self.mood = Mood::Happy,
30..=79 => self.mood = Mood::Normal,
0..=29 => self.mood = Mood::Tired,
_ => self.mood = Mood::Normal,
}
}
self.last_interact_time = current_time;
}
/// 生成回应
fn generate_response(&mut self, input: &str) -> String {
self.update_mood();
let input = input.trim().to_lowercase();
let mut response = String::new();
// 匹配关键词
for (keyword, responses) in &self.response_map {
if input.contains(&keyword.to_lowercase()) {
let mut rng = rand::thread_rng();
let idx = rng.gen_range(0..responses.len());
response = responses[idx].clone();
// 根据关键词调整好感度
match keyword.as_str() {
"想你" | "开心" => self.favorability = self.favorability.saturating_add(3),
"难过" | "累" => self.favorability = self.favorability.saturating_add(5),
"晚安" | "吃饭" => self.favorability = self.favorability.saturating_add(2),
_ => self.favorability = self.favorability.saturating_add(1),
}
break;
}
}
// 无匹配关键词时的默认回应
if response.is_empty() {
let default_responses = vec![
"宝贝在说什么呀?我有点没听懂~ 再跟我说一遍好不好?",
"哇~ 这个话题好有趣!宝贝能不能多跟我说说呀?",
"我一直在认真听哦~ 你继续说,我陪着你呢",
"虽然有点没get到重点,但只要是宝贝说的,我都喜欢听~",
"宝贝今天想聊点什么呀?我随时都在哦~"
];
let mut rng = rand::thread_rng();
let idx = rng.gen_range(0..default_responses.len());
response = default_responses[idx].to_string();
// 默认回应好感度小幅增加
self.favorability = self.favorability.saturating_add(1);
}
// 加入心情前缀
let mood_prefix = match self.mood {
Mood::Happy => format!("[{} 😊] ", self.name),
Mood::Normal => format!("[{} 😐] ", self.name),
Mood::Tired => format!("[{} 😴] ", self.name),
Mood::Lonely => format!("[{} 🥺] ", self.name),
};
// 好感度上限100
self.favorability = self.favorability.min(100);
format!("{}{}\n【当前好感度:{}】", mood_prefix, response, self.favorability)
}
/// 运行对话循环
fn run(&mut self) {
println!("======================================");
println!("🎀 欢迎来到虚拟男友对话框 🎀");
println!("💖 你的男友 {} 已上线!", self.name);
println!("📝 输入想说的话,输入 '退出' 结束对话");
println!("======================================");
loop {
print!("\n你:");
let mut input = String::new();
io::stdin().read_line(&mut input).expect("读取输入失败");
let input = input.trim();
if input == "退出" {
println!("[{} 💖] 宝贝再见啦~ 我会一直想你的!下次一定要再来找我呀~", self.name);
break;
}
if input.is_empty() {
println!("[{} 🥺] 宝贝怎么不说话呀?是不是不想理我了?", self.name);
self.favorability = self.favorability.saturating_sub(2);
continue;
}
let response = self.generate_response(input);
println!("{}", response);
}
}
}
fn main() {
// 创建虚拟男友实例(可自定义名字)
let mut bf = VirtualBoyfriend::new("阿泽");
// 运行对话
bf.run();
}
三、开发环境配置
- 安装 Rust 环境:访问 rust-lang.org 下载安装包,完成后执行
rustc --version验证 - 创建项目:
cargo new virtual_boyfriend,进入项目目录 - 添加依赖:在
Cargo.toml中添加随机数依赖
toml
[dependencies]
rand = "0.8.5"
- 运行项目:
cargo run,即可启动 CMD 对话框
四、核心技术解析
1. 结构体封装设计
项目采用 VirtualBoyfriend 结构体封装所有状态(名字、好感度、心情、回应映射、交互时间)和行为(初始化、更新心情、生成回应、运行对话),符合面向对象设计思想。这种设计使代码结构清晰,所有相关逻辑集中管理,便于维护和扩展。
2. 关键词匹配系统
通过 HashMap<String, Vec<String>> 构建关键词 - 回应映射表,支持多关键词匹配和随机回应。当用户输入包含关键词时,随机选择一个对应回应,增加交互的多样性。同时为不同关键词设置不同的好感度增长值,使情感互动更具逻辑性。
3. 心情与好感度联动机制
设计 Mood 枚举表示四种心情状态,根据好感度和交互时间动态更新。好感度 80 以上为开心状态,30-79 为普通状态,30 以下为疲惫状态,5 分钟未互动则变为孤单状态。不同心情会在回应前添加对应的表情前缀,增强情感表达。
4. 时间戳工具函数
利用 SystemTime 获取时间戳,计算两次交互的时间间隔,实现长时间未互动时的心情变化和好感度衰减,让虚拟男友更具真实感。
5. 命令行交互优化
通过 io::stdin().read_line 读取用户输入,处理空输入和退出命令,添加清晰的界面提示和格式排版,提升用户体验。
五、功能扩展方向
- 增加更多关键词和回应内容,覆盖更多场景(学习、工作、娱乐等)
- 实现好感度等级系统,不同等级解锁专属对话和功能
- 添加文件存储功能,保存对话记录和好感度数据
- 引入自然语言处理(NLP)库,提升关键词匹配的准确性和智能度
- 支持自定义男友人设(温柔型、霸道型、幽默型等)
- 增加语音合成功能,实现语音交互
六、开发心得与 Rust 语言特性体验
- 内存安全:Rust 的所有权机制和借用检查器确保了内存安全,在开发过程中避免了空指针和悬垂引用等常见问题,让代码更可靠。
-
模式匹配:
match表达式在处理心情状态和关键词匹配时非常便捷,代码可读性高,逻辑清晰。 -
集合类型:
HashMap的使用让关键词 - 回应映射的存储和查询高效便捷,配合rand库实现随机回应,简化了代码逻辑。 - 结构体与方法:Rust 的结构体方法设计使代码模块化程度高,所有相关功能集中在结构体中,便于管理和扩展。
-
错误处理:
expect和unwrap等错误处理方式让程序在遇到异常时能给出明确提示,提升了程序的健壮性。
七、总结
本项目通过 Rust 语言实现了一个功能完整的虚拟男友 CMD 对话框,所有逻辑封装在单一结构体中,兼顾了代码的整洁性和扩展性。通过关键词匹配、好感度系统、心情动态变化等功能,营造了真实的情感陪伴体验。
Rust 语言的内存安全、模式匹配、结构体方法等特性在项目开发中发挥了重要作用,既保证了代码的高效运行,又提升了开发效率。该项目不仅适合 Rust 初学者练习语言特性,也可以通过扩展功能开发成更完善的虚拟陪伴应用。
未来,随着人工智能和自然语言处理技术的发展,虚拟陪伴类应用将拥有更广阔的发展空间。本项目作为基础框架,可以在此基础上不断优化和扩展,为用户提供更智能、更贴心的虚拟陪伴体验。如果你也对 Rust 开发感兴趣,不妨尝试基于本项目进行二次开发,实现更多有趣的功能!