如何防止我的纸牌游戏在一只手上随机抽取同一张牌两次

本文关键字:两次 一张 纸牌游戏 我的 何防止 一只 随机 | 更新日期: 2023-09-27 18:22:31

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

如何防止我的纸牌游戏在一只手上随机抽取同一张牌两次

在您的情况下,从可用卡集中随机抽取下一张卡。如果你抽到一张红心皇后牌,从可用的牌(牌组)中移除该牌,并从剩余的牌中随机选择一张牌。

这意味着你目前随意挑选价值和西装的方法是不合适的。相反,你可以在开始时洗牌一次,然后选择前5张牌(这里与真人打牌的方式相似)。阵列中的每个条目都必须唯一标识一张卡,这样它才是有效的{Value, Suit}组合。

  1. 不要像那样使用Random的两个实例。种子是在创建对象时确定的,因此当您像这样连续创建两个对象时,它们可能会为每次对Next()的调用返回相同的值
  2. 要回答您的问题,您只需保存您的结果。创建随机数时,将其保存在列表或其他类型的集合中,并检查是否存在。如果没有,则保存并使用它。如果有,则不要使用它并生成另一个随机数,直到myGeneratedNums.Contains(randomNum)返回false

有更复杂的方法来处理这个问题,但鉴于你是一个初学者,这应该做。如果你想研究替代方案,我建议在评论中遵循安东尼·佩格拉姆的建议。

根据以下行为您的卡创建一个结构:

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})
.....

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

我建议以下几点可以帮助您实现目标和良好的设计:

  1. 定义一个类(或者更好的是,不可变结构)来表示"Card"(这将具有suit和rank枚举)
  2. 定义一种唯一标识卡对象的方法
  3. 当你生成一张随机卡时,将其放入某种数据结构中,在向用户显示卡之前,请检查以确保它尚未显示(即通过查询你定义的唯一标识符)

无论如何,这应该会给你一个良好的开端。

使用1个容器而不是2个。用枚举的并集填充它(嵌套for循环就可以了),所以每个卡都有1个值(我会将其存储在Card结构/类中)。然后,从该列表中随机选择。一旦抽到一张牌(可能是添加到另一个容器中),就替换为null,如果你碰到null,就重新抽。

如果必须使用枚举,请这样做:

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]));
        }
    }
  }

}