【はじプロ】重複しない乱数を攻略:中級者にステップアップできる技術を解説してみた(失敗事例あり)
2023.10.17更新
広告
【PR】この記事には広告を含みます。
この記事はこんな人に読んでもらいたい
- ランダム要素をもったゲームを作りたいあなた
- 重複しない乱数の作り方を探しているあなた
- はじプロに慣れてきて、中級レベルのプログラムを知りたいあなた
この記事を読めばこんなことがわかる
- 重複しない乱数をつくるには、ランダムノードンからの出力を使わずに、順位を乱数として使う
- 順位を決めるには総当たり表をつくる
- 総当たり表をつくるには、くらべるノードンとNOTノードンを使う
ゆーまるのゲームは、毎回ちがう数字のならびかたで始まるよね?
このしくみはどうやってつくっているの?
それは『重複しない乱数』をつかっているからだよ。
以前、「ナビつき!つくってわかる はじめてゲームプログラミング」(はじプロ)で使用するランダムノードンについて解説をしました。
- ランダムノードンについて解説
- リンク:【はじプロ】ランダムノードンを攻略:初心者がつまづきやすいポイントを解説してみた
ランダムノードンの解説ページをつくったのは、次の2つの理由があったからです。
ランダムノードンの解説ページをつくった理由
- ゆーまるがつくったゲームで使用しており解説したいから
- 『重複しない乱数』を見つけて感動したから
- ゆーまるがつくったゲーム
- リンク:【はじプロ】プログラミング教育ブログの筆者が作ったゲームIDを公開してみた
私がつくった最初のミニゲームは、1〜4の数字を順番にタッチする、というものです。
しかし、毎回おなじ並び方だと、いくら時間制限があってもつまらないですよね?
だからランダムノードンを使って、ゲームが始まるたびにパネルに書かれる数字を変更するしくみを作りました。
しかし、私も自身でゲームをつくっている際、発生する乱数が重複(ちょうふく・じゅうふく)してしまう問題にぶち当たりました。
そのときに調べた際に見つけたプログラムが『重複しない乱数』だったのです。
- はじカミ Nintendo Switch『ナビつき! つくってわかる はじめてゲームプログラミング』のゲームID共有サイト 『重複しない乱数』
- リンク:はじカミ Nintendo Switch『ナビつき! つくってわかる はじめてゲームプログラミング』のゲームID共有サイト 『重複しない乱数』
ゲームID:G 000 K88 LX6
プログラマーID:P 004 M9Y 4Y00
ランダムノードンの出力をそのまま使うのではなく、ランダムノードンの大小関係を使ってランダムな順番を生み出す、という言葉では表現しにくいしくみが考えられています。
発想が柔軟だと思って感動し、ぜひ知ってもらいたいと思ったので、まずは基礎知識として必要なランダムノードンの解説をしました。
今回は、私が発想に感動した『重複しない乱数』の作り方について解説します。
なお、過去に私が作ったゲームをご紹介しています。
ぜひ一度ご覧になってから、あるいは何度かプレイしてから読んでいただければ、より理解が深まります。
重複しない乱数の作り方!ランダムノードンに『順位』をつけよう!
過去の記事【はじプロ】ランダムノードンを攻略:初心者がつまづきやすいポイントを解説してみたの復習です。
ランダムノードンの特徴を一言でいうと、ランダムノードン=ビンゴゲームのガラガラでしたね。
さて、今から次のようなゲームを作りたいと考えているとします。
今から作りたいゲーム
1、2、3の数字がかかれたパネルを順番にタッチする
ノードンガレージでつくろうとすると、まずはこのような形が思い浮かぶのではないかと思います。
それぞれのランダムノードンでは、1〜3の数字が出力されるように設定しています。
ゲームを開始すると、それぞれのランダムノードンに入力があり、ガラガラから出た数字(1〜3)を出力します。
うまくいけば、3つのランダムノードンから出力される数字がバラバラで、ゲームとして成り立ちます。
しかし、それぞれのランダムノードンは他のランダムノードンに興味はないので、
どれか2つ、あるいは3つ全部のランダムノードンが同じ数字を出力してしまう可能性もありますよね。
こうなってしまっては、ゲームのプレイヤーは、
どのパネルを押せばいいのかわからないよ・・・
と困ってしまいますよね。
では、1〜3の数字をかぶらせないようにするためには、どのような工夫が考えられるでしょうか?
プログラミングに正解はありませんので、もしかしたら別の方法があるのかもしれませんが、
今回解説する方法はつぎのとおりです。
ランダムノードンの出力(1〜3)をかぶらせないようにする工夫
- それぞれのランダムノードンから出力された数値を使って『順位』をつける
- 『順位』を乱数として表示する
擬人化すると次のようなイメージです。
ランダムノードンの出力をそのまま乱数として使うのではなく、『順位』というワンクッションを入れるというアイデアに気づいたときに、考案された方の頭の柔軟さに感動しました。
『重複しない乱数』をガレージノードンでどうやってつくればいいの?
『重複しない乱数』をつくりあげるための考え方を示しました。
では、実際にかたちにするにはどのようにプログラミングをすればよいか、解説していきます。
さて、プログラムのなかで実現しなければならないゴールは次のとおりです。
重複しない乱数を表示させるために必要な作業
- ランダムノードンに出力させる
- 出力させた数値に対して順位をつける
- 順位を数つきモノノードンに表示させる
ここで、皆さんに考えていただきたいのは2つめの『出力させた数値に対して順位をつける』です。
今回の例でいうと、3つのランダムノードンそれぞれに対して、『1位』『2位』『3位』の冠をそれぞれ誰にかぶせるか?を決めるプログラムを構築する必要があります。
順位を決めるには、ランダムノードン同士で対決させて、勝ち負けを決める方法がありますね。
では、どのようなプログラムを組むべきでしょうか?
この答えは、皆さんが生活しているなかで必ず見たことがある仕組みを使います。
スクロールをする前にちょっと考えてみましょう。
・
・
・
・
・
では解答です。下の図をご覧ください。
スポーツが好きな方はよく見るかもしれませんね。総当たり表です。
3つのランダムノードンの順位を決めるには、3戦の勝敗を決める必要があります。
総当たり表をノードンガレージで作るには、どんなノードンを使えばよいでしょうか?
答えは、
- くらべるノードン
- NOTノードン
の2つを使います。使い方・考え方は次の図で解説します。
まずは、黄色のノードン(4)と緑色のノードン(9)をくらべるノードンを使って勝敗を決めます。
この2つの手順を、残り2つの組み合わせ(黄色vs青色、緑色vs青色)についても行って総当たり表を完成させます。
これらのしくみを、実際にノードンガレージでつくりあげると次のようになります。
(ゲーム画面)
最後にくらべるノードン・NOTノードンからの出力を、けいさんノードンで足し合わせることによって『勝ち点』を求めます。
最後に勝ち点から乱数をつくりだします。
勝ち点は0〜2、本来ほしい乱数は1〜3です。
ここで、先ほど示した総当たり表の『勝ち点』と『順位(=乱数)』を見てみると、
『勝ち点』+『順位(=乱数)』=3
という法則があることがわかると思います。
そこで、3から『勝ち点(0〜2)』を引くと、ほしい『乱数(1〜3)』を得ることができます。
なお、乱数4つにするには総当たり表を増やすだけ、つまりくらべるノードンとNOTノードンを増やすだけです。
オリジナルの作品:はじカミ Nintendo Switch『ナビつき! つくってわかる はじめてゲームプログラミング』のゲームID共有サイト 『重複しない乱数』と形は違いますが、仕組みは同じです。
興味がある方はぜひ見比べてみてください。
うまくいかなかった『重複する乱数』プログラミング方法
もともと、前述のプログラミングにめぐり合うまで、次のようなプログラミングを組んでいました。
うまくいかなかった乱数作成のプログラミングの流れ
- ゲームスタート時に3つのランダムノードンに入力をいれる
- くらべるノードンをつかって、1つめと2つめの入力が同じならば、2つめのランダムノードンの「リセット」に入力をいれる
- くらべるノードンをつかって、1つめと3つめの入力が同じならば、1つめのランダムノードンの「リセット」に入力をいれる
- くらべるノードンをつかって、2つめと3つめの入力が同じならば、3つめのランダムノードンの「リセット」に入力をいれる
このプログラミングの問題点は3つありました。
ゆーまるがつくった重複しない乱数プログラムの問題点3点
- 出力される乱数が重複してしまう
- そもそも重複しない乱数がそろう前に処理が終わってしまう
- 重複しない乱数が準備されるまでに時間がかかる
手順2〜4で重複してしまった際に再度出力するようプログラムを組んでいます。
しかし、問題点の1つ目(重複してしまう)という問題が解決していないので、何度も何度もリセットしてしまいます。
そのため、重複しない乱数が完成するまで時間がかかってしまい、ゲームの仕様のせいなのか処理が止まってしまいました。
考え方としては間違っていないと思うのですが、このようにつくってもダメだと反面教師にしてください。
まとめ
今回は、はじプロで『重複しない乱数』の作る方法について解説を行っていきました。
本記事のまとめ
- 重複しない乱数をつくるには、ランダムノードンからの出力を使わずに順位を乱数として使う
- 順位を決めるには、総当たり表をつくる
- 総当たり表をつくるには、くらべるノードンとNOTノードンを使う
もしかしたら、これ以外にも『重複しない乱数』をつくる方法はあるかもしれません。
以前、【親・指導者向け】プログラミング教育において子供にかけるべき言葉は?でもお話していますが、あるべき姿にさえ到達してしまえばどのような手順を作り上げてもよいのです。
プログラミング的思考を身に着けていくことができれば、今後たくさんの選択肢を思い浮かべることができるようになります。
今回の記事から『ノードンの組み方』だけを参考にするのではなく、ぜひ『考え方』や『発想』を自分のものにしていただけると、記事を頑張って書いた甲斐があります。
では、次の記事までごきげんよう。