コード例 #1
0
        public static Action Minimax(PentagoBoard currentState, Status.StateEnum color, int depth, NodeSelecter sel, StateEvaluater eva)
        {
            Action    bestAction = null;
            Placement curPlc     = new Placement()
            {
                Player = color,
            };
            Rotation curRtt = new Rotation();


            for (int i = 0; i < currentState.TotalWidth; i++)
            {
                for (int j = 0; j < currentState.TotalHeight; j++)
                {
                    if (currentState[i, j].State == Status.StateEnum.empty)
                    {
                        //curPlc = new Placement();
                        curPlc.X = i;
                        curPlc.Y = j;
                        curPlc.Do(currentState);

                        for (int k = 0; k < currentState.Sections.Count; k++)
                        {
                            //curRtt = new Rotation();
                            curRtt.SectionNo = k;
                            curRtt.Clockwise = true;
                            curRtt.Do(currentState);

                            if (depth <= 1 || currentState.IsFull(Status.StateEnum.empty) ||
                                currentState.HasConsecutiveNPiece(color, 5) ||
                                currentState.HasConsecutiveNPiece(GetOppoColor(color), 5))
                            {
                                int value = eva(currentState, color);
                                if (bestAction == null)
                                {
                                    bestAction       = new Action(curPlc, curRtt);
                                    bestAction.Value = value;
                                }
                                else if (sel(bestAction.Value, value) > 0)
                                {
                                    bestAction.SetAction(curPlc, curRtt);
                                    bestAction.Value = value;
                                }
                            }
                            else
                            {
                                var subAction = Minimax(currentState, GetOppoColor(color), depth - 1, sel, eva);
                                if (bestAction == null)
                                {
                                    bestAction       = new Action(curPlc, curRtt);
                                    bestAction.Value = -subAction.Value;
                                }
                                else if (sel(bestAction.Value, -subAction.Value) > 0)
                                {
                                    bestAction.SetAction(curPlc, curRtt);
                                    bestAction.Value = -subAction.Value;
                                }
                            }
                            curRtt.RollBack(currentState);

                            //if the board state remains the same after rotating clockwise, it will be the same after rotating counterclockwise
                            //so the node can be eliminated
                            if (!currentState.Sections[k].IsSameInBothDirection)
                            {
                                curRtt.Clockwise = false;
                                curRtt.Do(currentState);

                                if (depth == 1 || currentState.IsFull(Status.StateEnum.empty) ||
                                    currentState.HasConsecutiveNPiece(color, 5) ||
                                    currentState.HasConsecutiveNPiece(GetOppoColor(color), 5))
                                {
                                    int value = eva(currentState, color);
                                    if (bestAction == null)
                                    {
                                        bestAction       = new Action(curPlc, curRtt);
                                        bestAction.Value = value;
                                    }
                                    else if (sel(bestAction.Value, value) > 0)
                                    {
                                        bestAction.SetAction(curPlc, curRtt);
                                        bestAction.Value = value;
                                    }
                                }
                                else
                                {
                                    var subAction = Minimax(currentState, GetOppoColor(color), depth - 1, sel, eva);
                                    if (sel(bestAction.Value, -subAction.Value) > 0)
                                    {
                                        bestAction.SetAction(curPlc, curRtt);
                                        bestAction.Value = -subAction.Value;
                                    }
                                }
                                curRtt.RollBack(currentState);
                            }
                        }
                        curPlc.RollBack(currentState);
                    }
                }
            }
            return(bestAction);
        }
コード例 #2
0
        public static Action MinimaxLocal(PentagoBoard currentState, Status.StateEnum color, int depth, NodeSelecter sel, StateEvaluater eva)
        {
            Action    bestAction = null;
            Placement curPlc     = new Placement()
            {
                Player = color,
            };
            Rotation curRtt = new Rotation();

            var searchSpace = new bool[6, 6];

            if (currentState.IsEmpty(Status.StateEnum.empty))
            {
                for (int i = 0; i < currentState.TotalWidth; i++)
                {
                    for (int j = 0; j < currentState.TotalHeight; j++)
                    {
                        searchSpace[i, j] = true;
                    }
                }
            }
            else if (currentState.CountSteps(Status.StateEnum.empty) < 5)
            {
                for (int i = 0; i < currentState.TotalWidth; i++)
                {
                    for (int j = 0; j < currentState.TotalHeight; j++)
                    {
                        if (currentState[i, j].State == GetOppoColor(color))
                        {
                            for (int k = (i == 0) ? 0 : -1; k <= ((i == currentState.TotalWidth - 1) ? 0 : 1); k++)
                            {
                                for (int l = (j == 0) ? 0 : -1; l <= ((j == currentState.TotalHeight - 1) ? 0 : 1); l++)
                                {
                                    if (!(k == 0 && l == 0) && !searchSpace[i + k, j + l] && currentState[i + k, j + l].State == Status.StateEnum.empty)
                                    {
                                        searchSpace[i + k, j + l] = true;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                for (int i = 0; i < currentState.TotalWidth; i++)
                {
                    for (int j = 0; j < currentState.TotalHeight; j++)
                    {
                        if (currentState[i, j].State != Status.StateEnum.empty)
                        {
                            for (int k = (i == 0) ? 0 : -1; k <= ((i == currentState.TotalWidth - 1) ? 0 : 1); k++)
                            {
                                for (int l = (j == 0) ? 0 : -1; l <= ((j == currentState.TotalHeight - 1) ? 0 : 1); l++)
                                {
                                    if (!(k == 0 && l == 0) && !searchSpace[i + k, j + l] && currentState[i + k, j + l].State == Status.StateEnum.empty)
                                    {
                                        searchSpace[i + k, j + l] = true;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            var nospace = searchSpace.Cast <bool>().All(e => !e);

            for (int i = 0; i < currentState.TotalWidth; i++)
            {
                for (int j = 0; j < currentState.TotalHeight; j++)
                {
                    if (searchSpace[i, j])
                    {
                        //curPlc = new Placement();
                        curPlc.X = i;
                        curPlc.Y = j;
                        curPlc.Do(currentState);

                        for (int k = 0; k < currentState.Sections.Count; k++)
                        {
                            //curRtt = new Rotation();
                            curRtt.SectionNo = k;
                            curRtt.Clockwise = true;
                            curRtt.Do(currentState);

                            if (depth <= 1 || currentState.IsFull(Status.StateEnum.empty) ||
                                currentState.HasConsecutiveNPiece(color, 5) ||
                                currentState.HasConsecutiveNPiece(GetOppoColor(color), 5))
                            {
                                int value = eva(currentState, color);
                                if (bestAction == null)
                                {
                                    bestAction       = new Action(curPlc, curRtt);
                                    bestAction.Value = value;
                                }
                                else if (sel(bestAction.Value, value) > 0)
                                {
                                    bestAction.SetAction(curPlc, curRtt);
                                    bestAction.Value = value;
                                }
                            }
                            else
                            {
                                var subAction = Minimax(currentState, GetOppoColor(color), depth - 1, sel, eva);
                                if (bestAction == null)
                                {
                                    bestAction       = new Action(curPlc, curRtt);
                                    bestAction.Value = -subAction.Value;
                                }
                                else if (sel(bestAction.Value, -subAction.Value) > 0)
                                {
                                    bestAction.SetAction(curPlc, curRtt);
                                    bestAction.Value = -subAction.Value;
                                }
                            }
                            curRtt.RollBack(currentState);

                            //if the board state remains the same after rotating clockwise, it will be the same after rotating counterclockwise
                            //so the node can be eliminated
                            if (!currentState.Sections[k].IsSameInBothDirection)
                            {
                                curRtt.Clockwise = false;
                                curRtt.Do(currentState);

                                if (depth == 1 || currentState.IsFull(Status.StateEnum.empty) ||
                                    currentState.HasConsecutiveNPiece(color, 5) ||
                                    currentState.HasConsecutiveNPiece(GetOppoColor(color), 5))
                                {
                                    int value = eva(currentState, color);
                                    if (bestAction == null)
                                    {
                                        bestAction       = new Action(curPlc, curRtt);
                                        bestAction.Value = value;
                                    }
                                    else if (sel(bestAction.Value, value) > 0)
                                    {
                                        bestAction.SetAction(curPlc, curRtt);
                                        bestAction.Value = value;
                                    }
                                }
                                else
                                {
                                    var subAction = Minimax(currentState, GetOppoColor(color), depth - 1, sel, eva);
                                    if (sel(bestAction.Value, -subAction.Value) > 0)
                                    {
                                        bestAction.SetAction(curPlc, curRtt);
                                        bestAction.Value = -subAction.Value;
                                    }
                                }
                                curRtt.RollBack(currentState);
                            }
                        }
                        curPlc.RollBack(currentState);
                    }
                }
            }
            return(bestAction);
        }