首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >生锈新宠:刽子手游戏

生锈新宠:刽子手游戏
EN

Code Review用户
提问于 2020-10-10 18:25:55
回答 1查看 157关注 0票数 2

我决定试着玩一场Hangman游戏,让自己稍微熟悉一下这门语言。

代码语言:javascript
运行
复制
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个表示的。

你能帮我检查一下代码吗,我错过了“锈蚀”的东西吗?

EN

回答 1

Code Review用户

回答已采纳

发布于 2020-10-17 03:06:03

欢迎来到铁锈。以下是一些让你开始的建议:

创建惯用声明

在Rust中,通过使用声明直接将函数带入作用域并不常见。相反,io::stdinio::stdout是首选。有关更多信息,请参阅本书中的创建惯用路径一节。

使用结构来编写自文档代码

您在对代码的解释中包括了这句话:

为了存储已经猜到的字母,我使用一个u128并标记相应的位。应该可以,因为所有的ASCII字母都是用u8 <128个表示的。

最好将此信息包含在代码本身中。在这种情况下,我们可以引入一个struct

代码语言:javascript
运行
复制
#[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
    }
}

并相应地修改守则:

代码语言:javascript
运行
复制
let mut letters = AsciiSet::new();

loop {
    // ...
    if letters.contains(letter) { /* ... /* }

    // ...
    letters.push(letter);
}

ASCII

检查

如果是letter as u8!letter.is_ascii()会截断字符。检查这种情况,并相应地提示用户。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/250476

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档