如何防止我的纸牌游戏在一只手上随机抽取同一张牌两次
本文关键字:两次 一张 纸牌游戏 我的 何防止 一只 随机 | 更新日期: 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}
组合。
- 不要像那样使用
Random
的两个实例。种子是在创建对象时确定的,因此当您像这样连续创建两个对象时,它们可能会为每次对Next()
的调用返回相同的值 - 要回答您的问题,您只需保存您的结果。创建随机数时,将其保存在列表或其他类型的集合中,并检查是否存在。如果没有,则保存并使用它。如果有,则不要使用它并生成另一个随机数,直到
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更平滑,但这应该表明了这个想法。
我建议以下几点可以帮助您实现目标和良好的设计:
- 定义一个类(或者更好的是,不可变结构)来表示"Card"(这将具有suit和rank枚举)
- 定义一种唯一标识卡对象的方法
- 当你生成一张随机卡时,将其放入某种数据结构中,在向用户显示卡之前,请检查以确保它尚未显示(即通过查询你定义的唯一标识符)
无论如何,这应该会给你一个良好的开端。
使用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]));
}
}
}
}