
※途中で戻りたい場合は、ブラウザの「戻る」機能を使ってください。
メルマガの読者に助けられる前章で、1から43までの6つの数字をランダムに求めるプログラムで、結果が全て同じになってしまう問題を色々考えて悩んでいる旨をメルマガで伝えたところ、読者の方から解説つきのプログラムがメールで送られて来ました。どうやら問題解決することが出来そうです。以下、そのメールの情報を元に、理解しながら修正していきたいと思います。 では、前章で作ったプログラムのスナップショットをもう一度載せておきます。 ![]() 乱数を求めるプログラムをもっとスマートにするまず初めは2行に渡って作られた、1から43までの数字をランダムに求めるプログラムをもっと簡潔に出来ることを知りました。その問題部分を抽出してみました。 ![]() いままでのプログラムでは、30行で0から100までの乱数を求めて、40行で「43より大きければ、30行に戻り、もう一度乱数を得る」という仕組みです。 また、これだと0も得られてしまいます。 書き換えたプログラム箇所です。 そこで、30行をこう書き換えることで、2行にわたるプログラムを1行に簡潔にまとめることが出来ます。 解説すると、(RND(−TIME))に42をかけて小数部分を切り捨てることで得られる乱数の範囲は、0から42となります。 [ポイント] 0〜Aまでの乱数を求めるには、FIX(RND(-TIME)*A) そこで、その答えに1を加えることで得られる乱数の範囲は、1から43という結果になります。 前に書いた通り、小数点切捨てはFIX関数なので、INTからFIXに変えました(支障が無い限り、そうしていきます)。 ![]() 30行を書き換えた後は、40行を消去して1行にまとめることが出来ました。 二重のIF文には、ANDを使う次は60行のIF文を直します。60行を抽出して表示してみました。 ![]() この行の意味としては、「A(B)とAの内容が違うかつ「A(B)の内容が0である場合に、A(B)へAの内容を代入する」ということなのですが、「条件かつ条件ならば」という表現には、AND命令を使うとスマートに表現できます。 AND命令に置き換えてみました。 AND命令は「小さいプログラムから その3」で紹介されていますので、必要ならば参照してください。 FOR NEXT文をIF GOTO文へ抽出してみました。![]() 目的の処理は、「ランダムで選んできた数字が、今まで選んだ数字と違い、配列にまだ空きがあれば、代入する。今まで選んだ数字と一緒なら、もう一度ランダムで数字を選びなおす。配列に空きが無くなれば、処理を終了。」という事になると思います。 50行から70行までのFOR NEXT文ですが、この場合だと条件に合っていても、合っていなくても、繰り返してしまう問題です。 ここは、IF文でチェックしてGOTO文で分岐させれば、条件に関係した処理が出来ます。 まず、20行目のFOR文でI番目の配列を決めていることを確認してください。 A(B)の添え字の変数BとIが合うまで、Bをカウントアップしながら内容が一緒で無いかチェックしていき、途中でA(B)の内容が一緒になったらランダムの数字を選びなおし、BとIが一緒になれば(I番目は0であり、空きということだから)代入する。 後でRENUM命令を使って、行番号を整えておきましょう。 変更前のプログラム ![]() 変更後のプログラム ![]() そして、実行!! ![]() あれぇぇぇ・・・? なんでだ?? エラーメッセージをリファレンスで調べてみると、 「配列変数の添え字が、DIM文で定義した添え字の最大値より大きい」 とありました。 変更後のプログラムをもう一度よく見てみよう。 最初に50行を実行する時の I と B の内容は、 I=0 B=0 で、IF文の B<I は成り立たず、60行のB=B+1を実行して再び50行へ行く。 2回目の50行を実行する時の I と B の内容は、 I=0 B=1 で、IF文の B<I は成り立たず、B=B+1を実行して再び50行へ行く。 こうしてみると、 B が増加していくだけをずっと続き、最後には配列 A の最大の添え字である5を超えてしまいエラーとなることがわかった。 それに、70行以降は実行されないようになっているし・・・・。 ・・・・もう一度やり直しだ。 次章に続きます(続きすぎ?)。 |
Copyright(C) 2006. ピコピコテクノロジー All Right Reserved.