配列奮闘記
投稿者: naoki4019 投稿日:2017/02/19 01:40
≪配列奮闘記~second~
|
キー入力奮闘記≫
※個人で頑張って奮闘してるだけの日記なので生暖かい目で見てあげてください
※ついでにRmake記法を試してみたかったんです許してください何でもしますから
課題:ジョーカー含む計53枚のトランプからランダムに5枚を引く手段の模索
→配列0~52に入れた数字をランダムに入れ替えると解釈
目次----------------------------------------------
----------------------------------------------------
1.とりあえず配列0~52に0~52の数字をそれぞれ入れていくよ
これにより
とすることに成功した
この数字をランダムに入れ替える、つまり
というようにしたい、なのでrand関数は使えない(多分)
▲ページの先頭へ▲
2.でもrand関数使えそうじゃない?
使えないって決め付けるのは三流のやることです、考え次第ではどうにかなるでしょう(適当)
使う変数
r ...whileで繰り返すのに使う変数
deck ...[0]~[52]に0~52を順番通りにセットした配列
deck_s ...deck内をランダムに入れ替えた(shuffleの頭文字)配列、言わば今回の目標
r_s ...whileでdeck_sをランダムに入れ替えるのに使う変数
・・・う~んと?適当に組んだけどこれいろいろおかしいな(´・ω・`)
・rand関数でランダムに数字を呼び出す
・deck[0]~[52]のどこにその数字があるかをwhileで見つけ出し、そのdeckを使い物にならなくする
これを53回繰り返すことで「シャッフルしたあとのデッキ」が完成する、はず・・・
あ、見つけたらrandからやり直しにすればいいのか・・・いきなりスクリプトに起こした方が早そうね
なーんで私のスクリプトはこんな複雑に見えるんだ
これで全配列を探し回ってランダムに並び替えることに成功した、これで目標は達成したと思いきや・・・
▲ページの先頭へ▲
3.時間かかり過ぎ問題
スクリプトをこのように変更し、処理にかかる時間を計測しました
計測した結果、この処理にかかる時間は900~1200ミリ秒、
秒にして0.9~1.2秒の処理が必要となってしまうのです(´・ω・`)
当然ですね、aに8が入って8が処理されたあと、
もう一度aに8が入ったら全部探した挙句ありませんでした状態ですので(´・ω・`)
さて・・・どうしたものか・・・
そもそもwhileで探す必要なくない?
まさかの今までの考え全否定である
deck[7]には最初7が入っているとわかってるのになぜ全部探しているんだ・・・?(´・ω・`)
つまりaにランダムで数字を入れたらdeck[a]がaと同じかどうかを検証したいだけだ・・・あれすっごい単純
これで計測した結果、なんと15~50ミリ秒!全く気にならないレベルの高速化に成功!
N(長く)K(苦しい)T(戦いだった)・・・
▲ページの先頭へ▲
まとめ
今はspeak文で上から5枚を使っているだけですがあとはdeck_sの配列の数字を+1ずつしていくだけで
4人のプレイヤーに均等に配る、互いに1枚ずつ引いていく、など
いろんなことが可能になります(´・ω・`)
また、deck[1][0]=1,deck[1][1]="スペードの1" のように更に配列を仕込むことで
speakに表示する際は「スペードの1」と表示するということもできるはずです(`・ω・´)
↑を応用したものは後日じわじわと仕上げて行きます
本格的なトランプゲームもこれなら作れますねぇ・・・
▲ページの先頭へ▲
【追記】
a = "53万"
speak("私の戦闘力数は" + a + "です") ・・・①
speak("私の戦闘力数は" , a , "です") ・・・②
この①と②、同じ処理なんですね(´・ω・`)
なんか見た目がすっきりするので下の方が好きです(´・ω・`)
それでは、ここまで閲覧ありがとうございました三 ヾ(⌒(厂 ˙ω˙ )厂 ウェーイ
ツイート
※ついでにRmake記法を試してみたかったんです許してください何でもしますから
課題:ジョーカー含む計53枚のトランプからランダムに5枚を引く手段の模索
→配列0~52に入れた数字をランダムに入れ替えると解釈
目次----------------------------------------------
----------------------------------------------------
1.とりあえず配列0~52に0~52の数字をそれぞれ入れていくよ
r = 0 #whileで繰り返す(repetitionの頭文字)のに使用 deck = createArray() #deckという変数に配列を用意する魔法の言葉、createArray() while r < 53 deck[r] = r r = r + 1 end
これにより
変数名 | [0] | [1] | [2] | [3] | [4] | [5] | [6] | [7] | ... | [52] |
---|---|---|---|---|---|---|---|---|---|---|
deck | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ... | 52 |
この数字をランダムに入れ替える、つまり
変数名 | [0] | [1] | [2] | [3] | [4] | [5] | [6] | [7] | ... | [52] |
---|---|---|---|---|---|---|---|---|---|---|
deck_s(所謂コピー) | 4 | 0 | 1 | 9 | 40 | 19 | 7 | 50 | ... | 27 |
▲ページの先頭へ▲
2.でもrand関数使えそうじゃない?
使えないって決め付けるのは三流のやることです、考え次第ではどうにかなるでしょう(適当)
使う変数
r ...whileで繰り返すのに使う変数
deck ...[0]~[52]に0~52を順番通りにセットした配列
deck_s ...deck内をランダムに入れ替えた(shuffleの頭文字)配列、言わば今回の目標
r_s ...whileでdeck_sをランダムに入れ替えるのに使う変数
(r,r_s共に0を代入しておく) rand(53)を使って0~52の数字をランダムに変数a(仮)にセット ↓ while ┃deck[r]の中身がaと同じかどうか検証 ┃↓ ┃・同じならdeck[r]の中身を-1(0~52ではない数字)に変更、deck_s[r_s]にrを代入、r_sを+1 ┃・違うなら特に何も ┃↓ ┗rを+1
・・・う~んと?適当に組んだけどこれいろいろおかしいな(´・ω・`)
・rand関数でランダムに数字を呼び出す
・deck[0]~[52]のどこにその数字があるかをwhileで見つけ出し、そのdeckを使い物にならなくする
これを53回繰り返すことで「シャッフルしたあとのデッキ」が完成する、はず・・・
あ、見つけたらrandからやり直しにすればいいのか・・・いきなりスクリプトに起こした方が早そうね
r = 0 deck = createArray() while r < 53 deck[r] = r r = r + 1 end #-------------------------↓追加↓---------------------------- r_s = 0 #deck_sに使う配列の変数 a = 0 #rand関数で出たものを入れる変数 deck_s = createArray() #シャッフル後のデッキの配列 while r_s < 53 #deck_sの配列が52を越える、それは[0]~[52]が入った証 r = 0 #また繰り返しに使う変数 a = rand(53) while r < 53 if deck[r] == a #もしランダムに取り出した数aがdeck[0](初回)に入っている0だった場合 deck[r] = -1 #deck[0]の中身を-1にして今後検知されないようにする deck_s[r_s] = a #deck_s[0]にランダムに取り出した数a(=0)を代入する r_s = r_s + 1 #deck_sの配列の数字が次の段階へ r = 53 #めんどくさいのでもうaの数字探すループ抜けようぜ end r = r + 1 #見つかろうか見つからなかろうがとりあえず+1はしようや end end speak("上から順番に",deck_s[0],"、",deck_s[1],"、",deck_s[2],"、",deck_s[3],"、",deck_s[4],"でした")
なーんで私のスクリプトはこんな複雑に見えるんだ
これで全配列を探し回ってランダムに並び替えることに成功した、これで目標は達成したと思いきや・・・
▲ページの先頭へ▲
3.時間かかり過ぎ問題
speak("はじめるよ") #---------------追加-------------- time1 = getLocalCurrentTimeMillisecond() #---------------追加-------------- r = 0 deck = createArray() while r < 53 deck[r] = r r = r + 1 end r_s = 0 a = 0 deck_s = createArray() while r_s < 53 r = 0 a = rand(53) while r < 53 if deck[r] == a deck[r] = -1 deck_s[r_s] = a r_s = r_s + 1 a = -1 r = 53 end r = r + 1 end end time2 = getLocalCurrentTimeMillisecond() #---------------追加-------------- time3 = time2 - time1 #---------------追加-------------- speak("上から順番に",deck_s[0],"、",deck_s[1],"、",deck_s[2],"、",deck_s[3],"、",deck_s[4],"でした\nこの処理にかかった時間は",time3,"ミリ秒でした")#---------------変更--------------
スクリプトをこのように変更し、処理にかかる時間を計測しました
計測した結果、この処理にかかる時間は900~1200ミリ秒、
秒にして0.9~1.2秒の処理が必要となってしまうのです(´・ω・`)
当然ですね、aに8が入って8が処理されたあと、
もう一度aに8が入ったら全部探した挙句ありませんでした状態ですので(´・ω・`)
さて・・・どうしたものか・・・
そもそもwhileで探す必要なくない?
まさかの今までの考え全否定である
deck[7]には最初7が入っているとわかってるのになぜ全部探しているんだ・・・?(´・ω・`)
つまりaにランダムで数字を入れたらdeck[a]がaと同じかどうかを検証したいだけだ・・・あれすっごい単純
speak("はじめるよ") time1 = getLocalCurrentTimeMillisecond() r = 0 deck = createArray() while r < 53 deck[r] = r r = r + 1 end #-------------------------↓変更↓---------------------------- r = 0 a = 0 deck_s = createArray() while r < 53 a = rand(53) if deck[a] == a #もしdeck[a]がa(要約するとまだ選ばれていない)なら deck[a] = -1 #deck[a]を-1(言わば使用済み)にする deck_s[r] = a #そしてdeck_s[(初回なら0)]にaを代入する r = r + 1 #そしてdeck_sの配列は次のステージへ・・・ end end time2 = getLocalCurrentTimeMillisecond() time3 = time2 - time1 speak("上から順番に",deck_s[0],"、",deck_s[1],"、",deck_s[2],"、",deck_s[3],"、",deck_s[4],"でした\nこの処理にかかった時間は",time3,"ミリ秒でした")
これで計測した結果、なんと15~50ミリ秒!全く気にならないレベルの高速化に成功!
N(長く)K(苦しい)T(戦いだった)・・・
▲ページの先頭へ▲
まとめ
speak("はじめるよ") time1 = getLocalCurrentTimeMillisecond() r = 0 deck = createArray() while r < 53 deck[r] = r r = r + 1 end r = 0 a = 0 deck_s = createArray() while r < 53 a = rand(53) if deck[a] == a deck[a] = -1 deck_s[r] = a r = r + 1 end end time2 = getLocalCurrentTimeMillisecond() time3 = time2 - time1 speak("上から順番に",deck_s[0],"、",deck_s[1],"、",deck_s[2],"、",deck_s[3],"、",deck_s[4],"でした\nこの処理にかかった時間は",time3,"ミリ秒でした")
今はspeak文で上から5枚を使っているだけですがあとはdeck_sの配列の数字を+1ずつしていくだけで
4人のプレイヤーに均等に配る、互いに1枚ずつ引いていく、など
いろんなことが可能になります(´・ω・`)
また、deck[1][0]=1,deck[1][1]="スペードの1" のように更に配列を仕込むことで
speakに表示する際は「スペードの1」と表示するということもできるはずです(`・ω・´)
↑を応用したものは後日じわじわと仕上げて行きます
本格的なトランプゲームもこれなら作れますねぇ・・・
▲ページの先頭へ▲
【追記】
a = "53万"
speak("私の戦闘力数は" + a + "です") ・・・①
speak("私の戦闘力数は" , a , "です") ・・・②
この①と②、同じ処理なんですね(´・ω・`)
なんか見た目がすっきりするので下の方が好きです(´・ω・`)
それでは、ここまで閲覧ありがとうございました三 ヾ(⌒(厂 ˙ω˙ )厂 ウェーイ
コメントする
コメントするには、ログインする必要があります。
コメント一覧
純粋にシャッフルして
上から引く、でも早くできそう
上から引く、でも早くできそう
time1 = getLocalCurrentTimeMillisecond() #下準備 deck = createArray() i = 0; ilen = 53 while i < ilen deck[i] = i i = i + 1 end #シャッフル r = 0; n = 0 i = 0; ilen = 53 while i < ilen r = rand(ilen - i) + i n = deck[i] deck[i] = deck[r] deck[r] = n i = i + 1 end #必要な枚数取り出す deck_s = createArray() i = 0; ilen = 5 while i < ilen deck_s[i] = deck[i] i = i + 1 end #結果表示 time2 = getLocalCurrentTimeMillisecond() time3 = time2 - time1 speak(deck_s[0] + ":" + deck_s[1] + ":" + deck_s[2] + ":" + deck_s[3] + ":" + deck_s[4] + "\n time" + time3)
https://rmake.jp/wikis/391/
既にあったのですね(w
なぜ先に調べておかなかったんだ・・・(´;ω;`)
お二人ともわざわざありがとうございます_(:3 」∠)_
ちなみに追記のやつ、私①派です、なぜなら…
時々カンマにピリオドが混じってくるからです(´;ω;`)
ピリオドと見分けがつかないというのはつらいですね・・・
+がなかなかにでかくてごちゃごちゃしちゃうのでやっぱり②派です(`・ω・´)
みなさんのスクリプト見てるとほとんど②派のようですね('ω'っ)3