Javaによるプログラミング入門10
乱数

 こんにちは。前回のプログラムはまだまだ未完成ですが、それでもかなり長かったですね。しばらくあんなのはありません。あれを理解して、改良するため、今日から少し地道な勉強をします。

 今日は、入門9で出てきた「新しいこと」の説明をします。
 まず、でたらめな数、つまり乱数の話です。「乱数を発生させる」ということは「さいころを振る」というようなことです。ただ、さいころの場合は1から6の数しかでませんが、プログラムでは自由に選べます。
 まず例を見ましょう。次のようなプログラムをコンパイルし実行してみてください。

//Ransu.java
class Ransu
{
    public static void main(String[] args){
        System.out.println(Math.random());
        System.out.println(Math.random());
        System.out.println(Math.random());
    }
}

Fig.1 Ransuの実行
(出力される乱数は実行のたびに異なるはずです。
みなさんの環境で実行したものが、Fig.1と異なっていても問題ありません。)

 このプログラムを実行すると、3つのでたらめな数(正確には、0以上1未満のでたらめな数)が出力されるのです。このようなでたらめな数を乱数といいます。上のプログラムで、Math.random()というのは、「乱数を発生させるメソッド」で、「書いてある場所に、乱数を置いてくれる」メソッドなのです。System.out.printlnの丸カッコの中に「乱数を置く」ので、それが出力されるわけです。当然、main()の中に「System.out.println(Math.random());」をいくつも書けば、それだけ乱数が表示されるのです。(正確に言うと、Math.randomは、Mathというクラスのrandomというメソッドということになります。詳しくは、後ほど。また、「置いてくれる」は業界用語ではありません。Javaの用語では、「乱数を返す」などと言います。このような言い回しはあとで説明しますので、とりあえずは、「置いてくれる」と考えておいてください。)

 これで、でたらめな「0以上1未満の数」が得られるわけですが、でたらめな整数がほしいと思うかもしれません。たとえば、「1から10までの間のでたらめな整数」が必要ならどうすればよいのでしょうか。
 そのため、まず、「Math.random()」を10倍し、「Math.random() * 10」としてみます。するとこれは「0以上10未満の数」になりますね。ただし、これは、一般には、小数です。そこで、「(int)」を前に書き「(int)(Math.random() * 10)」とします。こうすると、小数点以下が切り捨てられることになっているのです。つまり、「(int)(Math.random() * 10)」は「0から9までの整数のどれか」ということになるわけです。
 したがって、「1から10までのあいだのでたらめな整数」は、それに1を足して、

(int)(Math.random() * 10) + 1

とすればよいことになるのです。ちょっとながかったですが、完成です。^^)

 それでは、ここで、問題です。もし、0から4までのどれかを発生させたければどうしますか?正解は「(int)(Math.random() * 5) 」ですね。1を足して「(int)(Math.random() * 5) + 1」とすれば「1から5までのどれか」になります。

 「1から10までのでたらめな整数を3つ表示するプログラム」が書ければ、この話はわかったことになります。。...答えは、次のようになりますね。

//Ransu2.java
class Ransu2
{
    public static void main(String[] args){
        System.out.println((int)(Math.random() * 10) + 1);
        System.out.println((int)(Math.random() * 10) + 1);
        System.out.println((int)(Math.random() * 10) + 1);
    }
}

Fig.2 Ransu2の実行

 説明がめんどうでわかりにくかった人はとりあえず、「(int)(Math.random() * 10) + 1」と書けば「1から10までのでたらめな整数」をつくれるということだけ覚えて、使ってみてください。


 上のプログラムはmainを持つクラス以外にはクラスをつくらないプログラムでした。これはプログラムがとても簡単だからです。
 以下に「おみくじ」のクラスを作って使うプログラムを載せておきます。少し強引にクラスを作った感じはしますが、まずは、頭の体操程度に思って見てみてください。内容はそれほど難しくないと思います。
 コンストラクタでユーザに「自分のラッキーナンバー」を入力してもらい、それをフィールドunに格納し、hikuメソッドでは、発生させた乱数がunに等しいときだけ「大吉」、そうでないときは「並み」と表示するようにしたのです。ちょっとがんばって読んでみてください。あまり、わからない人は少し復習してみてください。よくわかる人はひとりでにやにやしてみてください。

//OmikujiSample.java
import java.io.*;

class Omikuji
{
    private int un;  //ラッキーナンバー
    //コンストラクタ
    Omikuji() throws IOException{
        System.out.println("自分のラッキーナンバー(1〜5)を入力してください。");
        BufferedReader br =
            new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();             //ユーザから入力を文字列として受け取る
        un = Integer.parseInt(str);           //その文字列を整数に変換してunに格納
    }
    //おみくじを引くメソッド
    void hiku(){
        int x = (int)(Math.random() * 5) + 1;  //1〜5の乱数を発生させ、xに格納、これが引いたおみくじの番号
        System.out.print("あなたの運勢は");   //本文で説明します
        if(x == un){                                            //xとunが等しければ大吉
            System.out.println("大吉ということです。");
        }
        else{                                                    //xとunが等しくなければ「普通」
            System.out.println("並みということです。");
        }
    }
}

class OmikujiSample
{
    public static void main(String[] args) throws IOException{
        Omikuji today = new Omikuji();  //今日のおみくじ
        today.hiku();                       //おみくじをひく
    }
}

Fig.3 OmikujiSampleの実行画面
(いやあ、これはなかなか大吉にならないおみくじです。)

 おみくじの出力で、System.out.printというものを使っています。これは、「改行せずに文字列を出力せよ」という意味になります。

 しかし、上のプログラムを「mainを持つクラス」だけで簡単にかけないでしょうか?答えは「書けます」です。

//OmikujiSample2.java
import java.io.*;
class OmikujiSample2
{
    public static void main(String[] args) throws IOException {
        int un;  //ラッキーナンバー
        System.out.println("自分のラッキーナンバー(1〜5)を入力してください。");
        BufferedReader br =
            new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();             //ユーザから入力を文字列として受け取る
        un = Integer.parseInt(str);           //その文字列を整数に変換してunに格納
        int x = (int)(Math.random() * 5) + 1;  //引いたおみくじの番号
        System.out.print("あなたの運勢は");
        if(x == un){                                            //xとunが等しければ大吉
            System.out.println("大吉ということです。");
        }
        else{                                                    //xとunが等しくなければ「普通」
            System.out.println("並みということです。");
        }
    }
}

 いかがでしょう。このように短いプログラムを書く場合、特別なクラスを書かない方が簡単です。というか、タイプ量が少しですむわけです。しかし、一度「おみくじクラス」を作ってしまえば、それをいろいろなプログラムで使えるということを考えてください。たとえば、ゲームプログラムの前フリに使うこともできるでしょう。もちろん、このプログラムを大きなものに発展させる場合も、クラスを部品に考えた方がずっと楽になります。クラスは「再利用可能なプログラムの部品」なのです。ぜひ、クラスを書くようにしてください。

 それにしても、「大吉」と「並み」しかないおみくじって少し変ですね。改良したい人は、if文をもう少し細かく使って、「中吉」とか「小吉」なども入れてみてください。


 これで、前回のプログラム(大魔王とヒーロー)で、わからないところは無くなったはずです。もう一度、見直してください。
 次回はこのプログラムをもう少しゲームっぽくするために必要な、繰り返し(forやwhile)について説明します。


目次のページ
前のページ 次のページ