Beispiel #1
0
    public double simulate() //It simulates all the way to the end of the game, from currentNode
    {                        //Based on the result of the simulation(Win/lose), it return different sim value, used to judge whether its a good node or not
        MCTSState simState = new MCTSState(state.currentTurn, state.drawDeck, state.discardDeck, state.humanCards, state.AICards, state.hasDrawn, state.lastDiscard, state.lastDrawDeck);

        simState.stateResult = state.stateResult;
        int simValue = int.MinValue;

        while (simState.stateResult == MCTSState.Result.None && simState.drawDeck.Count > 0)
        {
            if (!simState.hasDrawn)//In Draw phase
            {
                simState.hasDrawn = true;

                if (simState.currentTurn == Main.Turn.AI) //AI's turn
                {
                    if (simState.discardDeck.Count > 0)
                    {
                        if (simState.AICards.NumOfCardsOfType(simState.discardDeck.GetTop().MeldType) == 2) //if drawing from discard deck can form a meld
                        {
                            simState.AICards.Add(simState.discardDeck.Pop());                               //Draw from discard deck
                        }

                        else
                        {
                            simState.AICards.Add(simState.drawDeck.Pop());   //Other wise just take from draw deck
                        }
                    }
                    else     //If no card in discard deck, draw from draw deck
                    {
                        simState.AICards.Add(simState.drawDeck.Pop());
                    }

                    if (simState.drawDeck.Count <= 0)  //After draw finish, if the draw deck is empty, mark the game result as draw
                    {
                        simState.stateResult = MCTSState.Result.Draw;
                        break;
                    }

                    if (CardsInHand.CheckVictory(simState.AICards))       //If victory goal met, mark the game result as AIWIN
                    {
                        simState.stateResult = MCTSState.Result.AIWin;
                        break;
                    }
                }
                else if (simState.currentTurn == Main.Turn.Human)  //Human's turn,everything same as above, basically duplicated code
                {
                    if (simState.discardDeck.Count > 0)
                    {
                        if (simState.humanCards.NumOfCardsOfType(simState.discardDeck.GetTop().MeldType) == 2)  //if drawing from discard deck can form a meld
                        {
                            simState.humanCards.Add(simState.discardDeck.Pop());
                        }
                        else
                        {
                            simState.humanCards.Add(simState.drawDeck.Pop());
                        }
                    }
                    else
                    {
                        simState.humanCards.Add(simState.drawDeck.Pop());
                    }

                    if (simState.drawDeck.Count <= 0)
                    {
                        simState.stateResult = MCTSState.Result.Draw;
                        break;
                    }

                    if (CardsInHand.CheckVictory(simState.humanCards))
                    {
                        simState.stateResult = MCTSState.Result.HumanWin;
                        break;
                    }
                }
            }

            else if (simState.hasDrawn)//In discard phase
            {
                simState.hasDrawn = false;
                if (simState.currentTurn == Main.Turn.AI)                                       //AI's turn
                {
                    MeldType typeToDiscard = MostUselessType(simState.AICards);                 //Get the least valuable meld type among the cards in hand
                    Card     cardToDiscard = simState.AICards.GetCardByMeldType(typeToDiscard); //get a card of that meld type, then discard it
                    simState.AICards.Remove(cardToDiscard);
                    simState.AICards.LeftShiftElement();
                    simState.discardDeck.Add(cardToDiscard);
                    simState.discardDeck.LeftShiftElement();
                    simState.currentTurn = Main.Turn.Human;
                }

                else   //duplicated code
                {
                    MeldType typeToDiscard = MostUselessType(simState.humanCards);
                    Card     cardToDiscard = simState.humanCards.GetCardByMeldType(typeToDiscard);
                    simState.humanCards.Remove(cardToDiscard);
                    simState.humanCards.LeftShiftElement();
                    simState.discardDeck.Add(cardToDiscard);
                    simState.discardDeck.LeftShiftElement();
                    simState.currentTurn = Main.Turn.AI;
                }
            }
        }

        switch (simState.stateResult)
        {
        case MCTSState.Result.Draw:
        {
            // Debug.Log("Draw result simed");
            simValue = 0;
            break;
        }

        case MCTSState.Result.HumanWin:
        {
            // Debug.Log("HumanWin result simed");
            simValue = -1;         //1 means victory, -1 means defeat
            break;
        }

        case MCTSState.Result.AIWin:
        {
            //Debug.Log("AIWin result simed");
            simValue = 1;
            break;
        }

        default:
        {
            // Debug.LogError("illegal simStateResult value");
            break;
        }
        }
        return(simValue);
    }
Beispiel #2
0
 public TreeNode(MCTSState state)
 {
     this.state = state;
 }