2013-04-16 29 views
3

我正在C#,一个二十一点游戏,用户按下一个按钮,它处理一张卡片,卡片的价值被添加到C#一个文本框。如果文本框的值超过21,则用户丢失。如何生成一个随机,然后不再显示该随机

我遇到了卡片的处理问题,我生成一个随机的,比如说5个生成的显示5个钻石,将5个钻石的值添加到得分文本框并显示一个图片框(钻石牌5)。然而,一旦产生了5个问题,我就不能再生成那张卡片了,我有需要发生什么的逻辑,我只是​​不确定实际的代码本身,因为我是初学者。

到目前为止,iv尝试了两种不同的方式,一个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(); 

     } 

在此先感谢,对于错误的语法感到抱歉!

+1

而不是一次生成1个随机数这里是另一种解决方案。将所有可能的牌放入列表中,然后将该列表洗牌。然后你可以选择开始和列表的开始。就像你玩真实卡片一样。 –

+0

为什么你在那段时间会有这样的突破?这将立即停止循环。删除它,它应该工作。 –

回答

0

最简单的事情就是随机对整个列表进行排序(按Rand() - 0.5排序),然后每次你想要一张“随机”卡片时,拿第一张卡片从列表中移除。这些牌是随机排列的,因此它在统计上与每次随机选择一样效果相同,并且在给定游戏中不会选择同一张牌。

4

我会采取相反的方法,通过创建一个集合来保存所有可能的卡片,然后随机从集合中绘制它们。

假设您有一个名为Deck的课程,该课程代表卡片组。填写Card课程。现在,当您开始绘制卡片时,随机挑选集合中的一个数字,并从Deck中移除该卡片。下一次绘制相同的随机数字时,它会从卡组中抽出一张不同的卡片,因为您移除了使用过的卡片。

只要记住生成一个随机数字,这个数字在牌组大小的范围内,在每次抽签后会减少。

+0

基本上,LightStriker与一些应该正常工作的示例代码有相同的答案。 –

+0

谢谢,我现在要去看看:) – mikeathers

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; 

既然你得到他们永远不会重复后去除。

+0

我在算法类中看到了这种方法,效果很好,没有性能开销。 –

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 
} 

这是每个卡被明确定义为一个独特的容器一个非常简单的,面向对象的方法。这可能不是最理想的方式,但可能更容易理解。

+0

谢谢你,我要试一试,虽然这一切都不复杂,说我没有打牌,但我仍然在生成52个数字,其中每个数字在一个if语句中做了不同的动作不是一种从生成的随机数范围中移除该数字的方法,或者如果该随机数再次生成,不做任何事情只是生成一个新的数字?再次感谢 – mikeathers

+0

无论是卡,整数,双打或其他,如果你可以将它们添加到集合中,你可以再次删除它们。 –

+0

@ Angelo109:你只需要替换'List '为'List ',你最终得到一个可以添加或删除的52个数字的列表。列表允许您通过索引或他们的身份添加或删除项目。 – LightStriker

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); 
0

从概念上做到这一点,最简单的方法是有代表的一副扑克牌的排列,然后从它处理卡。

理想情况下,你会为​​此使用堆栈,但不幸的是你不能洗牌堆栈!

因此,您最好的选择是使用List<Card>,其中'卡'是代表卡的类。 Card课程有两个属性:Suite和从1(王牌)到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; 
    } 
} 

真正的代码应该验证过程的等级和套房。另外,你最好写一个封装洗牌和交易的Deck类(它可以在交易时从List<Card>的末尾删除卡)。