Пример #1
0
        public Node Expand()
        {
            LimitHoldEmAction action = unexploredActions[0];

            unexploredActions.RemoveAt(0);
            LimitHoldEmState newState  = state.Step(action);
            Node             childNode = new Node(newState, this);

            children.Add(childNode);
            return(childNode);
        }
Пример #2
0
        public double Rollout(Node node)
        {
            LimitHoldEmState currentState = node.state;

            while (!currentState.isTerminal)
            {
                List <LimitHoldEmAction> actions = currentState.GetActions();
                Random            random         = new Random();
                LimitHoldEmAction action         = actions[random.Next(0, actions.Count)];
                currentState = currentState.Step(action);
            }

            return(currentState.reward);
        }
Пример #3
0
        static void Play(LHEPolicy lhePolicy, uint userIndex = 0)
        {
            LimitHoldEmState  state              = new LimitHoldEmState();
            LimitHoldEmAction selectedAction     = LimitHoldEmAction.Call;
            string            selectedActionName = "";
            double            winnings           = 0;

            while (true)
            {
                state.Reset();
                while (!state.isTerminal)
                {
                    if (state.playerIndex == userIndex)
                    {
                        Console.WriteLine("Your cards: " + state.holeCards[userIndex]);
                        Console.WriteLine("Community cards: " + state.communityCards);
                        Console.WriteLine("Total winnings so far: " + winnings);
                        uint pot = state.potContributions[0] + state.potContributions[1];
                        Console.WriteLine("Pot: " + pot);

                        selectedActionName = "";

                        while (selectedActionName != "c" && selectedActionName != "f" && selectedActionName != "r")
                        {
                            selectedActionName = Console.ReadLine();
                            selectedActionName = selectedActionName.ToLower();

                            if (selectedActionName == "q" || selectedActionName == "quit")
                            {
                                Environment.Exit(0);
                            }
                        }
                        switch (selectedActionName)
                        {
                        case "c":
                            selectedAction = LimitHoldEmAction.Call;
                            break;

                        case "f":
                            selectedAction = LimitHoldEmAction.Fold;
                            break;

                        case "r":
                            selectedAction = LimitHoldEmAction.Raise;
                            break;
                        }
                    }
                    else
                    {
                        uint              bucket    = state.Discretize(state.street, state.playerIndex);
                        string            policyKey = bucket.ToString() + state.previousActions;
                        string            actionName;
                        LimitHoldEmAction bestAction     = LimitHoldEmAction.Call;
                        double            bestValue      = double.MinValue;
                        string            bestActionName = "c";
                        foreach (LimitHoldEmAction action in state.GetActions())
                        {
                            switch (action)
                            {
                            case LimitHoldEmAction.Fold:
                                actionName = "f";
                                break;

                            case LimitHoldEmAction.Raise:
                                actionName = "r";
                                break;

                            default:
                                actionName = "c";
                                break;
                            }

                            string newKey      = policyKey + actionName;
                            double actionValue = lhePolicy.policy[newKey].value;
                            if (state.playerIndex == 1)
                            {
                                actionValue *= -1;
                            }

                            if (actionValue > bestValue)
                            {
                                bestValue      = actionValue;
                                bestAction     = action;
                                bestActionName = actionName;
                            }

                            selectedAction     = bestAction;
                            selectedActionName = bestActionName;
                        }

                        Console.WriteLine("\nSmoothUCT: " + selectedActionName + "\n");
                    }

                    state = state.Step(selectedAction);
                }

                uint opponent = (userIndex == 0) ? 1u : 0;
                Console.WriteLine("\nSmoothUCT cards: " + state.holeCards[opponent]);
                double hand_winnings;
                if ((state.reward > 0 && userIndex == 0) || (state.reward < 0 && userIndex == 1))
                {
                    hand_winnings = state.potContributions[opponent];
                    Console.WriteLine("You win " + hand_winnings);
                    winnings += hand_winnings;
                }
                else if (state.reward == 0)
                {
                    Console.WriteLine("Split pot");
                }
                else
                {
                    hand_winnings = state.potContributions[userIndex];
                    Console.WriteLine("SmoothUCT wins " + hand_winnings);
                    winnings -= hand_winnings;
                }

                userIndex = (userIndex + 1) % 2;
                Console.WriteLine("==========================================================================================");
            }
        }
Пример #4
0
        public LimitHoldEmState Step(LimitHoldEmAction action)
        {
            LimitHoldEmState newState = (LimitHoldEmState)Clone();
            uint             opponent = (newState.playerIndex == 0) ? 1u : 0;

            switch (action)
            {
            case LimitHoldEmAction.Fold:
                newState.previousActions += "f";
                newState.isTerminal       = true;
                newState.reward           = newState.potContributions[newState.playerIndex];
                if (newState.playerIndex == 0)        // max player is folding
                {
                    newState.reward *= -1;
                }
                break;

            case LimitHoldEmAction.Raise:
                newState.previousActions += "r";
                ++newState.nStreetBets;
                newState.potContributions[playerIndex] = newState.potContributions[opponent] + ((newState.street < 2) ? 2u : 4u);
                newState.playerIndex = opponent;
                break;

            case LimitHoldEmAction.Call:
                newState.previousActions += "c";
                newState.potContributions[newState.playerIndex] = newState.potContributions[opponent];

                // player checks
                if (newState.nStreetBets == 0 &&
                    ((newState.street == 0 && newState.playerIndex == 0) || newState.street > 0 && newState.playerIndex == 1))
                {
                    newState.playerIndex = opponent;
                }

                // player calls
                else
                {
                    if (newState.street == 0)
                    {
                        // advance from preflop to flop
                        newState.communityCards = newState.Deal() + " " + newState.Deal() + " " + newState.Deal();
                    }

                    else if (newState.street == 1 || newState.street == 2)
                    {
                        // advance from flop to turn or turn to river
                        newState.communityCards += " " + newState.Deal();
                    }

                    else
                    {
                        // end of hand
                        newState.isTerminal = true;

                        ulong   boardMask = Hand.ParseHand(newState.communityCards);
                        ulong[] handValue = new ulong[2];
                        for (int i = 0; i < 2; ++i)
                        {
                            handValue[i] = Hand.Evaluate(boardMask | Hand.ParseHand(newState.holeCards[i]), 7);
                        }

                        // ties would set reward to 0.0 but that is already the default
                        if (handValue[0] != handValue[1])
                        {
                            // both players are guaranteed to have contributed same amount
                            newState.reward = newState.potContributions[0];

                            if (handValue[1] > handValue[0])
                            {
                                newState.reward *= -1;
                            }
                        }
                    }

                    newState.nStreetBets = 0;
                    ++newState.street;
                    newState.playerIndex = 1u;
                }
                break;
            }

            return(newState);
        }