예제 #1
0
        //Rollout function (plays random moves till it hits a termination)
        protected override void rollout(AIState rolloutStart)
        {
            //If the rollout start is a terminal state
            int rolloutStartResult = rolloutStart.getWinner();

            if (rolloutStartResult >= 0)
            {
                //Add a win is it is a win, or a loss is a loss or otherwise a draw
                if (rolloutStartResult == rolloutStart.playerIndex)
                {
                    rolloutStart.addWin();
                }
                else if (rolloutStartResult == (rolloutStart.playerIndex + 1) % 2)
                {
                    rolloutStart.addLoss();
                }
                else
                {
                    rolloutStart.addDraw(drawScore);
                }
                return;
            }
            bool terminalStateFound = false;
            //Get the children
            List <AIState> children = rolloutStart.generateChildren();

            int loopCount = 0;

            while (!terminalStateFound)
            {
                //Loop through till a terminal state is found
                loopCount++;
                //If max roll out is hit or no childern were generated
                if (loopCount >= maxRollout || children.Count == 0)
                {
                    //Record a draw
                    rolloutStart.addDraw(drawScore);
                    break;
                }
                //Get a random child index
                int index = randGen.Next(children.Count);
                //and see if that node is terminal
                int endResult = children[index].getWinner();
                if (endResult >= 0)
                {
                    terminalStateFound = true;
                    if (endResult == 2)
                    {
                        rolloutStart.addDraw(drawScore);
                    }
                    //If it is a win add a win
                    else if (endResult == rolloutStart.playerIndex)
                    {
                        rolloutStart.addWin();
                    }
                    //Else add a loss
                    else
                    {
                        rolloutStart.addLoss();
                    }
                }
                else
                {
                    //Otherwise select that nodes as the childern and continue
                    children = children [index].generateChildren();
                }
            }
            //Reset the children as these are not 'real' children but just ones for the roll out.
            foreach (AIState child in rolloutStart.children)
            {
                child.children = new List <AIState>();
            }
        }
예제 #2
0
        //Rollout function (plays random moves till it hits a termination)
        protected override void rollout(AIState rolloutStart)
        {
            //If the rollout start is a terminal state
            int rolloutStartResult = rolloutStart.getWinner();

            if (rolloutStartResult >= 0)
            {
                //Add a win is it is a win, or a loss is a loss or otherwise a draw
                if (rolloutStartResult == rolloutStart.playerIndex)
                {
                    rolloutStart.addWin();
                }
                else if (rolloutStartResult == (rolloutStart.playerIndex + 1) % 2)
                {
                    rolloutStart.addLoss();
                }
                else
                {
                    rolloutStart.addDraw(drawScore);
                }
                return;
            }
            bool terminalStateFound = false;
            //Get the children
            List <AIState> children = rolloutStart.generateChildren();

            int loopCount = 0;

            while (!terminalStateFound)
            {
                //Loop through till a terminal state is found
                loopCount++;
                //If max roll out is hit or no childern were generated
                if (loopCount >= maxRollout || children.Count == 0)
                {
                    //record a draw
                    rolloutStart.addDraw(drawScore);
                    break;
                }
                //Default is the end of the array (because that will be the best move in a sorted list)
                int selectedChild = children.Count - 1;

                //epsilon greedy move selection.
                if (randGen.NextDouble() < epsilon)
                {
                    //Sort the array (we have all ready selected the most move indx above
                    foreach (AIState child in children)
                    {
                        if (child.stateScore == null)
                        {
                            child.stateScore = model.evaluate(child);
                        }
                    }
                    children = AIState.mergeSort(children);
                }
                else
                {
                    //Just select a random move
                    selectedChild = randGen.Next(children.Count);
                }
                //and see if that node is terminal
                int endResult = children[selectedChild].getWinner();
                if (endResult >= 0)
                {
                    terminalStateFound = true;
                    if (endResult == 2)
                    {
                        rolloutStart.addDraw(drawScore);
                    }
                    //If it is a win add a win
                    else if (endResult == rolloutStart.playerIndex)
                    {
                        rolloutStart.addWin();
                    }
                    //Else add a loss
                    else
                    {
                        rolloutStart.addLoss();
                    }
                }
                else
                {
                    //Otherwise select that nodes as the childern and continue
                    children = children [selectedChild].generateChildren();
                }
            }
            //Reset the children as these are not 'real' children but just ones for the roll out.
            foreach (AIState child in rolloutStart.children)
            {
                child.treeNode = true;
            }
        }