今回の授業は、for文を使って、ビンゴカードを自動作成しようというものでした。二重のfor文ポイントは、二重のfor文です。「5回の繰り返し」を5回繰り返すことで、5×5の25個の数字を並べます。}}c0からc4をr0からr4まで5回繰り返すということです。(授業でやったものとはrとcを逆にしました。列でまとめたかったからです)c0~c4が5列に並ぶという形になります。+”]”」とすることで、[00][10][20][30][40][01][11][21][31][41][02][12][22][32][42][03][13][23][33][43][04][14][24][34][44]となりました。それぞれの表示を1〜75の数字をランダムに出るようにすれば、ビンゴカードの出来上がりです。・・しかし、これだとそれぞれの数のランダムなので、数が重複する場合があります。(それはそれで二つ空けられるラッキーナンバーということにすればいいのかもしれませんが、一般的なビンゴゲームにも一応ルールがあって、その中には数は重複しないというのがあります)数が重複しないようにシャッフルを使うそこで、数が重複しないように作るにはどうしたらいいかということで、その方法も教えてくださいました。ここでダステンフェルドのシャッフルを使います。nums.push(i);//numsの中にiがプッシュされていく。nums[rdm]にtmp(muns[i])を入れる。nums);0から24までの数をシャッフルしています。なっているのかわかりにくいのでそれぞれconsole.logで見てみました。nums[rdm]にtmp(muns[i])を入れる。nums);すると、このような動きになっていました。for文の繰り返しの中でその都度配列の順番が変わって上書きされるので、最初はnums[22]は22だったのが、入れ替わったことで途中でnums[22]は24に変わっています。一度交換の相手になったランダムで選ばれた「数字」は、後ろから順番に入っていって固定され(iは減少していくから)二度と交換されることはありません。ないと精度的に正しいシャッフルとなりません。ラベルで表示するあとは、ランダムに並べ替えられた数字にindexを用意して、num[0]~num[24]までがラベルのテキストに入るように書き換えて、ランダムに並んだ数字を表示できました。ラベルのテキストがnums[0]からnums[24]になる一般的なルールのビンゴカードを作るつぎに、これを応用して、日本でのビンゴの一般的なルールにしたがったものを作ってみたいと思ってやってみました。wikipediaのビンゴよりルールには無数にバリエーションがあるが、ここでは日本で一般的に行われている代表的なものを示す。一般的にビンゴカードはタテ・ヨコ5マスずつ、計25個のマス目が書かれている。その内、中央を除く24マスには1から75までの番号のうち24個の番号が書かれており、中央はフリースポットとして最初から有効な番号として扱われる。1枚のカードの中で同じ番号が重複することはない。カードに書かれる番号は、通常はまったくのランダムで配置されているわけではなく、一番左の列は1-15の中から5個選ばれている。同様に、左から2列目は16-30、中央列は31-45、右から2列目は46-60、一番右の列は61-75から5個ずつ(中央列のみフリースポットがあるので4個)選ばれている全くのランダムではなく、15づつの数の固まりから5個ずつ選ぶようになっているようですね。ややこしそうですが、for文をたくさん使ってやってみました。1〜15まで、16から30まで、31から45まで、46から60まで、61から75までの数からそれぞれ5つずつランダムに選ぶ必要があるので、それぞれシャッフルした15個の中から5つを選んでそれを左の列から並べるというやり方で作りました。ここでやっていることは、要素15個の配列をシャッフルして、その最初から5つの目までの数を取り出してnumsselという配列に入れていくという処理です。シャッフルされた数なので、そこから5つの数を取り出せば、ランダムで重複しない数となります。出来たランダムな配列nums15から5つの数字を取り出してnumsselという配列に入れていく。}あとは、そのかたまりの始めの数は1,16,31,46,61なので、その関数をつぎのようなfor文で実行します。Nums15(i);}すると、ランダムに選ばれた5つの数を5回入れていくので、numsselには、1~15から5つ、16~30から5つ、31~45から5つ、46~60から5つ、61~75から5つ、合計25個の数が選ばれて入ります。"free";とします。あとは、授業でやったときとおなじように、この配列musselにindexを使ってラベルに対応させて表示させれば、左の列からルールのようにならんだビンゴカードができました。forをたくさん使ったので、すごくforの練習になりました。functionも使ったので、途中、頭がこんがらがって死にそうになりました。関数は作ってもその実行は別の場所でやる感じなので、コードでは後ろに書いてあっても処理としては戻るような感じになって、あっちこっちで訳がわからなくなりそうでしたが、これも慣れなのでしょうか・・頭の中でforループの処理を同時にシミュレーションできないと書けないと思うので、これがサラッとできちゃうプログラマさんてすごいね。functionmとforを使うと本当に短く書くことが出来て、達成感がありました。あと今見て思ったんですが「配列の配列」ってあるんかな、当然あるでしょうね。下書きしたまま放置の記事が結構ありますが、あんまりきちんとと堅苦しくなると続けられなくなるので、思いつくまま軽い感じでいきたいと思います。今日の授業は最近の中でも面白く感じたので、記録として書いておきます。今チャレンジしているゲームですが、実は息子は、今回のテーマの初回の授業を受けた後から、偶然にも、先生がモデルにされたサリータワーと全く同じようなものを作りたいと作り始めていました。左右に移動するもの(授業ではヘリ)から物(授業ではブロック)を落として、積み上げるというものです。前回の授業では、ブロックが積み上げられたら、ヘリにぶつかってしまうので、そうならないようにヘリを上昇させるにはどうしたらいいでしょうね、というところで終わりました。息子は続きを作るべく、そこに挑んでみましたが、これは難しいのです。「ブロックが上のほうまで積まれてきたら」というのが問題なのですが、これを判定しようにも、ブロックは一番上の位置から落としているのです。落とす時点で既に一番上にあるのですから、「ブロックの位置から・・」とやろうとすると、落とす時点でもう積んでいる。「積まれたブロックの一番上のものから・・」とやろうとするなら、いつ判定するのか、どうやって判定するのかということになります。この時点で、私はもう面倒くさそうと思ってしまい、授業では擬似的な方法で簡単にそれっぽく見せる方法を採られるのではないかと思っていました。そこで、今日の授業です。授業で示された方法は、「ブロックを落としてから2秒後(連続して落としていても最後に落としたものから2秒後)に、落としたブロックをすべて調べて一番上にあるものの高さを取り、それとヘリの高さを比較して一定以上近ければ離す」というものでした。先生は「如何に誤魔化すか」と言われましたが、私は結構な正攻法じゃないかと思ってさすが先生と思いました。これよりブロックは下へ行くことがないので、これをブロックの最上位の位置の初期値とする。ブロックのi番目のy座標が取得される。繰り返すことで最終的には一番高いyがborderYとなる。ヘリが上に上がっていくと見えなくなるのでスクロールさせるどうやって一番上のブロックのy座標を取り出すのかというと、まずブロックはy座標480より下に行くことはないので、borderYの初期値を480としておきます。1個めのブロックのy座標と比較して、これより上ならそのy座標の値をborderYに書き換え、さらに2個めのブロックも同様・・とブロックの個数分つまり全部で繰り返せば、最終的にborderYが一番高いブロックのy座標の値に書き換えられているという訳です。プログラミングではこうやってやるんだーと感心、納得。して順序立てて教えていただくと、想像したより難しくなかったですし、考え方ややり方はほかにも色々応用できそうです。