public static Players Compare(CardList A, CardList B)
        {
            int tieA = 0, tieB = 0;
            int rankA, rankB;
            Players tieBreaker = CompareHighest(A, B);

            // seems like we should be able to fix this horrible sequence with
            // delegates/function pointers but I can't see how to do it
            // easily

            var functions = new List<RankDelegate>() {
                RankRoyalFlush,
                RankStraightFlush,
                RankFourOfAKind,
                RankFullHouse,
                RankFlush,
                RankStraight,
                RankThreeOfAKind,
                RankTwoPairs,
                RankOnePair,
                RankHighCard
            };

            foreach (RankDelegate f in functions)
            {
                tieA = 0;
                tieB = 0;
                rankA = f(A, ref tieA);
                rankB = f(B, ref tieB);
                if (rankA + rankB > 0)
                {
                    Players p = CompareScore(rankA, tieA, rankB, tieB);
                    if (p == Players.Tie)
                    {
                        p = tieBreaker;
                    }
                    Console.Write(String.Join(", ", A));
                    Console.Write(" | ");
                    Console.Write(String.Join(", ", B));
                    Console.WriteLine();
                    Console.WriteLine("Player {0} won on {1}",
                        p.ToString(),
                        f.Method.Name
                    );
                    return p;
                }
            }
            throw new Exception("");
        }
 static IEnumerable<int> Values(CardList cards)
 {
     return cards.Select(c => Value(c));
 }
        private static int RankTwoPairs(CardList cards, ref int tie)
        {
            var values = Values(cards).ToList();
            List<int> counted = new List<int>();

            foreach (int v in values)
            {
                if (counted.Contains(v)) continue;

                if (values.Count(x => x == v) >= 2)
                {
                    counted.Add(v);
                }
            }
            if (counted.Count >= 2)
            {
                tie = counted.Max();
                return (int)Ranks.TwoPairs;
            }
            return 0;
        }
 private static int RankThreeOfAKind(CardList cards, ref int tie)
 {
     var values = Values(cards);
     foreach (int v in values)
     {
         if (values.Count(x => x == v) >= 3)
         {
             tie = v;
             return (int)Ranks.ThreeOfAKind;
         }
     }
     return 0;
 }
        /// <summary>
        /// Ranks a straight flush and removes cards
        /// </summary>
        /// <param name="cards"></param>
        /// <returns></returns>
        private static int RankStraightFlush(CardList cards, ref int tieBreaker)
        {
            if (!AllSameHouse(cards)) { return 0; }
            var values = Values(cards).ToList();
            values.Sort();

            for (int i = 1; i < values.Count; i++)
            {
                if (values.ElementAt(i) != values.ElementAt(0) + i)
                {
                    return 0;
                }
            }

            // is a flush
            tieBreaker = values.Max();
            //cards.RemoveRange(0, cards.Count);
            return (int)Ranks.StraightFlush;
        }
 /// <summary>
 /// Ranks a straight
 /// </summary>
 /// <param name="cards"></param>
 /// <param name="tieBreaker"></param>
 /// <returns></returns>
 private static int RankStraight(CardList cards, ref int tieBreaker)
 {
     var values = Values(cards).ToList();
     values.Sort();
     for (int i = 1; i < values.Count; i++)
     {
         if (values[0] + i != values[i])
         {
             return 0;
         }
     }
     tieBreaker = values.Max();
     return (int)Ranks.Straight;
 }
        /// <summary>
        /// Ranks a royal flush and removes cards
        /// </summary>
        /// <param name="cards"></param>
        /// <returns></returns>
        private static int RankRoyalFlush(CardList cards, ref int tieBreaker)
        {
            if (!AllSameHouse(cards))
            {
                return 0;
            }
            tieBreaker = 0;
            var flushVals = new List<string>() {
                "T", "J", "Q", "K", "A"
            }.Select(c => Value(c)).ToList();

            var ourVals = Values(cards).ToList();
            flushVals.Sort();
            ourVals.Sort();
            if (Enumerable.SequenceEqual(flushVals, ourVals))
            {
                //cards.RemoveRange(0, cards.Count);
                return (int)Ranks.RoyalFlush;
            }
            return 0;
        }
        private static Players CompareHighest(CardList A, CardList B)
        {
            var aVals = Values(A).ToList();
            var bVals = Values(B).ToList();
            aVals.Sort();
            bVals.Sort();
            aVals.Reverse();
            bVals.Reverse();

            for (int i = 0; i < aVals.Count; i++)
            {
                int a = aVals[i], b = bVals[i];
                if (a == b) { continue; }
                if (a > b)
                {
                    return Players.A;
                }
                else
                {
                    return Players.B;
                }
            }
            return Players.Tie;
        }
 private static int RankHighCard(CardList cards, ref int tie)
 {
     return Values(cards).Max();
 }
 /// <summary>
 /// Rank a full house and remove cards
 /// </summary>
 /// <param name="cards"></param>
 /// <returns></returns>
 private static int RankFullHouse(CardList cards, ref int tieBreaker)
 {
     var values = Values(cards).ToList();
     int triple = -1;
     int pair = -1;
     foreach (int v in values)
     {
         if (values.Count(x => x == v) == 3)
         {
             triple = v;
         }
         else if (values.Count(x => x == v) == 2)
         {
             pair = v;
         }
     }
     if (pair == -1 || triple == -1) { return 0; }
     tieBreaker = triple;
     return (int)Ranks.FullHouse;
 }
 /// <summary>
 /// Ranks matching a four of a kind
 /// </summary>
 /// <param name="cards"></param>
 /// <returns></returns>
 private static int RankFourOfAKind(CardList cards, ref int tieBreaker)
 {
     var values = Values(cards).ToList();
     foreach (int v in values)
     {
         if (values.Count(x => x == v) >= 4)
         {
             tieBreaker = v;
             return (int)Ranks.FourOfAKind;
         }
     }
     return 0;
 }
 /// <summary>
 /// Ranks  a flush
 /// </summary>
 /// <param name="cards"></param>
 /// <param name="tieBreaker"></param>
 /// <returns></returns>
 private static int RankFlush(CardList cards, ref int tieBreaker)
 {
     if (!AllSameHouse(cards)) { return 0; }
     tieBreaker = Values(cards).Max();
     return (int)Ranks.Flush;
 }
        static void Main(string[] args)
        {
            List<string> A, B;
            A = new List<string>() {
                "5H", "5C", "6S", "7S", "KD"
            };
            B = new List<string>() {
                "2C", "3S", "8S", "8D", "TD"
            };
            Compare(A, B);

            A = new List<string>() {
                "5D", "8C", "9S", "JS", "AC"
            };
            B = new List<string>() {
                "2C", "5C", "7D", "8S", "QH"
            };
            Compare(A, B);

            A = new List<string>() {
                "2D", "9C", "AS", "AH", "AC"
            };
            B = new List<string>() {
                "3D", "6D", "7D", "TD", "QD"
            };
            Compare(A, B);

            A = new List<string>() {
                "4D", "6S", "9H", "QH", "QC"
            };
            B = new List<string>() {
                "3D", "6D", "7H", "QD", "QS"
            };
            Compare(A, B);

            A = new List<string>() {
                "2H", "2D", "4C", "4D", "4S"
            };
            B = new List<string>() {
                "3C", "3D", "3S", "9S", "9D"
            };
            Compare(A, B);
            Console.ReadLine();
            //System.Environment.Exit(0);

            string[] lines = File.ReadAllLines("poker.txt");
            int aWins = 0;
            int bWins = 0;
            int draws = 0;
            foreach (string line in lines)
            {
                string[] s = line.Split(' ');
                CardList a = new CardList();
                CardList b = new CardList();
                for (int i = 0; i < s.Length; i++)
                {
                    if (i < 5) a.Add(s[i]);
                    else b.Add(s[i]);
                }
                if (a.Count != b.Count || a.Count != 5)
                {
                    throw new Exception();
                }
                Players winner = Compare(a, b);
                if (winner == Players.A)
                {
                    aWins++;
                }
                else if (winner == Players.B)
                {
                    bWins++;
                }
                else if (winner == Players.Tie)
                {
                    draws++;
                }
            }
            Console.WriteLine("{0} {1} {2}", aWins, bWins, draws);
            Euler.Utils.OutputAnswer(aWins.ToString());
        }
 static IEnumerable<char> Houses(CardList cards)
 {
     return cards.Select(c => House(c));
 }
 private static int RankOnePair(CardList cards, ref int tie)
 {
     var values = Values(cards).ToList();
     foreach (int v in values)
     {
         if (values.Count(x => x == v) >= 2)
         {
             tie = v;
             return (int)Ranks.OnePair;
         }
     }
     return 0;
 }
 static bool AllSameHouse(CardList cards)
 {
     var DiffHouses = Houses(cards).Where(h => h != House(cards.ElementAt(0)));
     return DiffHouses.Count() == 0;
 }
Example #17
0
 public Variable()
 {
     FactorName = new FactorName();
     Factors = new Factors();
 }