C# 在消除堆栈溢出异常的同时,维护功能的好方法是什么

C# 在消除堆栈溢出异常的同时,维护功能的好方法是什么,c#,C#,我这样做效率很低。我不是很有经验,只是尝试一些东西,希望它能起作用,我被堆栈溢出异常所困扰,这是可以理解的 因此,我的代码的第一部分非常明显,牌组中有33张牌,我随机渲染了3张,我尝试异常处理CheckForReDraw;防止重复的方法就是让事情变得。。。凌乱 public void DrawThreeUniqueGladiatorCards() { if (numberOfDiscards >= 30) { ShuffleGladCards();

我这样做效率很低。我不是很有经验,只是尝试一些东西,希望它能起作用,我被堆栈溢出异常所困扰,这是可以理解的

因此,我的代码的第一部分非常明显,牌组中有33张牌,我随机渲染了3张,我尝试异常处理CheckForReDraw;防止重复的方法就是让事情变得。。。凌乱

public void DrawThreeUniqueGladiatorCards()
{
    if (numberOfDiscards >= 30)
    {
        ShuffleGladCards();
    }

    Random gladCard = new Random();
    drawnGladCard1 = gladCard.Next(1, 34);

    Random gladCard2 = new Random();
    drawnGladCard2 = gladCard.Next(1, 34);

    Random questCard3 = new Random();
    drawnGladCard3 = gladCard.Next(1, 34);

    CheckForReDraw();
}

public void CheckForReDraw()
{

    if (drawnGladCard1 == drawnGladCard2 || drawnGladCard1 == drawnGladCard3 || drawnGladCard2 == drawnGladCard3)
    {
        DrawThreeUniqueGladiatorCards();
    }
    if (glad1Board == true || glad1Discard == true)
    {
        if (drawnGladCard1 == 1 || drawnGladCard2 == 1 || drawnGladCard3 == 1)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad2Board == true || glad2Discard == true)
    {
        if (drawnGladCard1 == 2 || drawnGladCard2 == 2 || drawnGladCard3 == 2)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad3Board == true || glad3Discard == true)
    {
        if (drawnGladCard1 == 3 || drawnGladCard2 == 3 || drawnGladCard3 == 3)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad4Board == true || glad4Discard == true)
    {
        if (drawnGladCard1 == 4 || drawnGladCard2 == 4 || drawnGladCard3 == 4)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad5Board == true || glad5Discard == true)
    {
        if (drawnGladCard1 == 5 || drawnGladCard2 == 5 || drawnGladCard3 == 5)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad6Board == true || glad6Discard == true)
    {
        if (drawnGladCard1 == 6 || drawnGladCard2 == 6 || drawnGladCard3 == 6)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad7Board == true || glad7Discard == true)
    {
        if (drawnGladCard1 == 7 || drawnGladCard2 == 7 || drawnGladCard3 == 7)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad8Board == true || glad8Discard == true)
    {
        if (drawnGladCard1 == 8 || drawnGladCard2 == 8 || drawnGladCard3 == 8)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad9Board == true || glad9Discard == true)
    {
        if (drawnGladCard1 == 9 || drawnGladCard2 == 9 || drawnGladCard3 == 9)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad10Board == true || glad10Discard == true)
    {
        if (drawnGladCard1 == 10 || drawnGladCard2 == 10 || drawnGladCard3 == 10)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad11Board == true || glad11Discard == true)
    {
        if (drawnGladCard1 == 11 || drawnGladCard2 == 11 || drawnGladCard3 == 11)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad12Board == true || glad12Discard == true)
    {
        if (drawnGladCard1 == 12 || drawnGladCard2 == 12 || drawnGladCard3 == 12)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad13Board == true || glad13Discard == true)
    {
        if (drawnGladCard1 == 13 || drawnGladCard2 == 13 || drawnGladCard3 == 13)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad14Board == true || glad14Discard == true)
    {
        if (drawnGladCard1 == 14 || drawnGladCard2 == 14 || drawnGladCard3 == 14)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad15Board == true || glad15Discard == true)
    {
        if (drawnGladCard1 == 15 || drawnGladCard2 == 15 || drawnGladCard3 == 15)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad16Board == true || glad16Discard == true)
    {
        if (drawnGladCard1 == 16 || drawnGladCard2 == 16 || drawnGladCard3 == 16)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad17Board == true || glad17Discard == true)
    {
        if (drawnGladCard1 == 17 || drawnGladCard2 == 17 || drawnGladCard3 == 17)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad18Board == true || glad18Discard == true)
    {
        if (drawnGladCard1 == 18 || drawnGladCard2 == 18 || drawnGladCard3 == 18)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad19Board == true || glad19Discard == true)
    {
        if (drawnGladCard1 == 19 || drawnGladCard2 == 19 || drawnGladCard3 == 19)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad20Board == true || glad20Discard == true)
    {
        if (drawnGladCard1 == 20 || drawnGladCard2 == 20 || drawnGladCard3 == 20)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad21Board == true || glad21Discard == true)
    {
        if (drawnGladCard1 == 21 || drawnGladCard2 == 21 || drawnGladCard3 == 21)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad22Board == true || glad22Discard == true)
    {
        if (drawnGladCard1 == 22 || drawnGladCard2 == 22 || drawnGladCard3 == 22)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad23Board == true || glad23Discard == true)
    {
        if (drawnGladCard1 == 23 || drawnGladCard2 == 23 || drawnGladCard3 == 23)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad24Board == true || glad24Discard == true)
    {
        if (drawnGladCard1 == 24 || drawnGladCard2 == 24 || drawnGladCard3 == 24)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad25Board == true || glad25Discard == true)
    {
        if (drawnGladCard1 == 25 || drawnGladCard2 == 25 || drawnGladCard3 == 25)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad26Board == true || glad26Discard == true)
    {
        if (drawnGladCard1 == 26 || drawnGladCard2 == 26 || drawnGladCard3 == 26)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad27Board == true || glad27Discard == true)
    {
        if (drawnGladCard1 == 27 || drawnGladCard2 == 27 || drawnGladCard3 == 27)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad28Board == true || glad28Discard == true)
    {
        if (drawnGladCard1 == 28 || drawnGladCard2 == 28 || drawnGladCard3 == 28)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad29Board == true || glad29Discard == true)
    {
        if (drawnGladCard1 == 29 || drawnGladCard2 == 29 || drawnGladCard3 == 29)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad30Board == true || glad30Discard == true)
    {
        if (drawnGladCard1 == 30 || drawnGladCard2 == 30 || drawnGladCard3 == 30)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad31Board == true || glad31Discard == true)
    {
        if (drawnGladCard1 == 31 || drawnGladCard2 == 31 || drawnGladCard3 == 31)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad32Board == true || glad32Discard == true)
    {
        if (drawnGladCard1 == 32 || drawnGladCard2 == 32 || drawnGladCard3 == 32)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
    if (glad33Board == true || glad33Discard == true)
    {
        if (drawnGladCard1 == 33 || drawnGladCard2 == 33 || drawnGladCard3 == 33)
        {
            DrawThreeUniqueGladiatorCards();
        }
    }
}
我一直在摆弄各种各样的东西,主要是想弄清楚当一张牌被选中时,如何通知随机函数,并且只从牌组中剩余的牌中选择,而不使用这种可笑的方法。非常感谢您提供任何指导或参考资料

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

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


我发现这篇文章在理论上很有用,但我自己似乎不知道如何实现它。

您的代码包含许多硬编码条件和冗余递归

考虑使用此构造:

bool error = false;
while(!error){
    error = someDrawFunction(args);
}
如果在本例中返回true,它将重复该函数,以保持递归堆叠调用


无论如何,我建议您使用一个存储卡。每次你抽一张牌,你就有N张可用的牌。从0到N-1绘制一个数字,并从列表中删除第N个索引元素。现在列表::大小减少了1,因为列表有N-1张卡。从较小的列表中抽取另一张卡。每次从0到size-1或从1到size进行随机转换时,等效地。不需要递归。

创建一个牌组类,用牌填充它,随机化顺序,而不是牌,然后从中抽取,就像你从一个真正的牌组中抽取一样

首先,创建一个表示卡的类:

class Card
{
    private readonly int suit;
    private readonly int rank;

    public Card(int suit, int rank)
    {
        this.suit = suit;
        this.rank = rank;
    }

    public int Suit { get { return suit; } }

    public int Rank{ get { return rank; } }
}
现在我们有了一个卡片类,我们需要一些东西来容纳它们。从牌组的顶部一次发一张牌,所以看起来a是合适的

我们将把这个队列包装在一个名为Deck的类中,并为它提供一些方法来填充它自己、随机化顺序和发牌

class Deck 
{
    private Queue<Card> cards = new Queue<Card>();  //Here's our queue
    private readonly Random random = new Random();

    //This is for a standard deck, but you could make it work it your special deck
    //We just loop and make sure there is one of each possible card
    private virtual IEnumerable<Card> CreateFreshDeck()
    {
        for (var suit = 1; suit<=4; suit++)
            for (var rank = 1; rank <=13; rank++)
                yield return new Card(suit,rank);
    }

    public void Shuffle()
    {
        this.cards = new Queue<Card>
        (
            CreateFreshDeck().OrderBy( a => random.Next() )  //This is where the shuffling happens
        );
    }

    public int CardsRemaining
    {
        get { return cards.Count; }  
    }

    public Card DealOne()
    {
        return this.cards.Dequeue();    
    }

    public IEnumerable<Card> DealMany(int count)
    {
        return this.cards.Take(count);
    }
}

这种新的随机性;x3是其中一个原因,可能是主要原因谢谢,我让他们在CheckForReDaw之前无问题运行;方法-当有多张角斗士牌在棋盘上或被丢弃时,堆栈溢出发生得更频繁,似乎是递归的本质触发了它。我想保留功能,但改为迭代lol我真是个笨蛋。再次感谢您的反馈,我将实例化随机类的不同版本哦,我甚至没有看到您在彼此之间调用两个函数,是的,应该这样做,您可能会把堆和所有这些随机对象弄乱,你只需要一个是全局的,然后从方法中调用下一个。只要你不使用递归调用,得到堆栈溢出的更改是非常模糊的。你区分了很多情况,但最后都是同样的画,三个独一无二的角斗士;。这难道不能简化吗?谢谢,听起来好多了,我会深入研究,看看如何实现一个列表。我的代码在一个有经验的程序员看来一定很糟糕,哈哈,我是自学成才的-希望做一个还不存在的棋盘游戏,我很乐意帮忙。您也可以使用已经完全实现的std::list啊,是的,当然这是C-u-,然后使用System.Collections.Generic list非常感谢您的反馈,这将需要我花一些时间来处理并理解。。我明白你说的是命令而不是命令cards@JaeBolton我不想低估你,但如果你觉得很难理解这个答案,那就读一读林奇的书,就像你的方法一样。认识到OP在编程方面是新的,如果您能更好地详细说明OrderBy的工作原理,并将重点放在比较器和谓词上,那就太好了。否则它将是100%模糊的…@John Wu这个例子是为名为Card的卡片假设一个类还是我离lol@John Wu很远
var d = new Deck();
d.Shuffle();
while (!gameOver)
{
    var card = d.DealOne();
    //etc.