配列奮闘記~second~

投稿者:           mini naoki4019 投稿日:2017/02/23 21:08

※個人で頑張って奮闘してるだけの日記なので生暖かい目で見てあげてください
※この日記は前回の続きです
※コメント欄で教えてもらったシャッフル関数は使ってません、ちょっとよくわからないので0(:3 _ )~

課題:ジョーカー含む計53枚のトランプからランダムに引いた5枚を数字順に並び替える


目次----------------------------------------------
----------------------------------------------------





1.まずやりたいことの整理

r = 0
deck = createArray()
 while r < 53
  deck[r] = createArray()
  deck[r][0] = r
  r = r + 1
 end
deck[0][1] = "ジョーカー"
deck[1][1] = "スペードのA"
deck[2][1] = "ハートのA"
deck[3][1] = "ダイヤのA"
deck[4][1] = "クローバーのA"
deck[5][1] = "スペードの2"
#(以下省略)

これで
変数名[0][1]
deck[0]0"ジョーカー"
deck[1]1"スペードのA"
deck[2]2"ハートのA"
deck[3]3"ダイヤのA"
deck[4]4"クローバーのA"
deck[5]5"スペードの2"
と入れることに成功した、deck[r][1]の部分が全部手書きでめんどうだけどそれはもうしょうがない(´・ω・`)

つまり今回の目標は
「前回の日記のスクリプトでランダムに引いた5枚をdeck{r}{0}の小さい順に並び替え、deck{r}{1}の文を取り出す」
ということですね(´・ω・`)

そういえば他のブログ見てて見つけたのですが「;」をつけると改行しなくても動作してくれるんですね(´・ω・`)
a = "53万" ; speak("私の戦闘力数は" , a , "です")
#「私の戦闘力数は53万です」と表示される

a = 4019 b = "マジやばくね?"   #この変数の場合「;」がなくても空白で機能する模様、知らなかった・・・
speak("私の戦闘力数が" , a , "に下がりました。",b,"")
 #「私の戦闘力数が4019に下がりました。マジやばくね?」と表示される


▲ページの先頭へ▲




2.具体的な解決法を簡略化したスクリプトで模索

a = createArray()
a[0] = createArray()
a[1] = createArray()
a[2] = createArray()
a[3] = createArray()
a[4] = createArray()
a[0][0] = 3         ; a[0][1] = "かっ"
a[1][0] = 1         ; a[1][1] = "はっ"
a[2][0] = 123456789 ; a[2][1] = "しおっ!"
a[3][0] = 9         ; a[3][1] = "のっ"
a[4][0] = 4         ; a[4][1] = "たっ"

早速「;」を利用して見やすく(´・ω・`)
※やっていることを視覚的にもわかりやすくするため今はwhileを使っていません
a = createArray()
a[0] = createArray()
a[1] = createArray()
a[2] = createArray()
a[3] = createArray()
a[4] = createArray()
a[0][0] = 3         ; a[0][1] = "かっ"
a[1][0] = 1         ; a[1][1] = "はっ"
a[2][0] = 123456789 ; a[2][1] = "しおっ!"
a[3][0] = 9         ; a[3][1] = "のっ"
a[4][0] = 4         ; a[4][1] = "たっ"

#ここに並べ替え処理を挟み、bに代入する

speak(b[0],b[1],b[2],b[3],b[4])

これでa[r][0]の数字を
3→1→123456789→9→4から1→3→4→9→123456789
と並び替え、a[r][1]も同様に並び替えてb[r]に代入し、
最後のspeakで「はっかったっのっしおっ!」と完成させるのが理想です(`・ω・´)
_人人人人人人人人人_
> 突然の伯方の塩 <
 ̄Y^Y^Y^Y^Y^Y^Y^Y ̄

▲ページの先頭へ▲




3.そうは言っても並び替えってどうすんのよ

さて、並び替え・・・なら
a[r][0]が0かどうかの判定、rが5になったら0にして
a[r][0]が1かどうかの判定、rが5になったら(ry

として当てはまったらbに随時代入していけばいいんだ(´・ω・`)
a = createArray()
a[0] = createArray()
a[1] = createArray()
a[2] = createArray()
a[3] = createArray()
a[4] = createArray()
a[0][0] = 3         ; a[0][1] = "かっ"
a[1][0] = 1         ; a[1][1] = "はっ"
a[2][0] = 123456789 ; a[2][1] = "しおっ!"
a[3][0] = 9         ; a[3][1] = "のっ"
a[4][0] = 4         ; a[4][1] = "たっ"
b = createArray() #完成形
c = 0 #カウント用
r = 0 #配列の数字用
r2 = 0 #数字模索用

while c < 5 #説明では「cループ」とする
 while r < 5 #説明では「rループ」とする
  if a[r][0] == r2
    b[c] = a[r][1]
    c = c + 1
    r = 5
  else
    r = r + 1
  end
 end
 r = 0
 r2 = r2 + 1
end
speak(b[0],b[1],b[2],b[3],b[4])

スクリプトとしてはこうだ、実際に順を追って考える

変数名[0][1]
a[0]3"かっ"
a[1]1"はっ"
a[2]123456789"しおっ!"
a[3]9"のっ"
a[4]4"たっ"
・まず最初にa[0][0]が0かどうか?違うのでrに+1される
・次にa[1][0]が0かどうか、これをa[4][0]まで繰り返すが全て失敗
・a[4][0]に失敗するとrは5になりrループを脱出
・脱出したらrを0、r2を+1してもう一度rループを始める
・a[0][0]が1かどうか?違うのでrに+1
・a[1][0]が1かどうか?そうなんです!
・するとb[0]にa[1][1]、"はっ"を代入します
・その後cに+1をして次のb[1]に入る言葉を捜します、rは5にして強制的にrループ脱出
・rループを脱出したのでrを0、r2を+1してもう一度rループ開始
・(中略)
・これを続けてcが5になる(=b[0]~b[4]まで埋まる)とrループ脱出後cループを脱出


こうすれば最終的に
変数名[0]
b[0]"はっ"
b[1]"かっ"
b[2]"たっ"
b[3]"のっ"
b[4]"しおっ!"
となり、speak(b[0],b[1],b[2],b[3],b[4])で「はっかったっのっしおっ!」が完成するはずです!やったね解決だ!

▲ページの先頭へ▲




4.時間かかり過ぎ問題

speak("はじめるよ")
time1 = getLocalCurrentTimeMillisecond()

a = createArray()
a[0] = createArray()
a[1] = createArray()
a[2] = createArray()
a[3] = createArray()
a[4] = createArray()
a[0][0] = 3         ; a[0][1] = "かっ"
a[1][0] = 1         ; a[1][1] = "はっ"
a[2][0] = 123456789 ; a[2][1] = "しおっ!"
a[3][0] = 9         ; a[3][1] = "のっ"
a[4][0] = 4         ; a[4][1] = "たっ"

b = createArray() #完成形
c = 0 #カウント用
r = 0 #配列の数字用
r2 = 0 #数字模索用
time1 = 
while c < 5
 while r < 5
  if a[r][0] == r2
    b[c] = a[r][1]
    c = c + 1
    r = 5
  else
    r = r + 1
  end
 end
 r = 0
 r2 = r2 + 1
end
time2 = getLocalCurrentTimeMillisecond()
time3 = time2 - time1
speak("",b[0],b[1],b[2],b[3],b[4],"\nかかった時間は",time3,"ミリ秒です")

先生、ゲームが応答してませんまるで成長していない・・・
そりゃぁこの例で言うと1億まで見ないといけないからね・・・1つだけ数字を跳ね上げたのはこのため、
どれだけ数字の差が大きくても使えるスクリプトじゃないと汎用性に優れないからね(´・ω・`)

▲ページの先頭へ▲




5.こうなったら別の方法だ

この時のためにもうひとつ考えていたこともある、それが
a{0}{0}とa{1}{0}はどっちが大きいかなー、などを繰り返してどうにかして並べる
というアバウトにもほどがある方法である(´・ω・`)

・案その1:総当たり戦
a[0][0]がa[1][0]より大きければ+1点、小さければ0点
a[0][0]がa[2][0]より大きければ+1点、小さければ0点...のように
総当たり戦をやります
a[0][0]a[1][0]a[2][0]a[3][0]a[4][0]総合得点
a[0][0]-点
a[1][0]-点
a[2][0]-点
a[3][0]-点
a[4][0]-点
こんな感じ、実際に試す
3112345678994総合得点
3×××1点
1××××0点
1234567894点
9×3点
4××2点
結果を点数低い順に並べると
1(0点)→3(1点)→4(2点)→9(3点)→123456789(4点)と・・・

あ、これじゃん

▲ページの先頭へ▲




6.ウィニングラン

これを早速スクリプトにまとめていきます
speak("はじめるよ")
time1 = getLocalCurrentTimeMillisecond()

a = createArray()
a[0] = createArray()
a[1] = createArray()
a[2] = createArray()
a[3] = createArray()
a[4] = createArray()
a[0][0] = 3                 ; a[0][1] = "かっ"         ;a[0][2] = 0
a[1][0] = 1                 ; a[1][1] = "はっ"         ;a[1][2] = 0
a[2][0] = 123456789 ; a[2][1] = "しおっ!"  ;a[2][2] = 0
a[3][0] = 9                 ; a[3][1] = "のっ"         ;a[3][2] = 0
a[4][0] = 4                 ; a[4][1] = "たっ"         ;a[4][2] = 0

b = createArray()
r = 0
r2 = 0
while r < 5
 while r2 < 5
    if a[r][0] > a[r2][0] #勝った場合は+1点,負けor同じ(比べている数字が被っている)場合は±0点
        a[r][2] = a[r][2] + 1
    end
   r2 = r2 + 1
 end
 r = r + 1
 r2 = 0
end

r = 0
r2 = 0 #rとr2の使いまわしである、なんてブラックな・・・
while r2 < 5
 while r < 5
    if a[r][2] == r2  #最初はa[r][2]が0のところを探してa[r][1]をb[0]に代入している
       b[r2] = a[r][1]
       r = 5
    end
   r = r + 1
 end
r = 0
r2 = r2 + 1
end

time2 = getLocalCurrentTimeMillisecond()
time3 = time2 - time1
speak("",b[0],b[1],b[2],b[3],b[4],"\nかかった時間は",time3,"ミリ秒です")

これにかかる時間は脅威の6ミリ秒!一瞬も間を感じません。゚+.(*`・∀・´*)゚+.゚

▲ページの先頭へ▲




まとめ

本来の目的であるトランプに置き換えます
speak("はじめるよ")
time1 = getLocalCurrentTimeMillisecond()

r = 0
deck = createArray()
 while r < 53
  deck[r] = createArray()
  deck[r][0] = r
  r = r + 1
 end
#ここまででdeck[r][0]を生み出しIDを振り分けた

deck[0][1] = "ジョーカー"
deck[1][1] = "スペードのA"   ;deck[2][1] = "ハートのA"   ;deck[3][1] = "ダイヤのA"  ;deck[4][1] = "クローバーのA"
deck[5][1] = "スペードの2"   ;deck[6][1] = "ハートの2"   ;deck[7][1] = "ダイヤの2"  ;deck[8][1] = "クローバーの2"
deck[9][1] = "スペードの3"   ;deck[10][1] = "ハートの3"  ;deck[11][1] = "ダイヤの3" ;deck[12][1] = "クローバーの3"
deck[13][1] = "スペードの4"  ;deck[14][1] = "ハートの4"  ;deck[15][1] = "ダイヤの4" ;deck[16][1] = "クローバーの4"
deck[17][1] = "スペードの5"  ;deck[18][1] = "ハートの5"  ;deck[19][1] = "ダイヤの5" ;deck[20][1] = "クローバーの5"
deck[21][1] = "スペードの6"  ;deck[22][1] = "ハートの6"  ;deck[23][1] = "ダイヤの6" ;deck[24][1] = "クローバーの6"
deck[25][1] = "スペードの7"  ;deck[26][1] = "ハートの7"  ;deck[27][1] = "ダイヤの7" ;deck[28][1] = "クローバーの7"
deck[29][1] = "スペードの8"  ;deck[30][1] = "ハートの8"  ;deck[31][1] = "ダイヤの8" ;deck[32][1] = "クローバーの8"
deck[33][1] = "スペードの9"  ;deck[34][1] = "ハートの9"  ;deck[35][1] = "ダイヤの9" ;deck[36][1] = "クローバーの9"
deck[37][1] = "スペードの10";deck[38][1] = "ハートの10";deck[39][1] = "ダイヤの10";deck[40][1] = "クローバーの10" 
deck[41][1] = "スペードのJ"  ;deck[42][1] = "ハートのJ"  ;deck[43][1] = "ダイヤのJ" ;deck[44][1] = "クローバーのJ"
deck[45][1] = "スペードのQ"  ;deck[46][1] = "ハートのQ"  ;deck[47][1] = "ダイヤのQ" ;deck[48][1] = "クローバーのQ"
deck[49][1] = "スペードのK"  ;deck[50][1] = "ハートのK"  ;deck[51][1] = "ダイヤのK" ;deck[52][1] = "クローバーのK"
#ここまででdeck[r][1]にカード名を振り分けた

r = 0
a = 0
deck_s = createArray()
while r < 53
a = rand(53)
   if deck[a][0] == a
      deck[a][0] = -1
      deck_s[r] = createArray()
      deck_s[r][0] = a
      deck_s[r][1] = deck[a][1]
      r = r + 1
   end
end
#ここでdeckをシャッフルしてdeck_sに代入した

r = 0
hand = createArray()
while r < 5
 hand[r] = createArray()
 hand[r][0] = deck_s[r][0]
 hand[r][1] = deck_s[r][1]
 hand[r][2] = 0
 r = r + 1
end

#ここまででhandという配列にシャッフルしたデッキの上から5枚の内容をコピーできました
#このhandを並び替え、hand_aという配列に代入します
r = 0
r2 = 0
while r < 5
  while r2 < 5
    if hand[r][0] > hand[r2][0]
       hand[r][2] = hand[r][2] + 1
    end
  r2 = r2 + 1
 end
r = r + 1
r2 = 0
end
#hand[r][2]に点数をつけ、並び替えの準備を始めた

r = 0
r2 = 0
hand_a = createArray()
while r2 < 5
 while r < 5
    if hand[r][2] == r2
       hand_a[r2] = hand[r][1]
       r = 5
    end
   r = r + 1
 end
r = 0
r2 = r2 + 1
end

time2 = getLocalCurrentTimeMillisecond()
time3 = time2 - time1
speak("引いたカードを並べると\n",hand_a[0],"、",hand_a[1],"、",hand_a[2],"、",hand_a[3],"、",hand_a[4],"です\nかかった時間は",time3,"ミリ秒です")

うっわー複雑ぅ・・・
(何度かやってたら「ジョーカー」「ハートの8」「ダイヤの8」「クローバーの8」「ハートの10」が出た、フォーカードォ...)
時間を計測すると大体40~70ミリ秒、時間も全然問題ありませんね(´・ω・`)
変数rと変数r2の間違いで結構エラー吐きました、よいこのみんなはもっとわかりやすい変数名にしようね(´・ω・`)
これで順番に並べることができたぜ・・・この仕組みの応用によってdeck[r][3]以降に便利な目印でも振っておくと
ポーカーの役が判断できるようになります、次日記を書くならこれが目標ですかね(´・ω・`)
(多分ジョーカーの処理が課題の大半です)
CPUとのポーカー対戦ゲームもだいぶ現実的になってきた(´・ω・`)

▲ページの先頭へ▲

それでは、ここまで閲覧ありがとうございました三 ヾ(⌒(厂 ˙ω˙ )厂 ウェーイ

コメントする

コメントするには、ログインする必要があります。

コメント一覧

            mini mosmoss(投稿日:2017/02/23 21:35, 履歴)
名前付けは、自分だったらwhileの中で一緒にやっちゃいますね
インデックスの数値を13で割って商0ハート1スペード2クラブ3ダイヤ4ジョーカー
ジョーカー以外で余りに1足したものを数字
さらに数字が1の時A 11の時J 12の時Q 13の時K それ以外は数値のままにします
           mini naoki4019(投稿日:2017/02/23 21:47, 履歴)
なぬ、余りを求める手段があるのか・・・(´・ω・`)
とはいえやろうと思えば余りを出す手段はいくらでもあるか・・・面倒だけど(´・ω・`)

やはりそういう発想がないと難しいというかめんどくさいですねぇ・・・うらやましい_(:3 」∠)_
            mini mosmoss(投稿日:2017/02/23 21:51, 履歴)
気になって調べたんですが、
トランプ配列って、この記事で書かれてるような
AAAA22223333と作っていく方が運用しやすいみたいですね

読んだ記事ではマークと数字をそれぞれ数値で格納していました
a[0][1]=0(ハート)
a[0][2]=1(数字1) みたいな
           mini naoki4019(投稿日:2017/02/23 22:07, 履歴)
一応これから役を判断しやすいようにマークや数字、他の要素も入れるつもりです(´・ω・`)
極端な話をするとロイヤルストレートフラッシュの役を作れるカードの[3]に1を代入して
手札5枚のマークと[3]が同じ(全部同じマークandロイヤルストレートフラッシュを作れるカード)ならロイヤルストレートフラッシュと判断する!みたいな(´・ω・`)

次の日記に全役と判断の仕方はまとめるつもりです(`・ω・´)
            mini mosmoss(投稿日:2017/02/23 22:11, 履歴)
楽しみにしてます(^ω^っ)3
ソート関数
https://rmake.jp/wikis/157
           mini naoki4019(投稿日:2017/02/23 22:18, 履歴)
しれっと関数教えるあたり鬼畜ですね(褒め言葉)
なんか自分で試行錯誤するのが楽しいからあえて調べないって面もある_( _´ω`)_ペショ