我正在用二十一点游戏C#写一个纸牌游戏,用户按下一个按钮然后处理一张卡片,该卡片的价值会被添加到一个文本框中。如果文本框的值超过21,则用户丢失。
我在处理卡片时遇到问题,我生成一个随机的,比如5个生成显示5颗钻石,将5颗钻石的值加到分数文本框中并显示一个图片框( 5张钻石扑克牌)。然而,一旦生成了5,我就会遇到无法再次生成该卡的问题,我对需要发生的事情有所了解,我只是不确定实际的代码本身,因为我是初学者。
到目前为止,我尝试了两种不同的方式,一个List和一个布尔值数组,我仍在苦苦挣扎,任何人都可以指出我在代码方面的正确方向。
List<int> Diamonds = new List<int>();
Random random = new Random();
genRandom = random.Next(0, 5);
while (Diamonds.Contains(genRandom))
{
genRandom = random.Next(0, 5);
break;
}
while (!Diamonds.Contains(genRandom))
if (genRandom == 0)
{
Diamonds.add(0);
score = score += 2;
scoreTextBox.Text = score.ToString();
diamonds2.Show();
}
提前致谢,抱歉语法不好!
答案 0 :(得分:4)
我会采取相反的方法,通过创建一个包含所有可能卡片的集合,然后随机地从集合中绘制它们。
假设您有一个名为Deck
的班级,代表卡片组。填写Card
个类。现在,当您开始绘制卡片时,随机选择一个集合中的数字并从Deck
中删除该卡片。下次绘制相同的随机数时,它将从卡组中抽取不同的卡,因为您删除了用过的卡。
请记住生成一个在牌组大小范围内的随机数,每次抽牌后都会减少。
答案 1 :(得分:4)
您现在遇到的问题是您没有卡池。您应该有一张可以从中抽取的卡片列表,一旦选择了一张卡片,它就会从可用的选项中删除,并且无法再次绘制。
List<Card> deck = new List<Card>();
deck.Add(new Card(1, CardType.Diamonds));
deck.Add(new Card(2, CardType.Diamonds));
...
Card nextCard = deck[Random.Next(0, deck.Count - 1)];
deck.Remove(nextCard);
其中:
struct Card
{
public int number;
public CardType type;
public Card(int number, CardType type)
{
this.number = number;
this.type = type;
}
}
enum CardType
{
Diamonds,
Spades,
Hearts,
Clubs
}
这是一种非常简单的,面向对象的方法,每张卡都被明确定义为一个独特的容器。它可能不是最佳方式,但可能更容易理解。
答案 2 :(得分:1)
有许多方法可以做到这一点,我使用它的最多如下:
List<int> available = new List<int>(5000);
for(int i=1; i<=5; i++)
available.Add(i);
以上代码将生成所有随机数。
现在您可以按如下方式选择:
List<int> result = new List<int>(5000);
while(available.Count > 0)
{
int index = random.Next(availableCount);
result.Add(available[index]);
available.RemoveAt(index);
}
return result;
因为你在获取后正在移除它们永远不会重复。
答案 3 :(得分:1)
你可以这样做:
List<int> Diamonds = new List<int>();
for(int i = 1; i <= 10; i++) //10 is just an example..dk how many cards :P
{
Diamonds.Add(i);
}
Random random = new Random();
int index = random.Next(0, Diamonds.Count - 1);
int nr = Diamonds[index];
Diamonds.Remove(index);
答案 4 :(得分:0)
最简单的方法是随机排序整个列表(按Rand() - 0.5
排序),然后每次需要“随机”卡时,取出第一张卡并将其从列表中删除。这些牌是随机顺序的,所以它在统计上与每次选择一张随机牌相同,并且在给定的游戏中你不会选择相同的牌两次。
答案 5 :(得分:0)
概念上最简单的方法是使用一个代表一副牌的阵列,然后从中处理卡片。
理想情况下,你会使用一个堆栈,但不幸的是你无法改变堆栈!
因此,您最好的选择是使用List<Card>
,其中'卡'是代表卡的类。 Card
类有两个属性:一个Suite
和一个从1(Ace)到13的等级,其中11是杰克,12是女王,13是国王。
您可以使用所有52张可能的卡填充List<Card>
牌组,然后您可以使用Fisher-Yates shuffle的实施方式对其进行随机播放。
这是一个完整的样本:
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var deck = new List<Card>();
for (int rank = 1; rank <= 13; ++rank)
foreach (Suite suite in Enum.GetValues(typeof(Suite)))
deck.Add(new Card {Rank = rank, Suite = suite});
var shuffler = new Shuffler();
shuffler.Shuffle(deck);
// Deal the top 10 cards.
for (int i = 0; i < 10; ++i)
Console.WriteLine(deck[i]);
}
}
public enum Suite
{
Clubs,
Diamonds,
Hearts,
Spades
}
public sealed class Card
{
public Suite Suite;
public int Rank;
public override string ToString()
{
string rank;
switch (Rank)
{
case 1: rank = "Ace"; break;
case 11: rank = "Jack"; break;
case 12: rank = "Queen"; break;
case 13: rank = "King"; break;
default: rank = Rank.ToString(); break;
}
return string.Format("{0} of {1}", rank, Suite);
}
}
public sealed class Shuffler
{
public Shuffler()
{
_rng = new Random();
}
public void Shuffle<T>(IList<T> array)
{
for (int n = array.Count; n > 1; )
{
int k = _rng.Next(n);
--n;
T temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
private readonly Random _rng;
}
}
当然,真正的代码应该验证Rank和Suite。另外,你最好写一个Deck类,它封装了shuffling和处理(它可以在处理时从List<Card>
的末尾删除卡片。)