使用Linq查找列表是否包含至少5个值的增量序列

时间:2017-03-01 14:24:38

标签: c# linq

我正在开发一款扑克游戏,根据你所发出的牌,找出你所做的牌。我目前坚持直线的逻辑(增量序列中的5张卡,例如3,4,5,6,7)。我使用的Card对象有一个int属性,表示它的值(默认为ace为14)。

这是我到目前为止所拥有的:

private static bool CheckForStraight()
{
        List<Card> tmpCards = new List<Card>(_cards); //local copy of the cards
        if (tmpCards.Count < 5) //need atleast 5 cards to make a straight
            return false;

        tmpCards = tmpCards.DistinctBy(v => v.CardValue).ToList(); //remove duplicate values
        tmpCards = tmpCards.OrderBy(x => x.CardValue).ToList(); //order list

        int count = 0;

        if (tmpCards.Zip(tmpCards.Skip(1), (a, b) => (a.CardValue + 1) == b.CardValue).Any(x => x))
        {
            count++;
        }
        else
        {
            count = 0;
        }
        return false;
}

当运行此代码时,linq表达式将检查列表中的任何卡值是否按顺序排列...因此,如果列表包含值为2,3,5,8,11的卡,则会+1计为2和3是顺序的。所以count总是要么是0还是1,这对我没用。理想情况下,如果按顺序排列五张牌,我希望数为5。然后,如果计数等于5,我可以继续找到直线的牌。

(如果一个linq表达式可以确定哪些卡是顺序的,不确定这是否可能在一个表达式思维中,那就更好了。)

我的问题:如何修改我当前的linq表达式以获得我需要的结果?或者,如果我以错误的方式解决这个问题,我是否可以指出正确的方向,提前谢谢。

2 个答案:

答案 0 :(得分:2)

你已经关闭了 - 只需用卡片检查每张卡片后面的4个位置,看看差异是4。

private static bool CheckForStraight()
{
    List<Card> tmpCards = new List<Card>(_cards); //local copy of the cards
    if (tmpCards.Count < 5) //need atleast 5 cards to make a straight
        return false;

    tmpCards = tmpCards.DistinctBy(v => v.CardValue).ToList(); //remove duplicate values
    tmpCards = tmpCards.OrderBy(x => x.CardValue).ToList(); //order list

    return tmpCards
        .Zip(tmpCards.Skip(4), (a, b) => (a.CardValue + 4) == b.CardValue)
        .Any(x => x);
}

答案 1 :(得分:0)

你在一条好的轨道上,现在只需添加一个循环:

private static bool CheckForStraight()
{
    List<Card> tmpCards = _cards.DistinctBy(v => v.CardValue).OrderBy(v => v.CardValue).ToList();
    if(tmpCards.Count < 5) return false;

    int count = 0;

    for(int i = 1; i < tmpCards.Count; i++)
    {
        if(tmpCards[i] != tmpCards[i - 1] + 1 && count < 4) return false;
        count++;
    }
    return count >= 5;
}