手札捨て への返答

投稿で使用できる特殊コードの説明。(別タブで開きます。)
本名は入力しないようにしましょう。
投稿した後で削除するときに使うパスワードです。返答があった後は削除できません。
返答する人が目安にします。相手が小学生か社会人かで返答の仕方も変わります。
最初の投稿が質問の場合、質問者が解決時にチェックしてください。(以降も追加書き込み・返信は可能です。)
※「過去ログ」について書くときはその過去ログのURLも書いてください。

以下の返答は逆順(新しい順)に並んでいます。

投稿者 HiDE-Ada  (社会人) 投稿日時 2013/10/31 18:20:08
カードはどのように管理していますか?

たとえば、PictureBox1に表示されているカードは何のカードが
表示されているか、わかりますか?

というか、なんらかの方法、配列とかコレクションとかで管理していますか?

PictureBoxのTagプロパティを使用して管理してもいいです。

単に表示されている画像からカードを判断することはできません。
・・・厳密に言えば、不可ではないんでしょうけど^^;

どこかに表示中のカードの情報を管理しておかないと、何も判断できません。
投稿者 高橋だよ  (社会人) 投稿日時 2013/10/31 10:49:59
選択したカードが同じ数字のカードじゃないといけないようにしたいです。
投稿者 shu  (社会人) 投稿日時 2013/10/30 12:43:21
> 手札を選択し
が分からないのか

> 墓地に捨てる
が分からないのか

>選択したカードが同じ数字のカードじゃないといけないようにしたいです。 
が分からないのか

どこが分からないのでしょうか?

現在どのように実装されているのでしょうか?
投稿者 HiDE-Ada  (社会人) 投稿日時 2013/10/30 01:39:23
最初の質問をそのままの処理すればよいと思いますね。

1.選択されている2枚の数字を比較する。
 …ここは、カードのデータをどのように設計したかによります。
2.同じなら、PictureBox14へどちらかのカードを表示。
 …カードの値が違う場合は、どうする?
3.元の選択状態のカードをクリア
 …選択状態の解除も
4.必要なら、カードの整列を行う。

2.と3.はどちらが先でもかわらないでしょう。

もし、質問が見た目の問題でカードが移動していくように見せたい
ということであれば、まったく誤答ですね^^;
投稿者 るきお  (社会人) 投稿日時 2013/10/29 15:24:58
このような感じで1つずつ考えていけば、ババ抜きは作れると思います。

まとめると、
「やりたいこと」を「計算やデータの読み書きで表現してみる」
という『方向』で『考える』ことが重要で、
考える過程でわからないことを質問するのがもっとも有意義です。

その時は、途中まで考えたその考えも一緒に説明するようにしましょう。
たとえば、カードはcardsという変数でコレクションで管理しているとか、
そういう前提のことです。

長くなりました。
まずはどのような考えでプログラムを作っているか教えてください。
それを基にカードを捨てる方法を一緒に考えましょう。
投稿者 るきお  (社会人) 投稿日時 2013/10/29 15:23:56
さて、このカードを4人のプレイヤーに配ることにしましょう。
この段階でわからなければ、上記のプログラムを基にして、「プレイヤーにカードを配るためにはどういう構造にしたらよいか?」という切り口で質問しましょう。
上記のプログラムが基になっていれば、データの読み書きついてはいろいろとわかるので回答もしやすいです。
たとえば、
・すべてのカードはcards変数に格納されている。
・カードのマークはMarkプロパティを読めばわかる。
・カードの数字はNumberプロパティを読めばわかる。
という感じです。

さて、今回は4人のプレイヤーの手札を表現するために 4つのコレクションを追加しましょう。
Dim player1Cards As New List(Of Card)
    Dim player2Cards As New List(Of Card)
    Dim player3Cards As New List(Of Card)
    Dim player4Cards As New List(Of Card)

この4つのコレクションにカードを配りましょう。
すべてのカードはcardsの中にあるのでcardsからデータを読んで、プレイヤーのカードのコレクションにデータを書き込みましょう。

ここまで整えば、カードを配る方法はおおむね次のようになるはずです。
For i As Integer = 0 To cards.Count - 1
    Select Case i Mod 4
        Case 0
            player1Cards.Add(cards(i))
        Case 1
            player2Cards.Add(cards(i))
        Case 2
            player3Cards.Add(cards(i))
        Case 3
            player4Cards.Add(cards(i))
    End Select
Next


しかし、これでは問題があります。いつも同じプレイヤーに同じカードが配られるのです。
またプレイヤーの数が4人で固定という点も問題になるでしょう。

このような問題があるものの、ここまでの全体像は次のようになります。
Public Class Form1

    Dim cards As New List(Of Card)

    Dim player1Cards As New List(Of Card)
    Dim player2Cards As New List(Of Card)
    Dim player3Cards As New List(Of Card)
    Dim player4Cards As New List(Of Card)

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        For i As Integer = 1 To 13
            cards.Add(New Card With {.Mark = "スペード", .Number = i})
            cards.Add(New Card With {.Mark = "ダイヤ", .Number = i})
            cards.Add(New Card With {.Mark = "クラブ", .Number = i})
            cards.Add(New Card With {.Mark = "ハート", .Number = i})
        Next

        cards.Add(New Card With {.Mark = "ババ"})

        For i As Integer = 0 To cards.Count - 1
            Select Case i Mod 4
                Case 0
                    player1Cards.Add(cards(i))
                Case 1
                    player2Cards.Add(cards(i))
                Case 2
                    player3Cards.Add(cards(i))
                Case 3
                    player4Cards.Add(cards(i))
            End Select
        Next

    End Sub
End Class

Public Class Card
    Public Property Mark As String
    Public Property Number As Integer
End Class
投稿者 るきお  (社会人) 投稿日時 2013/10/29 15:23:28
コンピューターは「カード」を理解していません。ですから、「カードを捨てる」ということはできません。
計算やデータの読み書きならばコンピューターは得意です。

プログラマは表現しようとしていることを、コンピューターが得意な計算やデータの読み書きに置き換えて考える必要があります。

カードの扱いをどのようにして 計算やデータの読み書き に置き換えるかは実にさまざまな方法があって無数と言っていいほどです。

高橋だよさんの質問には 計算やデータの読み書き についてはまったく触れられていないので、回答する人がそのことを考える必要があります。
しかし、それには無数の方法があるので回答する人によって考えていることが違くなります。
回答する知識がある人は当然そのことに気が付いているので、回答しにくくなります。

また、「カードを捨てる」ことをなんとか計算やデータの読み書きに置き換えて回答したとしても、次に、では「カードを取る方法は?」となると、また計算やデータの読み書きを考える必要があり、最初の回答のときに考えていたこととは異なる発想になるかもしれません。

つまり、このような質問の仕方はプログラム上あまり意味がないと私は思います。

では、どうすればいいかというと、
まずは高橋さんはババ抜きをどのようにして計算やデータの読み書きで表現するかを考えるべきで、わからないところがあればそれを質問すべきです。

たとえば、トランプのカードはババも入れると53枚あります。
だからデータを保存するために53個のカード型の変数を作ることにしましょう。
しかし、53個も変数を宣言するのは大変なので、まずはコレクションにしてみましょう。
この段階でわからなければ「ババ抜きを前提に、VBのプログラムでカードを表現する最適な方法は何か?」というような質問になるわけです。

ひとまず、次のようにします。
Public Class Form1

    Dim cards As New List(Of Card)

End Class

Public Class Card

End Class


しかし、カードにはマークと数字の個性がありますから、このデータはプロパティで表現するようにしましょう。
(ババは特別なマークと考えることにします。)

次のようになります。
Public Class Form1

    Dim cards As New List(Of Card)

End Class

Public Class Card
    Public Property Mark As String
    Public Property Number As Integer
End Class


これでカード自体の管理方法は決まりましたが、まだカードの実体が1枚もありません。FormのLoad時にカードの実体を生成するようにしてみます。
Public Class Form1

    Dim cards As New List(Of Card)

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        For i As Integer = 1 To 13
            cards.Add(New Card With {.Mark = "スペード", .Number = i})
            cards.Add(New Card With {.Mark = "ダイヤ", .Number = i})
            cards.Add(New Card With {.Mark = "クラブ", .Number = i})
            cards.Add(New Card With {.Mark = "ハート", .Number = i})
        Next

        cards.Add(New Card With {.Mark = "ババ"})

    End Sub
End Class

Public Class Card
    Public Property Mark As String
    Public Property Number As Integer
End Class


これで53枚のカードは実体化されました。
投稿者 高橋だよ  (学生) 投稿日時 2013/10/29 14:46:49
VB2010でババ抜きゲームを作っていて、カードを配ることができたのですが、手札を選択し墓地に捨てるやり方がわかりません。そのやり方をぜひ教えてもらいたいです。

説明↓
手札のPictureBox1~13を2枚まで選択することができ、Bitton1を押すと墓地のPictureBox14に捨てることができる。しかし、選択したカードが同じ数字のカードじゃないといけないようにしたいです。