骰子问题(满屋和直接识别)

时间:2011-06-26 10:15:30

标签: c# regex poker dice

我正在制作一个骰子游戏。有5个骰子,我有所有的值,我需要确定它们是否构成一个完整的房子(一个中的3个和另一个中的2个),小直(1-4,2-6或3-6)或一个大直(1-5,2-6)。

或许最好的解决方法似乎是使用正则表达式。

有谁知道如何在正则表达式中表示这些规则?

或者,如果您能提供更好的解决方案,我会很感激。

示例:

  • 满屋= 44422或11166或12212等。
  • Small Straight = 12342或54532等。
  • 大直= 12345或52643等

修改
改变了措辞,强调这是我没有经验的意见。

我知道如何使用代码来实现这一点,但它看起来像是一个冗长的解决方案,我想知道是否有更简单的方法。

7 个答案:

答案 0 :(得分:5)

无论是在int []还是字符串中,我都会对所有数字进行排序,然后对每个值进行一些线性标准匹配。

答案 1 :(得分:5)

不知道c#,但是用脚本语言我会采用正则表达式路由。对于每一方,计算组合中出现的次数并将结果连接在一起。例如,对于组合12342,计数器字符串将为121100。然后将计数器字符串与这些模式匹配:

/5/         = Five of a kind
/4/         = Four of a kind
/20*3|30*2/ = Full house
/1{5}/      = Large Straight
/[12]{4}/   = Small Straight
/3/         = Three of a kind
/2[013]*2/  = Two pair
/2/         = One pair

答案 2 :(得分:0)

您始终可以执行LINQ汇总查询并计算相同卡的数量。它会类似于(无法测试):

var query =  from card in hand
             group card by card into groupedCards
             select new { Card = groupedCards.Key, Count = groupedCards.Count() };

通过这种方式,您可以轻松地知道您是否正在处理可能的直线(或者根本没有),一对,三重等等。

我不是LINQ专家,我现在无法测试这段代码,所以我不确定它是否会按原样进行编译,但它可以帮助您或者让您了解如何解决手头的问题。

例如:

  1. 如果count query = 5:我们正在处理空手,同花顺或直线=>运行特定的冲洗/直线逻辑。

  2. 如果count query = 4:我们正在处理一对。

  3. 如果count query = 3:我们正在处理双重对或三重=>如果最大计数= 3,那么三倍

  4. 如果count query = 2:我们正在处理一个完整的房子/扑克。如果max count = 4则扑克

答案 3 :(得分:0)

我不会评论您如何查找结果,而是评论如何存储结果以供以后查找。

由于你只有46656种可能的组合,而且一个字节可以存储所产生的手部力量,这个问题比扑克手问题容易得多。

您可以拥有一个查找表,该表由指针组成,并与该指针的结果相关联(一些指针可以有多个结果)。每个字节都可以将所有手型存储为二进制表示(希望如果不使用短的话)。

您获得的每个数字(例如66655 - 满堂)是六(1-6)的数字,将其转换为基数为10的数字,以便在查找表中获取索引。

它需要大约46656个字节(+ CPU对齐),并且可以适合CPU L2缓存。速度很高,因为您需要做的唯一操作是转换数字基数,并使用二进制OR运算来提取手势。

你会想念的是一只手的真正力量。例如。 66655比66644好。你可以轻松搞清楚 - 你需要一个更大的类型来存储结果:)

答案 4 :(得分:0)

我决定尝试自己,最后我没有使用正则表达式 - 我认为可能需要简单的搜索,正则表达式会增加比保存更多的复杂性。我在另一个答案中使用了类似的逻辑:计算每个数字的数量并根据该数字得出所有得分:

  enum RollScoreType
  {
     HighDie,
     Pair,
     TwoPair,
     ThreeOfAKind,
     SmallStright,
     PairSmallStriaght,
     FullHouse,
     LargeStraight,
     FourOfAKind,
     FiveOfAKind
  }

  struct RollScore
  {
     public RollScoreType type;
     public byte highestDie;
     public byte nextHighestDie;
     public RollScore(RollScoreType type, byte highest, byte next)
     {
        this.type = type;
        this.highestDie = highest;
        this.nextHighestDie = next;
     }
     public override string ToString()
     {
        return string.Format("{0} {1} {2}", type, highestDie, nextHighestDie);
     }
  }

  static RollScore GetDiceScore(string input)
  {
     char[] dice = input.ToCharArray();
     byte[] diceCount = new byte[6];

     for (int i = 0; i < dice.Length; i++)
        diceCount[int.Parse(dice[i].ToString())-1]++;

     if (Array.IndexOf(diceCount, (byte)5) >= 0)
        return new RollScore(RollScoreType.FiveOfAKind, (byte)(Array.IndexOf(diceCount, (byte)5) + 1), 0);
     else if (Array.IndexOf(diceCount, (byte)4) >= 0)
        return new RollScore(RollScoreType.FourOfAKind, (byte)(Array.IndexOf(diceCount, (byte)4) + 1), (byte)(Array.IndexOf(diceCount, (byte)1) + 1));
     else if (Array.IndexOf(diceCount, (byte)3) >= 0)
     {
        byte three = (byte)(Array.IndexOf(diceCount, (byte)3) + 1);
        if (Array.IndexOf(diceCount, (byte)2) >= 0)
        {
           byte pair = (byte)(Array.IndexOf(diceCount, (byte)2) + 1);
           return new RollScore(RollScoreType.FullHouse, Math.Max(pair, three), Math.Min(pair, three));
        }
        else
           return new RollScore(RollScoreType.ThreeOfAKind, three, (byte)(Array.LastIndexOf(diceCount, (byte)1) + 1));
     }
     else if (Array.IndexOf(diceCount, (byte)2) >= 0)
     {
        byte pair = (byte)(Array.IndexOf(diceCount, (byte)2) + 1);
        byte highPair = (byte)(Array.LastIndexOf(diceCount, (byte)2) + 1);
        if (highPair != pair)
           return new RollScore(RollScoreType.TwoPair, highPair, pair);
        else
        {
           byte lowMissingDie = (byte)Array.IndexOf(diceCount, (byte)0);
           byte highMissingDie = (byte)Array.LastIndexOf(diceCount, (byte)0);
           switch (lowMissingDie)
           {
              case 0:
                 if (highMissingDie == 5)
                    return new RollScore(RollScoreType.PairSmallStriaght, 5, 4);
                 if (highMissingDie == 1)
                    return new RollScore(RollScoreType.PairSmallStriaght, 6, 5);
                 break;
              case 4:
                 return new RollScore(RollScoreType.PairSmallStriaght, 4, 3);
           }
           return new RollScore(RollScoreType.Pair, pair, (byte)(Array.LastIndexOf(diceCount, (byte)1) + 1));
        }
     }
     byte missingDie = (byte)Array.IndexOf(diceCount, (byte)0);
     switch(missingDie)
     {
        case 0:
           return new RollScore(RollScoreType.LargeStraight, 6, 5);
        case 1:
           return new RollScore(RollScoreType.SmallStright, 6, 5);
        case 4:
           return new RollScore(RollScoreType.SmallStright, 4, 3);
        case 5:
           return new RollScore(RollScoreType.LargeStraight, 5, 4);                  
        default:
           return new RollScore(RollScoreType.HighDie, 6, (byte)(Array.LastIndexOf(diceCount, (byte)1, 3) + 1));
     }
  }

令我惊讶的是,我发现,在5个模具辊中,小直线和大直线的概率是相等的。这是真的吗??

编辑:已修复;我看到当我包括一对包含一对的小直道时,小直线的概率显着上升。

当我考虑它时,一对和一个小直线应该使用该对作为最高的模具,并且直线中的最高数量作为下一个最高(为了[正确比较两个都是一对的两个卷]小直)。如果是这样,我将用以下代码替换处理PairSmallStraight的代码块:

           switch (lowMissingDie)
           {
              case 0:
                 if (highMissingDie == 5)
                    return new RollScore(RollScoreType.PairSmallStriaght, pair, 5);
                 if (highMissingDie == 1)
                    return new RollScore(RollScoreType.PairSmallStriaght, pair, 6);
                 break;
              case 4:
                 return new RollScore(RollScoreType.PairSmallStriaght, pair, 4);
           }

答案 5 :(得分:0)

您可以尝试将值放入列表中。这样您就可以快速对值进行排序。如果你添加可以提供帮助的值。 111AA = 29和222KK = 30.只是一个想法。

答案 6 :(得分:0)

这是我的代码:

    public static int   CalculateTotalOfSingles       (int pipNumber)
    {
        //
        var myScore = 0;
        foreach (var myDie in Roll5Player.MyHand.Dice)
        {
            {   if (myDie.Pips == pipNumber)
                myScore+= pipNumber;
            }
        }
        //
        return myScore;
    }
    public static int   CalculateDicePips       ()
    {
        //
        var myScore = 0;
        foreach (var myDie in Roll5Player.MyHand.Dice)
        {
            {myScore += myDie.Pips;
            }
        }
        //
        return myScore;
    }
    //
    //
    //
    public static int   CalculateTotalOfAllSingles    (int pipNumber)
    {
        //
        var myScore = 0;
        for (int i = 1; i <= 6; i++)
        {
            myScore += pipNumber;
        }
        //
        return myScore;
    }
    public static bool  CalculateIsNOfaKind     (int count)
    {
        //
        for (var index = 1; index <= 6; index++)
        {
            var cntr = 0;
            foreach (var myDie in Roll5Player.MyHand.Dice)
            {
                if (myDie.Pips == index)
                    cntr++;
            }
            //
            if (cntr == count)
            {
                return true;
                ;
            }
        }
        //
        return false;
    }
    public static int   CalculateNOfaKind       (int count  )
    {
        //
        var myScore = 0;
        for (var index = 1; index <= 6; index++)
        {
            var cntr = 0;
            foreach (var myDie in Roll5Player.MyHand.Dice)
            {
                    if (myDie.Pips == index)
                        cntr++;
            }
            //
            if (cntr >= count)
            {   myScore = CalculateDicePips();
                return myScore;
                ;
            }
        }
        //
        return myScore;
    }
    /// 
    public static int   CaluclateFullHouse      (           )
    {
        // 
        var myScore = 0;
        var cntr    = new int[6];
        for (var index = 1; index <= 6; index++)
        {
            foreach (var myDie in Roll5Player.MyHand.Dice)
            {
                if (myDie.Pips == index)
                    cntr[index-1]++;
            }
        }

        //
        var boolCondA = false;
        var boolCondB = false;
        foreach (var i in cntr)
        {
            if (i == 3)
            {boolCondA = true;
                break;
            }
        }
        if (boolCondA)
        {
            foreach (var i in cntr)
            {
                if (i == 2)
                {boolCondB = true;
                    break;
                }
            }
        }


        //
        if (boolCondB ) 
            myScore = CalculateDicePips();



        //
        //
        //
        return myScore;
    }
    public static int   CaluclateStraights      (int straightCount, int score)
    {
        // 
        var tempPip     = 0;
        var myScore     = 0;
        var isFirstIteration = true;
        var cntr = 0;
        int[] sortedDice = new int[5];
        var sortedDiceLise = new List<int>();


        foreach (var myDie in Roll5Player.MyHand.Dice)
        {
            sortedDiceLise.Add(myDie.Pips);
        }
        sortedDiceLise.Sort();







        foreach (var myDie in sortedDiceLise)
        {
            //
            //
            if (!isFirstIteration)
            {
                if (myDie == tempPip + 1)
                    cntr++;
            }
            //
            isFirstIteration = false;
            tempPip = myDie;
        }





        if (cntr == straightCount - 1)
        {myScore = score;
        }

        //
        //
        //
        return myScore;
    }

    public static int   CalculateYahtzee        ()
    {
        //
        for (var index = 1; index <= 6; index++)
        {
            var cntr = 0;
            foreach (var myDie in Roll5Player.MyHand.Dice)
            {
                if (myDie.Pips == index)
                    cntr++;
            }
            //
            if (cntr == 5)
            {
                return 50;
                ;
            }
        }
        //
        return 0;
    }