やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

Rust自習(じゃんけんゲーム2)

 u32型をenum型にした。

成果物

コード

use rand::Rng;
use std::io::Write;
use std::io::stdout;
fn main() {
    loop {
        println!("じゃんけんゲーム");
        print!("1:✊ 2:✌ 3:✋> ");
        stdout().flush();
        let player: u32 = read_stdin();
        let player = Hand::Rock.from(player);
        let npc = Hand::Rock.random();
        let res = Hand::Rock.jadge(player, npc);
        crate::Result::Win.show(res);
    }
}
fn read_stdin<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

#[derive(Debug,PartialEq)]
enum Result { Win, Lose, Draw }
impl crate::Result {
    fn show(&self, hand: crate::Result) {
        if hand == crate::Result::Win { println!("Win!!"); }
        else if hand == crate::Result::Lose { println!("Lose..."); }
        else { println!("Draw"); }
    }
}
#[derive(Debug,PartialEq)]
enum Hand { Rock, Scissors, Paper }
impl Hand {
    fn from(&self, hand: u32) -> Hand {
        match hand {
            1 => Hand::Rock,
            2 => Hand::Scissors,
            3 => Hand::Paper,
            _ => panic!("手は1〜3のいずれかで指定してください。")
        }
    }
    fn random(&self) -> Hand {
        let mut rng = rand::thread_rng();
        let hand = rng.gen_range(1, 4);
        self.from(hand)
    }
    fn jadge(&self, pc: Hand, npc: Hand) -> crate::Result {
        if pc == Hand::Rock && npc == Hand::Scissors { crate::Result::Win }
        else if pc == Hand::Rock && npc == Hand::Paper { crate::Result::Lose }
        else if pc == Hand::Scissors && npc == Hand::Rock { crate::Result::Lose }
        else if pc == Hand::Scissors && npc == Hand::Paper { crate::Result::Win }
        else if pc == Hand::Paper && npc == Hand::Rock { crate::Result::Win }
        else if pc == Hand::Paper && npc == Hand::Scissors { crate::Result::Lose }
        else { crate::Result::Draw }
    }
    fn show(&self, hand: Hand) -> char {
        if hand == Hand::Rock { '✊' }
        else if hand == Hand::Rock { '✌' }
        else { '✋' }
    }
}

思ってたのと違う

fn main() {
    loop {
        ...
        let player = Hand::Rock.from(player);
        let npc = Hand::Rock.random();
        let res = Hand::Rock.jadge(player, npc);
        crate::Result::Win.show(res);

 以下のようにやりたかったのに……。

fn main() {
    loop {
        ...
        let player = Hand.from(read_stdin());
        let npc = Hand.random();
        player.jadge(npc).show();

 Rock, Win, res, player, npcのような無駄な引数が多すぎる。どうやって実装すればいいのか?

所感

 なんかもう、全体的にダメダメに見える。どうやって書けばスマートになるのか。

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux

前回まで