protected override void Initialize()
        {
            MyFlop = ((FlopCommunity)MyCommunity).MyFlop;

            if (DerivedSetup.SuitReduce)
            {
                FindRepresentative();

                // Only initialize if this is a representative branch
                if (IsRepresentative())
                    base.Initialize();
            }
            else
            {
                base.Initialize();
            }
        }
        public FlopCommunity(CommunityRoot Parent, Flop flop)
            : base(Parent)
        {
            MyFlop = flop;
            ClassifyAvailability();

            Weight = ((number)1) / Counting.Choose(Card.N - 4, 3);
            Phase = BettingPhase.Flop;
            InitiallyActivePlayer = Player.Dealer;

            MakeScratchSpace();
            CreateBranches();

            #if DEBUG
            InstanceCount++;
            #endif
        }
        public TurnCommunity(FlopCommunity Parent, Flop flop, int turn)
            : base(Parent)
        {
            #if DEBUG
            InstanceCount++;
            #endif

            MyFlop = flop;
            MyTurn = turn;
            ClassifyAvailability();

            Weight = ((number)1) / (Card.N - 4 - 3);
            Phase = BettingPhase.Turn;
            InitiallyActivePlayer = Player.Dealer;

            MakeScratchSpace();
            CreateBranches();
        }
        public Flop(int c1, int c2, int c3)
        {
            this.c1 = c1;
            this.c2 = c2;
            this.c3 = c3;

            if (DerivedSetup.SuitReduce)
            {
                // Get the representative of this flop
                if (CurrentRepresentative == null)
                    CurrentRepresentative = this;
                Representative = CurrentRepresentative;

                // Determine the mapping between this flop and its representative
                for (int s = 0; s < Card.Suits; s++)
                    SuitMap[s] = -1;

                int s1 = Card.GetSuit(c1), s2 = Card.GetSuit(c2), s3 = Card.GetSuit(c3);
                int _s1 = Card.GetSuit(Representative.c1), _s2 = Card.GetSuit(Representative.c2), _s3 = Card.GetSuit(Representative.c3);
                Assert.That(SuitMap[s1] < 0 || SuitMap[s1] == _s1); SuitMap[s1] = _s1;
                Assert.That(SuitMap[s2] < 0 || SuitMap[s2] == _s2); SuitMap[s2] = _s2;
                Assert.That(SuitMap[s3] < 0 || SuitMap[s3] == _s3); SuitMap[s3] = _s3;

                int NextSuit = Math.Max(_s1, Math.Max(_s2, _s3)) + 1;
                for (int s = 0; s < Card.Suits; s++)
                {
                    if (SuitMap[s] < 0)
                    {
                        SuitMap[s] = NextSuit++;
                        Assert.That(SuitMap[s] < Card.Suits);
                    }
                }
                Assert.That(SuitMap.Sum(s => 10 * s) == SuitMapSum);

                // Use the suit map to determine the card mappings and the pocket mappings
                for (int c = 0; c < Card.N; c++)
                    CardMap[c] = MapCard(c, SuitMap);

                for (int p = 0; p < Pocket.N; p++)
                    PocketMap[p] = MapPocket(p, SuitMap);
            }
        }
        public RiverCommunity(TurnCommunity Parent, Flop flop, int turn, int river)
            : base(Parent)
        {
            #if DEBUG
            InstanceCount++;
            #endif

            MyFlop = flop;
            MyTurn = turn;
            MyRiver = river;
            ClassifyAvailability();

            Weight = ((number)1) / (Card.N - 4 - 3 - 1);
            Phase = BettingPhase.River;
            InitiallyActivePlayer = Player.Dealer;

            // Get all pocket values
            PocketValue = new uint[Pocket.N];
            for (int p = 0; p < Pocket.N; p++)
            {
                //if (Collision(p))
                //    PocketValue[p] = 0;//uint.MaxValue;
                //else
                //    PocketValue[p] = Value.Eval(MyFlop, MyTurn, MyRiver, Pocket.Pockets[p]);
                if (AvailablePocket[p])
                    PocketValue[p] = Value.Eval(MyFlop, MyTurn, MyRiver, Pocket.Pockets[p]);
                else
                    PocketValue[p] = 0;//uint.MaxValue;
            }

            // Sort pockets
            SortedPockets = new int[Pocket.N];
            for (int i = 0; i < Pocket.N; i++) SortedPockets[i] = i;

            SortedPocketValue = new uint[Pocket.N];
            PocketValue.CopyTo(SortedPocketValue, 0);

            Array.Sort(SortedPocketValue, SortedPockets);

            MakeScratchSpace();
        }
        public static string CommunityToString(Flop flop, int turn = -1, int river = -1)
        {
            string str = "";

            str += string.Format("({0})", flop);

            if (turn >= 0) str += string.Format(" {0}", ToString(OutputStyle.Number, turn));
            else return str;

            if (river >= 0) str += string.Format(" {0}", ToString(OutputStyle.Number, river));
            else return str;

            return str;
        }
 public string FileString_Community(Flop flop, int turn, int river)
 {
     return string.Format("{0}/{1}/{2}/", Flop.IndexOf(flop), turn, river);
 }
 public string FileString_Community(Flop flop)
 {
     return string.Format("{0}/", Flop.IndexOf(flop));
 }
        public static void InitFlops()
        {
            int TotalFlops = Counting.Choose(Card.N, 3);
            Flops = new List<Flop>(TotalFlops);

            if (DerivedSetup.SuitReduce)
            {
                int S = Card.Vals;

                int Count = 0;

                for (int s = 0; s < Card.Suits; s++)
                    SuitMapSum += 10 * s;

                // Same suit
                for (int v1 = 0; v1 < Card.Vals; v1++)
                    for (int v2 = 0; v2 < v1; v2++)
                        for (int v3 = 0; v3 < v2; v3++)
                        {
                            CurrentRepresentative = null;
                            for (int Suit = 0; Suit < Card.Suits; Suit++)
                                Flops.Add(new Flop(v1 + Suit * S, v2 + Suit * S, v3 + Suit * S));
                        }
                Count += Card.Suits * Counting.Choose(Card.Vals, 3);
                Assert.That(Count == Flops.Count);

                // Two suit
                for (int v1 = 0; v1 < Card.Vals; v1++)
                    for (int v2 = 0; v2 < Card.Vals; v2++)
                        for (int v3 = 0; v3 < v2; v3++)
                        {
                            CurrentRepresentative = null;
                            for (int Suit1 = 0; Suit1 < Card.Suits; Suit1++)
                                for (int Suit2 = 0; Suit2 < Card.Suits; Suit2++)
                                    if (Suit1 != Suit2)
                                        Flops.Add(new Flop(v1 + Suit1 * S, v2 + Suit2 * S, v3 + Suit2 * S));
                        }
                Count += Counting.Permute(Card.Suits, 2) * Card.Vals * Counting.Choose(Card.Vals, 2);
                Assert.That(Count == Flops.Count);

                // Three suit, all different values
                for (int v1 = 0; v1 < Card.Vals; v1++)
                    for (int v2 = 0; v2 < v1; v2++)
                        for (int v3 = 0; v3 < v2; v3++)
                        {
                            CurrentRepresentative = null;
                            for (int Suit1 = 0; Suit1 < Card.Suits; Suit1++)
                                for (int Suit2 = 0; Suit2 < Card.Suits; Suit2++)
                                    for (int Suit3 = 0; Suit3 < Card.Suits; Suit3++)
                                        if (Suit1 != Suit2 && Suit1 != Suit3 && Suit2 != Suit3)
                                            Flops.Add(new Flop(v1 + Suit1 * S, v2 + Suit2 * S, v3 + Suit3 * S));
                        }
                Count += Counting.Permute(Card.Suits, 3) * Counting.Choose(Card.Vals, 3);
                Assert.That(Count == Flops.Count);

                // Three suits, one pair
                for (int v1 = 0; v1 < Card.Vals; v1++)
                    for (int v2 = 0; v2 < Card.Vals; v2++)
                    {
                        if (v1 != v2)
                        {
                            CurrentRepresentative = null;
                            for (int Suit1 = 0; Suit1 < Card.Suits; Suit1++)
                                for (int Suit2 = 0; Suit2 < Card.Suits; Suit2++)
                                    for (int Suit3 = 0; Suit3 < Suit2; Suit3++)
                                        if (Suit2 != Suit1 && Suit3 != Suit1)
                                            Flops.Add(new Flop(v1 + Suit1 * S, v2 + Suit2 * S, v2 + Suit3 * S));
                        }
                    }
                Count += Card.Suits * Counting.Choose(Card.Suits - 1, 2) * Counting.Permute(Card.Vals, 2);
                Assert.That(Count == Flops.Count);

                // Three of a kind
                for (int v1 = 0; v1 < Card.Vals; v1++)
                {
                    CurrentRepresentative = null;
                    for (int Suit1 = 0; Suit1 < Card.Suits; Suit1++)
                        for (int Suit2 = 0; Suit2 < Suit1; Suit2++)
                            for (int Suit3 = 0; Suit3 < Suit2; Suit3++)
                                Flops.Add(new Flop(v1 + Suit1 * S, v1 + Suit2 * S, v1 + Suit3 * S));
                }
                Count += Counting.Choose(Card.Suits, 3) * Card.Vals;
                Assert.That(Count == Flops.Count);

                Assert.That(Flops.Count == TotalFlops);
            }
            else
            {
                for (int c1 = 0; c1 < Card.N; c1++)
                    for (int c2 = 0; c2 < c1; c2++)
                        for (int c3 = 0; c3 < c2; c3++)
                            Flops.Add(new Flop(c1, c2, c3));
            }

            N = Flops.Count;
        }
 /// <summary>
 /// Get the index of a given flop in the Flop list.
 /// </summary>
 public static int IndexOf(Flop flop)
 {
     return Game.FlopLookup[flop.c1, flop.c2, flop.c3];
 }
        public override void SetFlop(int c1, int c2, int c3)
        {
            int flop = Game.FlopLookup[c1, c2, c3];

            if (DerivedSetup.SuitReduce)
            {
                TrueFlop = Flop.Flops[flop];
                flop = Flop.RepresentativeOf(flop);

                TruePocket = Pocket;
                Pocket = TrueFlop.PocketMap[Pocket];
            }

            Head = Head.AdvanceHead(flop);
        }
 public bool Overlaps(Flop flop)
 {
     return flop.Contains(Cards[0]) || flop.Contains(Cards[1]);
 }