我决定试着玩一场Hangman游戏,让自己稍微熟悉一下这门语言。
use std::io::{stdin, stdout, Write};
fn main() {
let stdin = stdin();
let mut stdout = stdout();
let to_guess = String::from("BENEDICT");
let mut letters: u128 = 0;
loop {
// Replace unguessed letters of to_guess by underscores
let current = to_guess.chars().map(|x| {
if x <= 127 as char && letters & (1 << x as u8) > 0 {
x
} else {
'_'
}
});
// Add spaces between letters
let current = current
.map(|x| x.to_string() + &' '.to_string())
.collect::<Vec<String>>()
.join(" ");
println!("Current word: {}", current.trim_end());
if !current.contains('_') {
println!("Congratulations!");
break;
}
print!("Enter new letter: ");
stdout.flush().unwrap();
let mut letter = String::new();
stdin.read_line(&mut letter).expect("Invalid letter");
if letter.trim().len() != 1 {
println!("Use only one ASCII letter");
continue;
}
let letter = letter.to_uppercase().chars().next().unwrap();
letters |= 1 << letter as u8
}
}to_guess字是硬编码的,猜测的次数是无限的。
为了存储已经猜到的字母,我使用一个u128并标记相应的位。应该可以,因为所有的ASCII字母都是用u8 <128个表示的。
你能帮我检查一下代码吗,我错过了“锈蚀”的东西吗?
发布于 2020-10-17 03:06:03
欢迎来到铁锈。以下是一些让你开始的建议:
在Rust中,通过使用声明直接将函数带入作用域并不常见。相反,io::stdin和io::stdout是首选。有关更多信息,请参阅本书中的创建惯用路径一节。
您在对代码的解释中包括了这句话:
为了存储已经猜到的字母,我使用一个
u128并标记相应的位。应该可以,因为所有的ASCII字母都是用u8<128个表示的。
最好将此信息包含在代码本身中。在这种情况下,我们可以引入一个struct:
#[derive(Clone, Copy, Debug, Default)]
struct AsciiSet {
flag: u128,
}
impl AsciiSet {
fn new() -> Self {
Self { flag: 0 }
}
fn push(&mut self, letter: u8) {
self.flag |= (1 << letter);
}
fn contains(&self, letter: u8) -> bool {
(self.flag & (1 << letter)) != 0
}
}并相应地修改守则:
let mut letters = AsciiSet::new();
loop {
// ...
if letters.contains(letter) { /* ... /* }
// ...
letters.push(letter);
}ASCII
检查
如果是letter as u8,!letter.is_ascii()会截断字符。检查这种情况,并相应地提示用户。
https://codereview.stackexchange.com/questions/250476
复制相似问题