今回は配列をシャッフルします。
シャッフル=混ぜるということになります。
並んでいるデータをランダムにしたいわけです。
ゲームなんかを作るときは必須の処理ですね。
アイテムがランダムにドロップしたり、タメージの乱数とか、
即死魔法の確率とか、敵とエンカウントする判定とか色々です。
シャッフルするためのランダム数値をどうやって発動するか
もうすでに理解しているように、配列は添字で0から数字が
割り当てられていますね。並んでいるデータをランダムにするということは
添字をバラバラにしていく作業になります。
では、どうすればランダムに並び替えることかできるか考えてみましょう。
そもそも、ランダムに並べるためには、ランダムな数字がないと、
実現できないことがわかります。
ということで、まずはランダムな数字を出す方法を学びましょう。
とても簡単です。
1 |
Math.random() |
これだけです。
実際にコンソールから実行すると0以上1未満のランダムな数字が確認できますね。
でも、ダメなんです、そうです、配列の添字は0から1,2・・・と続いていくので
小数点じゃダメなんです。じゃあ10倍すればいいですね。
実行してみます。
1 |
Math.random()*10 |
こんどは、不要な小数点以下が出てきます。
不要なので、小数点をなんとかしましょう。
小数点をなんとかするには、切り捨て、切り上げ、または小数点
四捨五入する等、色々な処理がありますが、
今回は切り捨てを行います。
1 2 3 |
Math.floor(); //切り捨て Math.round(); //四捨五入 Math.seil(); //切り上げ |
これを使うと
下のようになります。
1 2 |
var randno = Math.random()*10; Math.floor(randno); //切り捨て |
いい感じですね。
でも、これだと0から9までの要素しかでないです。
課題
1から4までのランダムな数字を出したい場合はどうしたら良いか考えてみよう。
ランダム数値を使うケース
ではランダム数値を使用する機会について考えてみます。
じゃんけんの手を出すプログラムを組みました。
次のようなプログラムです。
1 2 3 4 |
var data = ["グー","チョキ", "パー"]; for(var i=0; i < data.length; i++){ alert(data[i]); } |
何回やっても同じ順番の手が出てきますね。
これでは何が出されるかわかってしまうので、ゲームになりません。
このような場合に配列の要素の順番をシャッフルします。
それではシャッフルの方法の説明をしたいところですが、
その前に、今回のプログラムで新しい関数を1つ利用しているので紹介します。
配列の中身を結合するjoin(ジョイン)
1 |
配列の格納された変数名.join() |
join関数を利用することで,配列の中身を結合して文字列にすることができます。
試しに使用してみましょう。
1 2 3 4 |
var Hello = ['こ','ん','に','ち', 'は']; alert(Hello.join()); //こ,ん,に,ち,はと表示されます |
join関数はかっこの中に何も入れない場合はカンマで結合します。
試しに括弧の中にハイフンを入れてみましょう。
1 2 3 4 |
var Hello = ['こ','ん','に','ち', 'は']; alert(Hello.join('-')); //こ-ん-に-ち-はと表示されます |
特に間に結合文字をつけたくない場合は「””」で空文字を入れてあげればOKです。
今回の目的は配列の要素をシャッフルすることです。
サンプルとして次のような配列を用意します。
1 2 |
var data = ['イヌ','ネコ','クマ','キリン','ライオン'] alert(data.join()); |
この配列をシャッフル後再度アラートで表示させた時、
最初に確認した時と並び順が変わって入ればOKです。
1 |
'キリン','ライオン','ネコ','イヌ','クマ' |
配列をシャッフルするアルゴリズム
では実際の処理を確認していきましょう。
シャッフルの方法は色々ありますが、有名なFisher-Yates shuffleを紹介します。
1 2 3 4 5 6 7 8 |
var data = ['イヌ','ネコ','クマ','キリン','ライオン'] for(var i = data.length - 1; i > 0; i--){ var r = Math.floor(Math.random() * (i + 1)); var tmp = data[i]; data[i] = data[r]; data[r] = tmp; } data.join() |
この処理は後ろの要素を選択する、ループ変数iとランダムな値で得られた数値r
を入れ替えていく処理になります。
まずは処理の流れを理解できるようにしていきましょう。
配列のシャッフルとランダム数値まとめ
- Math.random()を利用すると(0~1)までのランダムな数値を得ることができる。
- Fisher-Yates shuffleで配列をランダムに混ぜることができる。
- 配列変数.join()で配列の要素を結合することができる。
課題
1.要素数10個の配列に1~10までの数字を格納して、
その配列をシャッフル後、alertで一つずつ表示してください。
2.1で作成したプログラムについて、数字が5と10倍数の場合はそれぞれ
「five」、「ten」と表示方法を変えてアラートを出してください。