やってみる

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

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

 一応できた。

成果物

f:id:ytyaru:20190711161231p:plain f:id:ytyaru:20190711161237p:plain f:id:ytyaru:20190711161252p:plain f:id:ytyaru:20190711161256p:plain

コード

src/main.rs

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();
        if player != 1 && player !=2 && player != 3 { break; }
        let npc = npc();
        let result = jadge(player, npc);
        println!("{} {}", hand(player), hand(npc));
        show_result(result);
    }
}
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()
}
fn npc() -> u32 {
    let mut rng = rand::thread_rng();
    rng.gen_range(1, 4)
}
// 0:draw, 1:lose, 2:win
fn jadge(player:u32, npc:u32) -> u32 {
    if      player == 1 && npc == 2 { 2 }
    else if player == 1 && npc == 3 { 1 }
    else if player == 2 && npc == 1 { 1 }
    else if player == 2 && npc == 3 { 2 }
    else if player == 3 && npc == 1 { 2 }
    else if player == 3 && npc == 2 { 1 }
    else { 0 }
}
// 1:✊, 2:✌, 3:✋
fn hand(hand:u32) -> char {
    match hand {
        1 => '✊',
        2 => '✌',
        3 => '✋',
        _ => panic!("手は1,2,3のいずれかのみ。"),
    }
}
fn show_result(result: u32) {
    if result == 1 { println!("Lose..."); }
    else if result == 2 { println!("Win!!"); }
    else { println!("Draw"); }
}

Cargo.toml

[dependencies]
rand = "0.6"

 ポイントは以下。

  • 乱数にrand外部クレートを使う
    • rand::thread_rng().gen_range(1, 4)
  • 標準入力受付: std::io::stdin().read_line(&mut s)

実行例

$ cargo run
...
じゃんけんゲーム
1:✊ 2:✌ 3:✋> 1
✊ ✌
Win!!
じゃんけんゲーム
1:✊ 2:✌ 3:✋> 2
✌ ✊
Lose...
じゃんけんゲーム
1:✊ 2:✌ 3:✋> 3
✋ ✋
Draw

所感

 クソださいコード……。ドキュメントをすべて学習したのに、2章の数当てゲームから何の進歩ない。でもこれが限界だった。もっと以下のようなことをしてカッコよくしたいのに技術力が追いつかない。

  • 構造化したい
    • Hand: Rock, Scissors, Paper
    • Result: Win, Lose, Draw
  • jadge()if
    • 3すくみの関係性を構築したい(循環リスト)
      • let result = player_hand.jadge(npc_hand);

 とくに要である循環リストは実装できる気がしない。所有権まわりが難解すぎて思い通りのコードが書けない。でも、そのへんを理解しないと抽象化された再利用性のあるコードが書けない。いつかリベンジしたい。

対象環境

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

前回まで