×

[PR]この広告は3ヶ月以上更新がないため表示されています。
ホームページを更新後24時間以内に表示されなくなります。

ゲームを作ろう! ポーカーその1 カードを並べよう


トランプゲームのひとつ、ポーカーをSmall Basicで作ってみます。
といっても私はポーカーといったらド○クエのカジノのルールしかわかりません。
なので、ここで作るのはコンピュータ相手に1対1で遊ぶ、いわゆるビデオポーカーです。

さて、どう作れば良いでしょうか。
チップはさておいて、カードのことを考えましょう。
ド○クエ式ポーカーはまず、5枚カードを手札とし、各カードを残すか交換するかを決めてカードを配り、5枚のカードで出来た役で勝ち負けを競う、という流れです。
カードの交換を考えると、最初にトランプの中から10枚をランダムで選んでおけば良さそうです。
ややこしくなるので、ジョーカーはなしにします。
とすると、トランプは全部で52枚です。
ランダムな数字を獲得する、

Math.GetRandomNumber(52)

これで1から52のうち、ひとつの数字を選んでくれます。

1〜13:ハートの1〜13
14〜26:ダイヤの1〜13
27〜39:クラブの1〜13
40〜52:スペードの1〜13

と、しましょう。
問題は、「1枚目で選んだカードを2枚目以降では選んではいけない」ということです。
2枚目も同じく、Math.GetRandomNumber(52)でランダムな数字を選びますが、1枚目とは違う数字が出るまでループで計算をさせればよいでしょう。
1枚目を「number[1]」、2枚目を「number[2]」とすると、

number[1] = Math.GetRandomNumber(52)

trp2:
number[2] = Math.GetRandomNumber(52)
If (number[1] = number[2]) Then
  Goto trp2
EndIf

2枚目は、Gotoループで「もしnumber[1] = number[2]なら乱数を再取得」としています。
これを10枚分繰り返しても良いのですが、長ったらしくなりそうです。
縮められないか考えてみます。
「最初に10枚ランダムで生成して、その10枚をひたすら比較する」のはどうでしょうか?
ひたすら比較の方法さえわかればどうにかできそうです。
比較は「1枚目と2枚目を比較」を「1・2」と書くと、比較する枚数はこんな感じ。

1・2
1・3
1・4
……
1・10
2・3
2・4
2・5
……
2・10
3・4
……
9・10

このように、規則性があります。
For構文を上手く使えばなんとかなるかな?

'トランプ10枚分ランダム作成
trp:
For i = 1 To 10
  number[i] = Math.GetRandomNumber(52)
EndFor

For x = 1 To 8
  For i = x To 9
    If (number[x] = number[i+1]) Then
      Goto trp
    EndIf
  EndFor
EndFor

こんな感じで、被らない10個の数字=トランプ10枚を生成できます。
なお、この方法は「52の数字から被らない10個の数字を選ぶまでループさせる」であり、確率としてもそんなに低くないため生成に時間はかかりません。
しかし、選ぶ数字が多くなると確率がぐっと下がるためにループ回数がどんどん増えて、プログラムの処理が追いつかなくなります。
上の方法を他のプログラムで使う時はご注意を。

初期段階では、number[1]〜number[5]をトランプのカードの数字に変換して並べます。
ちなみに、ハートマークなどは
Text.GetCharacter(characterCode)
という、Unicode文字コード変換オブジェクトを使います。
Unicodeって何? という説明はこのサイトではしませんが、文字とか記号に番号が振ってあると思ってください。
Unicode - Wikipedia
例えば、ハートマークの場合その番号が「9829」なので、
Text.GetCharacter(9829)
これでハートマークを表示できます。他のマークは、

Text.GetCharacter(9830)……ダイヤ
Text.GetCharacter(9827)……クラブ
Text.GetCharacter(9824)……スペード

です。

「トランプのカードの数字に変換」とあっさり書きましたが、実際は色々とめんどくさいです。
トランプの場合は、1はAだし、11はJだし、12はQで13はKですね。
乱数で得た「number[1]」を「トランプのカードの数字に変換」するにはどうしたら良いか?

まず、マークから考えます。
最初に決めたとおり、

1〜13:ハートの1〜13
14〜26:ダイヤの1〜13
27〜39:クラブの1〜13
40〜52:スペードの1〜13

です。
カード5枚を順に並べるので、ForToを上手く使うとまとめて書けそう。
まず、「number[1]〜[5]がハート」と仮定して書いてみます。

For n = 1 To 5 'number[1]〜[5]
  For x = 1 To 13 'ハートの1〜13
    If number[n] = x Then
      GraphicsWindow.BrushColor = "Red"
      Pos1a[n] = Shapes.AddText(Text.GetCharacter(9829)) 'Pos1aはカードのマーク位置
      Shapes.Move(Pos1a[n], 100*n, 80)
      If x=1 Then
        Pos1b[n] = Shapes.AddText("A") 'Pos1bはカードの数字位置
        Shapes.Move(Pos1b[n], 100*n, 150)
      ElseIf x=11 Then
        Pos1b[n] = Shapes.AddText("J")
        Shapes.Move(Pos1b[n], 100*n, 150)
      ElseIf x=12 Then
        Pos1b[n] = Shapes.AddText("Q")
        Shapes.Move(Pos1b[n], 100*n, 150)
      ElseIf x=13 Then
        Pos1b[n] = Shapes.AddText("K")
        Shapes.Move(Pos1b[n], 100*n, 150)
      Else
        Pos1b[n] = Shapes.AddText(x) 'A、J、Q、K以外は数字なので、そのまま記述する
        Shapes.Move(Pos1b[n], 100*n, 150)
      EndIf
    EndIf
  EndFor
EndFor

これで試してみたのですが、ハートマークと文字位置をちょっとズラさないとダメだな、と気づきました。
また、これで実行すると、数字の「10」だけが2文字なので、「10」のみ位置を配慮した方が良いです。

ということで、トランプを5枚並べるプログラムは以下の通り。

GraphicsWindow.Title = "poker"
GraphicsWindow.Width = 640
GraphicsWindow.Height = 480
GraphicsWindow.CanResize = "False"
GraphicsWindow.BackgroundColor = "LightGreen"

mojicolor = "Black"
bgcolor = "White"

GraphicsWindow.FontName = "Meiryo UI"
GraphicsWindow.FontSize = 15
GraphicsWindow.BrushColor = mojicolor

trumpbutton = Controls.AddButton("ゲーム開始", 80, 20)
Controls.Move(trumpbutton, 1, 1)

koukan1button = Controls.AddButton("交換", 30, 20)
Controls.Move(koukan1button, 110, 250)

koukan2button = Controls.AddButton("交換", 30, 20)
Controls.Move(koukan2button, 210, 250)

koukan3button = Controls.AddButton("交換", 30, 20)
Controls.Move(koukan3button, 310, 250)

koukan4button = Controls.AddButton("交換", 30, 20)
Controls.Move(koukan4button, 410, 250)

koukan5button = Controls.AddButton("交換", 30, 20)
Controls.Move(koukan5button, 510, 250)

nokosu1button = Controls.AddButton("残す", 30, 20)
Controls.Move(nokosu1button, 110, 250)

nokosu2button = Controls.AddButton("残す", 30, 20)
Controls.Move(nokosu2button, 210, 250)

nokosu3button = Controls.AddButton("残す", 30, 20)
Controls.Move(nokosu3button, 310, 250)

nokosu4button = Controls.AddButton("残す", 30, 20)
Controls.Move(nokosu4button, 410, 250)

nokosu5button = Controls.AddButton("残す", 30, 20)
Controls.Move(nokosu5button, 510, 250)

kubarubutton = Controls.AddButton("配る", 30, 20)
Controls.Move(kubarubutton, 310, 290)

Controls.HideControl(koukan1button)
Controls.HideControl(koukan2button)
Controls.HideControl(koukan3button)
Controls.HideControl(koukan4button)
Controls.HideControl(koukan5button)
Controls.HideControl(nokosu1button)
Controls.HideControl(nokosu2button)
Controls.HideControl(nokosu3button)
Controls.HideControl(nokosu4button)
Controls.HideControl(nokosu5button)
Controls.HideControl(kubarubutton)

Controls.ButtonClicked = trumpnarabe

Sub trumpnarabe
  Sound.PlayClick()
  If Controls.LastClickedButton = trumpbutton Then
    
'トランプ10枚分ランダム作成
trp:
For i = 1 To 10
  number[i] = Math.GetRandomNumber(52)
EndFor

For x = 1 To 8
  For i = x To 9
    If (number[x] = number[i+1]) Then
      Goto trp
    EndIf
  EndFor
EndFor

  Controls.ShowControl(koukan1button)
  Controls.ShowControl(koukan2button)
  Controls.ShowControl(koukan3button)
  Controls.ShowControl(koukan4button)
  Controls.ShowControl(koukan5button)
  Controls.ShowControl(kubarubutton)
  Controls.HideControl(trumpbutton)

  For i = 1 To 5
    GraphicsWindow.BrushColor = bgcolor
    GraphicsWindow.FillRectangle(90+100*(i-1), 90, 80, 140)
  EndFor
  
  'トランプを5枚配置
  GraphicsWindow.FontSize =60
  For n = 1 To 5
    For x = 1 To 52
      If number[n] = x Then
        If 1 <= x And x <= 13 Then
          GraphicsWindow.BrushColor = "Red"
          Pos1a[n] = Shapes.AddText(Text.GetCharacter(9829))
          Shapes.Move(Pos1a[n], 100*n, 80)
        EndIf
        If 14 <= x And x <= 26 Then
          GraphicsWindow.BrushColor = "Red"
          Pos1a[n] = Shapes.AddText(Text.GetCharacter(9830))
          Shapes.Move(Pos1a[n], 100*n, 80)
        EndIf
        If 27 <= x And x <= 39 Then
           GraphicsWindow.BrushColor = mojicolor
           Pos1a[n] = Shapes.AddText(Text.GetCharacter(9827))
           Shapes.Move(Pos1a[n], 100*n, 80)
        EndIf
        If 40 <= x And x <= 52 Then
          GraphicsWindow.BrushColor = mojicolor
          Pos1a[n] = Shapes.AddText(Text.GetCharacter(9824))
          Shapes.Move(Pos1a[n], 100*n, 80)
        EndIf
      If x=1 or x=1+13 Then
          GraphicsWindow.BrushColor = "Red"
          Pos1b[n] = Shapes.AddText("A")
          Shapes.Move(Pos1b[n], 100*n+7, 150)
        ElseIf x=10 or x=10+13 Then
          GraphicsWindow.BrushColor = "Red"
          Pos1b[n] = Shapes.AddText("10")
          Shapes.Move(Pos1b[n], 100*n-11, 150)
        ElseIf x=11 or x=11+13 Then
          GraphicsWindow.BrushColor = "Red"
          Pos1b[n] = Shapes.AddText("J")
          Shapes.Move(Pos1b[n], 100*n+7, 150)
        ElseIf x=12 or x=12+13 Then
          GraphicsWindow.BrushColor = "Red"
          Pos1b[n] = Shapes.AddText("Q")
          Shapes.Move(Pos1b[n], 100*n+7, 150)
        ElseIf x=13 or x=13+13 Then
          GraphicsWindow.BrushColor = "Red"
          Pos1b[n] = Shapes.AddText("K")
          Shapes.Move(Pos1b[n], 100*n+7, 150)
        ElseIf x=1+13*2 or x=1+13*3 Then
          GraphicsWindow.BrushColor = mojicolor
          Pos1b[n] = Shapes.AddText("A")
          Shapes.Move(Pos1b[n], 100*n+7, 150)
        ElseIf x=10+13*2 or x=10+13*3 Then
          GraphicsWindow.BrushColor = mojicolor
          Pos1b[n] = Shapes.AddText("10")
          Shapes.Move(Pos1b[n], 100*n-11, 150)
        ElseIf x=11+13*2 or x=11+13*3 Then
          GraphicsWindow.BrushColor = mojicolor
          Pos1b[n] = Shapes.AddText("J")
          Shapes.Move(Pos1b[n], 100*n+7, 150)
        ElseIf x=12+13*2 or x=12+13*3 Then
          GraphicsWindow.BrushColor = mojicolor
          Pos1b[n] = Shapes.AddText("Q")
          Shapes.Move(Pos1b[n], 100*n+7, 150)
        ElseIf x=13+13*2 or x=13+13*3 Then
          GraphicsWindow.BrushColor = mojicolor
          Pos1b[n] = Shapes.AddText("K")
          Shapes.Move(Pos1b[n], 100*n+7, 150)
        Else
        If 1+1 <= x And x <= 13-4 Then
          GraphicsWindow.BrushColor = "Red"
          Pos1b[n] = Shapes.AddText(x)
          Shapes.Move(Pos1b[n], 100*n+7, 150)
        EndIf
        If 14+1 <= x And x <= 26-4 Then
          GraphicsWindow.BrushColor = "Red"
          Pos1b[n] = Shapes.AddText(x-13)
          Shapes.Move(Pos1b[n], 100*n+7, 150)
        EndIf
        If 27+1 <= x And x <= 39-4 Then
           GraphicsWindow.BrushColor = mojicolor
          Pos1b[n] = Shapes.AddText(x-13*2)
          Shapes.Move(Pos1b[n], 100*n+7, 150)
        EndIf
        If 40+1 <= x And x <= 52-4 Then
          GraphicsWindow.BrushColor = mojicolor
          Pos1b[n] = Shapes.AddText(x-13*3)
          Shapes.Move(Pos1b[n], 100*n+7, 150)
        EndIf
        EndIf
      EndIf
    EndFor
  EndFor
EndIf

ポーカー

ポーカー

こんな感じです。
次回に続く。

次:その2 カード交換


▲TOPへ戻る