
どうもこんにちは夫です。
今回はRustで数当てゲームのプログラムを作って行きます。
数当てゲーム完成形
まずどの様なものかイメージしてもらう為に
ソースコードだけ先に貼って実行します。
main.rsに以下を記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
extern crate rand; // randというクレートを使用、これはなくても良い use std::io; use std::io::Write; use std::io::stdout; use rand::Rng; use std::cmp::Ordering; fn main(){ println!("数当てゲームの始まり!"); let secret_number = rand::thread_rng().gen_range(1,10); //1から10までの数字を生成 loop { print!("入力 >"); stdout().flush().unwrap(); let mut guess = String::new(); // 可変変数で文字列のguessを用意 io::stdin().read_line(&mut guess) .expect("読み込み失敗"); // 入力をしてもらい失敗すればメッセージ let guess: u32 = match guess.trim().parse(){ Ok(num) => num, Err(_) => continue, // matchで比較、トリムで数字を整理、パースで数字に型変換 // 数字以外が入力されたらコンテニュー }; println!("入力したのは{}",guess); match guess.cmp(&secret_number){ Ordering::Less => println!("その数字は小さいね"), Ordering::Greater => println!("その数字は大きいね"), Ordering::Equal => {println!("その数字は正解だよ");break; // 入力した数字とmatchで比較 } } } } |
あとCargo.tomlのファイルの
[dependencies]の下の行に「 rand = “0.3.14”」を追加。
この二つが完了すればcargo runしてみてください。
だいたいこんな感じです。

おそらくこれだけではわかりづらいのでじっくりと解説をして行きます。
参考サイト
その前に参考サイトですがこちらです。
Rustのチュートリアルの和訳ですが
どうも初心者にはわかりづらい様でしたので分かり易くするのを心がけて解説します!
このプログラムを理解すればmatch文や外部クレートについて理解が進むと思います。
まずはプロジェクトの作成
まずはターミナルでプロジェクトを作りたいディレクトリに移動してから以下のコマンドで
1 |
$ cargo new number_game |
ではmain.rsをいじって行きます!
ここでちょっと話から外れますが「main.rsって何?」
ってなった方はこちらの記事を見てください。
では話に戻ります。
まずはゲームの始まり!という表示をします。
main関数のブロックの中に下のコードを写経しましょう。
1 2 |
println!("数当てゲームの始まり!"); let secret_number = rand::thread_rng().gen_range(1,10); |
ここではprintlnマクロで始まるメッセージを表示してから
secret_numberという変数に1から10までの数字を代入してます。
2行目にランダムな数字を生成してますが、
ここでややこしいのが現状ではRustの標準ライブラリには
数字をランダムに数字を作るライブラリがありません。
そこでクレートってやつが登場です。
クレートを使おう
クレートはざっくりいうと外部ライブラリみたいなものです。
pythonで言うとpipインストールしたものをimportする様なものです。
で、それを使う為に「Cargo.toml」というファイルに記述します。
このファイルはプロジェクト生成時に作られています。
このファイルを開いてこの様に記述するだけ

この1行を追加するとcrates.ioというとこで
超親切なcargoさんがダウンロードとコンパイルを後でしてくれます。
とりあえずここでビルドしてみましょう。
1 |
$ cargo build |
これで出来ます。

randに依存しているlibcもダウンロードしてくれてます。
ここでCargo.lockを見てみると…

パッケージとしてズラーっと取り込んだものが並んでいます。
この様になってたらOKです。
これで準備はできたのでプログラムの行頭に「use rand::Rng;」を追加して完了です。
1 |
let secret_number = rand::thread_rng().gen_range(1,10); |
これでこの行が実行可能となります。
入力するプログラムを作ろう
1 2 3 4 5 6 7 8 |
loop { print!("入力 >"); stdout().flush().unwrap(); let mut guess = String::new(); // 可変変数で文字列のguessを用意 io::stdin().read_line(&mut guess) .expect("読み込み失敗"); // 入力してもらうためのプログラム |
ざっくりした流れですが
- loop文から初めて入力を何度でも出来る様にする
- 「入力 >」という文字を表示して右に入力してもらう
- guessという変数の文字列型で変数を用意
- 入力する関数を使用してエラーがあれば”読み込み失敗”のメッセージ
まずはio::stdin()やstdout()などを使用する為にコードの行頭に

上の画像の様に入力しましょう。
あとは「.except()」で何か問題があればメッセージを表示する様にしないと
Rustから注意喚起されます。
これで入力する準備は完了です。
入力した数字を判定しよう
お次のコードはこれです。
1 2 3 4 5 6 |
let guess: u32 = match guess.trim().parse(){ Ok(num) => num, Err(_) => continue, // matchで比較、トリムで数字を整理、パースで数字に型変換 // 数字以外が入力されたらコンテニュー }; |
guessという変数を新たに文字列じゃなく整数型で変数を用意してます。
matchで判定式を作ります。
その前に入力された数字は受け取った際には本当に数字だけでしょうか?
実際には入力した後にEnterキーを押しますよね。
これのおかげで「/n」というデータまで受け取るので
trim()で数字だけ抽出してparse()で整数型にしています。
では判定式の方に戻ります.
入力されたものが数値ならnumという変数を返すだけですが、
もし文字など想定外のものが入力されればloop文の最初から戻ります。
入力結果の判定をしよう
こんな感じ
1 2 3 4 5 6 7 8 |
println!("入力したのは{}",guess); match guess.cmp(&secret_number){ Ordering::Less => println!("その数字は小さいね"), Ordering::Greater => println!("その数字は大きいね"), Ordering::Equal => {println!("その数字は正解だよ");break; // 入力した数字とmatchで比較 } } |
ここでもmatch文を使って判定しています。
また先ほどと同様で行頭に「use std::cmp::Ordering;」を追加してください。
guessとsecret_numberの参照(変数の頭に&を付ける)を比較して
その結果を数字の大小と等しいかで判定しています。
ゲームですので等しいってことは正解です。
正解すればゲームの終了なのでmatch文で定義した
Equalの後にプログラムを抜け出す為にbreakします。
これで完了です。
最後に
お疲れ様でした。
途中で僕の文を解読するのに疲れたかと思います笑
できれば写経してもらえると理解が深まるので
是非やってみてください。
途中で解説しきれないことがありすぎたので
わからないことがあればTwitterでもお問い合わせフォームからでも
全然良いので気軽に聞いてください。
コメント