2012-02-02 61 views
0

我想開發一款紙牌遊戲,用戶點擊一個按鈕並自動顯示5張牌。無論如何,現在我正在做一個控制檯應用程序,其中顯示來自兩個Ace的5個字符並顯示5個隨機卡片套裝。但我無法弄清楚如何防止重複一個具有相同值+花色的卡片。誰能幫幫我嗎。這裏是我的代碼如何讓我的紙牌遊戲不會隨機抽取同一張牌兩次?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Collections; 

namespace ConsoleApplication1 
{ 
class Program 
{ 
    static void Main(string[] args) 
    { 

     Array values = Enum.GetValues(typeof(CardValue)); 
     Array symbols = Enum.GetValues(typeof(CardSuit)); 
     Random random = new Random(); 
     Random randomsymbol = new Random(); 
     ArrayList mySymbols = new ArrayList(); 
     ArrayList myAl = new ArrayList(); 

     for (int i = 0; i < 5; i++) 
     { 
      CardValue randomBar = (CardValue)values.GetValue(random.Next(values.Length)); 
      myAl.Add(randomBar);} 
      for (int j = 0; j < 5; j++) 
      { 
       CardSuit randomsign = (CardSuit)symbols.GetValue(randomsymbol.Next(symbols.Length)); 
       mySymbols.Add(randomsign); 
      } 
      Console.WriteLine("Values:"); 
      PrintValues(myAl); 
      Console.WriteLine(); 
      PrintSigns(mySymbols); 


      Console.In.ReadLine(); 


    } 
    enum CardValue { Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace }; 
    enum CardSuit { Hearts, Clubs, Diamonds, Spades }; 


    public static void PrintValues(IEnumerable mylist) 
    { 
     foreach (Object obj in mylist) 
      Console.Write("  {0}", obj); 

    } 

    public static void PrintSigns(IEnumerable mySigns) 
    { 
     foreach (Object obj1 in mySigns) 
      Console.Write(" {0}", obj1); 

    } 

    } 
} 
+0

是否值必須是在一個單獨的枚舉的西裝? – MyKuLLSKI 2012-02-02 21:19:00

+0

你到目前爲止嘗試過什麼?顯然你必須跟蹤你以某種方式生成了哪張牌;上面的代碼顯示沒有嘗試這樣做。 – 2012-02-02 21:19:36

+1

此外,關於Random的一個觀察:當它被實例化時(我相信),由該類的一個實例產生的僞隨機數的模式被確定。快速連續創建兩個實例意味着連續調用random.Next()和randomSymbol.Next()會產生非常相似的值;如果選擇的價值和訴訟應該是無關聯的,只需聲明一個「Random」實例並在整個程序中使用它。 – 2012-02-02 21:20:44

回答

1

我建議以下的東西,這將幫助你追求目標和良好的設計一般:

  1. 定義一個類(或更好,但不變的結構)來代表「卡」(這將有套裝和排名枚舉)
  2. 定義一種唯一標識卡對象的方法。
  3. 當您生成一張隨機卡時,將其放入某種數據結構中,並在將卡片顯示給用戶之前,檢查以確保它尚未顯示(即通過查詢您擁有的唯一標識符定義)

無論如何,這應該給你一個運行的開始。

2
  1. 不要使用這樣的兩個實例Random。種子是在創建對象時確定的,因此當您連續創建兩個對象時,它們可能會爲每次調用Next()返回相同的值。
  2. 要回答你的問題,你只需要保存你的結果。當創建一個隨機數字時,將它保存在List或其他類型的集合中,並檢查它是否存在。如果沒有,則保存並使用它。如果是,請不要使用它並生成另一個隨機數,直到myGeneratedNums.Contains(randomNum)返回false

有更復雜的方法來處理這個問題,但看到你應該這樣做的初學者。如果您想調查替代方案,那麼我建議您在評論中跟隨Anthony Pegram的建議。

+0

我一直在努力保存這個結果,但我不能拿出一個答案,你可以給我一個開始。是的,我是一個初學者,所以一旦我得到這個項目的工作,我實際上可以實施安東尼的建議。 – Edward 2012-02-04 00:29:08

4

在你的情況下,從可用的卡組中抽取下一張隨機卡。如果您畫出一張紅心皇后,從可用卡片(卡組)中取出該卡牌並從剩餘的卡片中隨機選擇一張卡片。

這意味着你目前的隨機挑選價值和套裝的方法並不合適。相反,你可以例如shuffle該陣列一開始就選擇了前5張牌(類似於真人玩牌的方式在這裏引人注目)。數組中的每個條目都必須唯一標識一張卡片,以便它將成爲有效的{Value, Suit}組合。

+1

+1爲洗牌的概念。這是比我檢查空衝突的建議更好的選擇。 – Kendrick 2012-02-02 21:29:55

+0

確實+1用於模擬洗牌和交易的實際行爲。 – 2012-02-02 21:57:10

1

使用1個容器而不是2個。使用枚舉的聯合(嵌套for循環會這樣做)來填充它,所以每個卡片有1個值(我將它存儲在一個Card結構/類中)。然後,從這個列表中隨機選擇。一旦卡被繪製(可能被添加到另一個容器),並且如果你點擊一個空值,則重新繪製替換爲null。

3

自發ID一起的線爲您的卡結構:

struct Card 
{ 
    CardValue value; 
    CardSuit suit; 
} 

ID,然後在創建一個能夠代表你的甲板上,並填寫此表與你幾乎在甲板上通常看到的卡的列表。即

List<Card> deck = new List<Card>(); 
deck.Add(new Card(){value = One, suit = Hearts}) 
deck.Add(new Card(){value = Two, suit = Hearts}) 
..... 

然後隨機化你的結果,確保從列表中取出卡片。通過引入一些循環來填充甲板可以變得更平滑,但是這應該顯示出這個想法。

0

如果你必須使用一個枚舉這樣來做:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Collections; 
using System.Text.RegularExpressions; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     enum Cards 
     { 
      TwoOFHearts, 
      TwoOFClubs, 
      TwoOFDiamonds, 
      TwoOFSpades, 

      ThreeOFHearts, 
      ThreeOFClubs, 
      ThreeOFDiamonds, 
      ThreeOFSpades, 

      FourOFHearts, 
      FourOFClubs, 
      FourFDiamonds, 
      FourOFSpades, 

      FiveOFHearts, 
      FiveOFClubs, 
      FiveOFDiamonds, 
      FiveOFSpades, 

      SixOFHearts, 
      SixOFClubs, 
      SixOFDiamonds, 
      SixOFSpades, 

      SevenOFHearts, 
      SevenOFClubs, 
      SevenOFDiamonds, 
      SevenOFSpades, 

      EightOFHearts, 
      EightOFClubs, 
      EightOFDiamonds, 
      EightOFSpades, 

      NineOFHearts, 
      NineOFClubs, 
      NineOFDiamonds, 
      NineOFSpades, 

      TenOFHearts, 
      TenOFClubs, 
      TenOFDiamonds, 
      TenOFSpades, 

      JackOFHearts, 
      JackOFClubs, 
      JackOFDiamonds, 
      JackOFSpades, 

      QueenOFHearts, 
      QueenOFClubs, 
      QueenOFDiamonds, 
      QueenOFSpades, 

      KingOFHearts, 
      KingOFClubs, 
      KingOFDiamonds, 
      KingOFSpades, 

      AceOFHearts, 
      AceOFClubs, 
      AceOFDiamonds, 
      AceOFSpades, 
    } 

    Random Random = new Random(); 
    Cards[] CardList; 
    Regex Rexex = new Regex("OF"); 

    static void Main(string[] args) 
    { 
     CardList = (Cards[])Enum.GetValues(typeof(Cards)); 
     ShuffleCards(); 
     PrintCards(5); 
    } 

    private static void ShuffleCards() 
    { 
     for (int i = CardList.Length - 1; i > 0; i--) 
     { 
      int n = Random.Next(i + 1); 
      Cards card = CardList[i]; 
      CardList[i] = CardList[n]; 
      CardList[n] = card; 
     } 
    } 

    private static void PrintCards(int count) 
    { 
     for (int i = 0; i < count; i++) 
     { 
      string[] card = Rexex.Split(CardList[i].ToString()); 
      Console.WriteLine(string.Concat("Card ", i.ToString(), " - Value:", card[0], " Suit: ", card[1])); 
     } 
    } 
    } 

}