如何让我的纸牌游戏不会在一只手中随机抽取同一张卡两次?

时间:2012-02-02 21:14:09

标签: c#

我正在尝试开发纸牌游戏,用户点击按钮并自动显示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);

    }

  }
}

6 个答案:

答案 0 :(得分:4)

在你的情况下,从可用的卡中抽取下一张随机卡。如果你画了一张Queen of Hearts,请从可用卡(卡座)中取出该卡,然后从剩余的卡中挑选一张随机卡。

这意味着您当前随机挑选价值和套装的方法并不合适。相反,你可以例如shuffle数组一旦开始并挑选前5张牌(类似于真实的人打牌如何引人注目)。数组中的每个条目都必须唯一地标识一张卡,因此它将是一个有效的{Value, Suit}组合。

答案 1 :(得分:3)

  1. 请勿使用Random这样的两个实例。种子是在创建对象时确定的,因此当您连续创建两个时,它们可能会为每次调用Next()返回相同的值。
  2. 要回答您的问题,您只需保存结果即可。创建随机数时,将其保存在List或其他类型的集合中,并检查它是否存在。如果没有,则保存并使用它。如果是,请不要使用它并生成另一个随机数,直到myGeneratedNums.Contains(randomNum)返回false
  3. 有更复杂的方法可以解决这个问题,但看到你是初学者应该这样做。如果您想研究替代方案,那么我建议在评论中跟进Anthony Pegram的建议。

答案 2 :(得分:3)

Spontaneously Id按以下方式为您的卡片创建一个结构:

struct Card
{
    CardValue value;
    CardSuit suit;
}
然后,我会创建一个代表你的套牌的清单,并用你通常在牌组中看到的牌填充这个清单。即。

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

然后将结果随机化,确保在挑选时从列表中删除这些卡片。通过引入一些循环可以使填充甲板变得更平滑,但这应该表明这个想法。

答案 3 :(得分:1)

我建议以下内容可以帮助您实现目标和一般的优秀设计:

  1. 定义一个类(或更好的,不可变的结构)来表示“卡片”(这将具有套装和等级枚举)
  2. 定义一种唯一识别卡片对象的方法。
  3. 当您生成随机卡时,将其放入某种数据结构中,然后在向用户显示卡之前,检查以确保它尚未显示(即通过查询您已使用的唯一标识符定义)
  4. 无论如何,这应该让你有一个好的开始。

答案 4 :(得分:1)

使用1个容器代替2.使用枚举的并集填充它(嵌套for循环会这样做),因此每个卡都有1个值(我将它存储在Card结构中/类)。然后,从该列表中随机选择。一旦绘制了一张卡(可能被添加到另一个容器中),则替换为null,如果您点击一个空值,则重新绘制。

答案 5 :(得分: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]));
        }
    }
  }

}