Visual Basic 简单纸牌游戏。在编写评分过程时遇到问题 - 初学者
Visual Basic Simple Card Game. Having problems with coding the scoring process - Beginner
- 向下滚动到问题部分查看我的问题 *
我的目标是什么?
我正在尝试编写一个程序来记录一个简单的两人游戏的分数(52 张牌,13 个可能的名字各有 4 个,所以没有王牌)。 Jack, Queen, King 和 Ace 是我的大牌,有了它们,两个玩家中的一个可以得分。牌组必须洗牌(从牌列表中随机 select)。玩家 1 先转动一张牌,然后是玩家 B,依此类推。一张牌一旦使用,就不能重复使用,所以一旦拉出 52 张牌,游戏就结束了。本场比赛计分如下:
- 如果玩家翻开一张 A,至少还有 4 张牌要翻开,并且接下来的 4 张牌中 none 是大牌,则该玩家得 4 分。
- 如果玩家翻开 K,至少还有 3 张牌要翻开,并且接下来的 3 张牌中 none 是大牌,则该玩家获得 3 分。
- 如果玩家翻开 Q,至少还有 2 张牌未翻开,并且接下来的 2 张牌中 none 是大牌,则该玩家将获得 2 分
- 如果玩家翻开 J 点,至少还有 1 张牌要翻开,并且下一张牌不是大牌,则该玩家得 1 分
- **注:玩家自己的牌也可以推翻自己放下的前一张大牌。假设玩家 1 拉出 Q,当再次轮到他时,他拉出 A。然后,他不能得到 2 分,而是必须遵守开 A 时的规则。
游戏玩法示例:
- 玩家 1 拉三
- 玩家 2 拉出 7
- Player 1 pulls a Queen--------High Card Queen (需要2张非高牌才能得2分)
- 玩家 2 拉了一张八
- Player 1 pulls a 5------------Player 1 刚刚得了2分!
我现在有什么代码?
Public Class Form1
'Variable (make a list)
Dim cards As New List(Of String) From {"two", "two", "two", "two", "three", "three", "three", "three", "four", "four", "four", "four", "five", _
"five", "five", "five", "six", "six", "six", "six", "seven", "seven", "seven", "seven", "eight", "eight", _
"eight", "eight", "nine", "nine", "nine", "nine", "ten", "ten", "ten", "ten", "jack", "jack", "jack", _
"jack", "queen", "queen", "queen", "queen", "king", "king", "king", "king", "ace", "ace", "ace", "ace"}
'What Happens when button 1 is clicked
Private Sub btnPlayer1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPlayer1.Click
Dim rnd = New Random() 'Set rnd as random generator
If cards.Count > 0 Then 'If all cards have been drawn then no more cards can be drawn
Dim randomcards = cards(rnd.Next(0, cards.Count)) 'Set randomcards as one randomly chosen (using rnd) card from cards list
lstbox1.Items.Add(randomcards) 'Add 1 randomly chosen card from cards list into lstbox1 each time btnPlayer1 is clicked
cards.Remove(randomcards) 'Remove the randomly generated card from cards list to reduce deck size. No card will be picked more than 4 times
End If
lstbox1.TopIndex = lstbox1.Items.Count - 1 'Automatically scroll down lstbox1 each time new item is added so players only see last played card (can still scroll up to see previous cards)
End Sub
'What happens when button 2 is clicked
Private Sub btnPlayer2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPlayer2.Click
Dim rnd = New Random() 'Set rnd as random generator
If cards.Count > 0 Then 'If all cards have been drawn then no more cards can be drawn
Dim randomcards = cards(rnd.Next(0, cards.Count)) 'Set randomcards as one randomly chosen (using rnd) card from cards list
lstbox2.Items.Add(randomcards) 'Add 1 randomly chosen card from cards list into lstbox2 each time btnPlayer2 is clicked
cards.Remove(randomcards) 'Remove the randomly generated card from cards list to reduce deck size. No card will be picked more than 4 times
End If
lstbox2.TopIndex = lstbox2.Items.Count - 1 'Automatically scroll down lstbox2 each time new item is added so players only see last played card (can still scroll up to see previous cards)
End Sub
'Button to restart program
Private Sub btnRestart_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnRestart.Click
Application.Restart()
End Sub
'Button to close program
Private Sub btnClose_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnClose.Click
End
End Sub
End Class
我遇到了什么问题? (删除了之前我能够解决的问题)
- 剩下的问题是评分过程。因为我有两个列表框,左边的是玩家 A 的牌所在的位置,右边的是玩家 B 的牌所在的位置。所以我的问题是:
我如何检索 data/order 从两个列表框中抽取的卡片(如果抽取顺序为 A B A B 等...),然后将我的评分规则应用于该列表框
卡顺序? (除非它不是来自列表框,否则我应该获取我的数据...?)
刚开始
供您参考,我三周前才开始编程。我从 VB 开始,一旦我变得更好,我将继续 Python。我真的很想在未来成为一名游戏创作者,所以我制作的所有程序都是这样的小游戏(目前超级简单)。现在我从一个游戏创意开始,画出外观,设置我希望游戏遵循的规则,然后根据我设置的规则编写代码。这是我迄今为止最具挑战性的游戏,我碰壁了。非常感谢您的帮助:) 谢谢!
我会用评论更新这个答案,以便稍后解释所有内容。现在,这就是我开始编写您的游戏的方式。我使用控制台应用程序只是因为它是最快的。答案的核心是 Deck
class 加上使用 Queue(Of T)
确保每张卡片只分发一次的事实。
Public Module Module1
Public Sub Main()
Dim PlayDeck As New Queue(Of Deck.Card)
Dim Deck As New Deck(True)
Deck.CardList.ForEach(Sub(x) PlayDeck.Enqueue(x))
Dim player1card As Deck.Card = PlayDeck.Dequeue()
Dim player2card As Deck.Card = PlayDeck.Dequeue()
Console.WriteLine(player1card.ToString())
Console.WriteLine(player2card.ToString())
Console.ReadLine()
End Sub
Public Class Deck
Public Structure Card
Public Property Suit As Suits
Public Property Value As CardValue
Public Enum Suits
Hearts = 0
Spades = 1
Clubs = 2
Diamonds = 3
End Enum
Public Enum CardValue
Two = 2
Three = 3
Four = 4
Five = 5
Six = 6
Seven = 7
Eight = 8
Nine = 9
Ten = 10
Jack = 11
Queen = 12
King = 13
Ace = 14
End Enum
Public Overrides Function ToString() As String
Return [Enum].GetName(GetType(CardValue), Me.Value) & " of " & [Enum].GetName(GetType(Suits), Me.Suit)
End Function
End Structure
Public CardList As List(Of Card)
Public Sub New()
CardList = New List(Of Card)
For Each suit As Card.Suits In [Enum].GetValues(GetType(Card.Suits))
For Each val As Card.CardValue In [Enum].GetValues(GetType(Card.CardValue))
CardList.Add(New Card With {.Suit = suit, .Value = val})
Next
Next
End Sub
Public Sub New(Shuffle As Boolean)
Me.New()
If Shuffle Then ShuffleCards()
End Sub
Public Sub ShuffleCards()
Dim csprng As New System.Security.Cryptography.RNGCryptoServiceProvider
Dim c As Integer = Me.CardList.Count
While c > 1
Dim b As Byte() = New Byte(0) {}
Do
csprng.GetBytes(b)
Loop While Not b(0) < c * (Byte.MaxValue / c)
Dim k As Integer = (b(0) Mod c)
c -= 1
Dim v As Card = Me.CardList(k)
Me.CardList(k) = Me.CardList(c)
Me.CardList(c) = v
End While
End Sub
End Class
End Module
- 向下滚动到问题部分查看我的问题 *
我的目标是什么?
我正在尝试编写一个程序来记录一个简单的两人游戏的分数(52 张牌,13 个可能的名字各有 4 个,所以没有王牌)。 Jack, Queen, King 和 Ace 是我的大牌,有了它们,两个玩家中的一个可以得分。牌组必须洗牌(从牌列表中随机 select)。玩家 1 先转动一张牌,然后是玩家 B,依此类推。一张牌一旦使用,就不能重复使用,所以一旦拉出 52 张牌,游戏就结束了。本场比赛计分如下:
- 如果玩家翻开一张 A,至少还有 4 张牌要翻开,并且接下来的 4 张牌中 none 是大牌,则该玩家得 4 分。
- 如果玩家翻开 K,至少还有 3 张牌要翻开,并且接下来的 3 张牌中 none 是大牌,则该玩家获得 3 分。
- 如果玩家翻开 Q,至少还有 2 张牌未翻开,并且接下来的 2 张牌中 none 是大牌,则该玩家将获得 2 分
- 如果玩家翻开 J 点,至少还有 1 张牌要翻开,并且下一张牌不是大牌,则该玩家得 1 分
- **注:玩家自己的牌也可以推翻自己放下的前一张大牌。假设玩家 1 拉出 Q,当再次轮到他时,他拉出 A。然后,他不能得到 2 分,而是必须遵守开 A 时的规则。
游戏玩法示例:
- 玩家 1 拉三
- 玩家 2 拉出 7
- Player 1 pulls a Queen--------High Card Queen (需要2张非高牌才能得2分)
- 玩家 2 拉了一张八
- Player 1 pulls a 5------------Player 1 刚刚得了2分!
我现在有什么代码?
Public Class Form1
'Variable (make a list)
Dim cards As New List(Of String) From {"two", "two", "two", "two", "three", "three", "three", "three", "four", "four", "four", "four", "five", _
"five", "five", "five", "six", "six", "six", "six", "seven", "seven", "seven", "seven", "eight", "eight", _
"eight", "eight", "nine", "nine", "nine", "nine", "ten", "ten", "ten", "ten", "jack", "jack", "jack", _
"jack", "queen", "queen", "queen", "queen", "king", "king", "king", "king", "ace", "ace", "ace", "ace"}
'What Happens when button 1 is clicked
Private Sub btnPlayer1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPlayer1.Click
Dim rnd = New Random() 'Set rnd as random generator
If cards.Count > 0 Then 'If all cards have been drawn then no more cards can be drawn
Dim randomcards = cards(rnd.Next(0, cards.Count)) 'Set randomcards as one randomly chosen (using rnd) card from cards list
lstbox1.Items.Add(randomcards) 'Add 1 randomly chosen card from cards list into lstbox1 each time btnPlayer1 is clicked
cards.Remove(randomcards) 'Remove the randomly generated card from cards list to reduce deck size. No card will be picked more than 4 times
End If
lstbox1.TopIndex = lstbox1.Items.Count - 1 'Automatically scroll down lstbox1 each time new item is added so players only see last played card (can still scroll up to see previous cards)
End Sub
'What happens when button 2 is clicked
Private Sub btnPlayer2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPlayer2.Click
Dim rnd = New Random() 'Set rnd as random generator
If cards.Count > 0 Then 'If all cards have been drawn then no more cards can be drawn
Dim randomcards = cards(rnd.Next(0, cards.Count)) 'Set randomcards as one randomly chosen (using rnd) card from cards list
lstbox2.Items.Add(randomcards) 'Add 1 randomly chosen card from cards list into lstbox2 each time btnPlayer2 is clicked
cards.Remove(randomcards) 'Remove the randomly generated card from cards list to reduce deck size. No card will be picked more than 4 times
End If
lstbox2.TopIndex = lstbox2.Items.Count - 1 'Automatically scroll down lstbox2 each time new item is added so players only see last played card (can still scroll up to see previous cards)
End Sub
'Button to restart program
Private Sub btnRestart_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnRestart.Click
Application.Restart()
End Sub
'Button to close program
Private Sub btnClose_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnClose.Click
End
End Sub
End Class
我遇到了什么问题? (删除了之前我能够解决的问题)
- 剩下的问题是评分过程。因为我有两个列表框,左边的是玩家 A 的牌所在的位置,右边的是玩家 B 的牌所在的位置。所以我的问题是:
我如何检索 data/order 从两个列表框中抽取的卡片(如果抽取顺序为 A B A B 等...),然后将我的评分规则应用于该列表框 卡顺序? (除非它不是来自列表框,否则我应该获取我的数据...?)
刚开始 供您参考,我三周前才开始编程。我从 VB 开始,一旦我变得更好,我将继续 Python。我真的很想在未来成为一名游戏创作者,所以我制作的所有程序都是这样的小游戏(目前超级简单)。现在我从一个游戏创意开始,画出外观,设置我希望游戏遵循的规则,然后根据我设置的规则编写代码。这是我迄今为止最具挑战性的游戏,我碰壁了。非常感谢您的帮助:) 谢谢!
我会用评论更新这个答案,以便稍后解释所有内容。现在,这就是我开始编写您的游戏的方式。我使用控制台应用程序只是因为它是最快的。答案的核心是 Deck
class 加上使用 Queue(Of T)
确保每张卡片只分发一次的事实。
Public Module Module1
Public Sub Main()
Dim PlayDeck As New Queue(Of Deck.Card)
Dim Deck As New Deck(True)
Deck.CardList.ForEach(Sub(x) PlayDeck.Enqueue(x))
Dim player1card As Deck.Card = PlayDeck.Dequeue()
Dim player2card As Deck.Card = PlayDeck.Dequeue()
Console.WriteLine(player1card.ToString())
Console.WriteLine(player2card.ToString())
Console.ReadLine()
End Sub
Public Class Deck
Public Structure Card
Public Property Suit As Suits
Public Property Value As CardValue
Public Enum Suits
Hearts = 0
Spades = 1
Clubs = 2
Diamonds = 3
End Enum
Public Enum CardValue
Two = 2
Three = 3
Four = 4
Five = 5
Six = 6
Seven = 7
Eight = 8
Nine = 9
Ten = 10
Jack = 11
Queen = 12
King = 13
Ace = 14
End Enum
Public Overrides Function ToString() As String
Return [Enum].GetName(GetType(CardValue), Me.Value) & " of " & [Enum].GetName(GetType(Suits), Me.Suit)
End Function
End Structure
Public CardList As List(Of Card)
Public Sub New()
CardList = New List(Of Card)
For Each suit As Card.Suits In [Enum].GetValues(GetType(Card.Suits))
For Each val As Card.CardValue In [Enum].GetValues(GetType(Card.CardValue))
CardList.Add(New Card With {.Suit = suit, .Value = val})
Next
Next
End Sub
Public Sub New(Shuffle As Boolean)
Me.New()
If Shuffle Then ShuffleCards()
End Sub
Public Sub ShuffleCards()
Dim csprng As New System.Security.Cryptography.RNGCryptoServiceProvider
Dim c As Integer = Me.CardList.Count
While c > 1
Dim b As Byte() = New Byte(0) {}
Do
csprng.GetBytes(b)
Loop While Not b(0) < c * (Byte.MaxValue / c)
Dim k As Integer = (b(0) Mod c)
c -= 1
Dim v As Card = Me.CardList(k)
Me.CardList(k) = Me.CardList(c)
Me.CardList(c) = v
End While
End Sub
End Class
End Module