Esempio n. 1
0
        private int EvaluateBoard(Board board)
        {
            DiscColor color         = this.Player.Color;
            DiscColor oppositeColor = DiscColor.GetOpposite(this.Player.Color);

            List <int[]> oppositePlayerPossibleMoves = this.GetPossibleMoves(board, oppositeColor);
            List <int[]> possibleMoves = this.GetPossibleMoves(board, color);

            if ((possibleMoves.Count == 0) && (oppositePlayerPossibleMoves.Count == 0))
            {
                int result = board.GetDiscsCount(color) - board.GetDiscsCount(oppositeColor);
                int addend = (int)Math.Pow(board.Size, 4) + (int)Math.Pow(board.Size, 3); // because it is a terminal state, its weight must be bigger than the heuristic ones
                if (result < 0)
                {
                    addend = -addend;
                }
                return(result + addend);
            }
            else
            {
                int mobility = this.GetPossibleConvertions(board, color, possibleMoves)
                               - this.GetPossibleConvertions(board, oppositeColor, oppositePlayerPossibleMoves);
                int stability = (this.GetStableDiscsCount(board, color) - this.GetStableDiscsCount(board, oppositeColor)) * board.Size * 2 / 3;

                return(mobility + stability);
            }
        }
Esempio n. 2
0
        //функция оценки доски
        private int EvaluateBoard(Board board)
        {
            DiscColor color         = this.Player.Color;
            DiscColor oppositeColor = DiscColor.GetOpposite(this.Player.Color);
            //списки предположительных ходов игроков
            List <int[]> oppositePlayerPossibleMoves = this.GetPossibleMoves(board, oppositeColor);
            List <int[]> possibleMoves = this.GetPossibleMoves(board, color);

            if ((possibleMoves.Count == 0) && (oppositePlayerPossibleMoves.Count == 0))       //если списки пусты
            {
                int result = board.GetDiscsCount(color) - board.GetDiscsCount(oppositeColor); //от количества фишек ии отнимает количество фишек противника
                int addend = (int)Math.Pow(board.Size, 4) + (int)Math.Pow(board.Size, 3);     // потому что это конечное состояние, его вес должен быть больше эвристического
                if (result < 0)                                                               //если разность меньше 0
                {
                    addend = -addend;
                }
                return(result + addend);
            }
            else//если ходы есть
            {
                //количество фишек противника, которые могут быть преобразованы
                int mobility = this.GetPossibleConvertions(board, color, possibleMoves)
                               - this.GetPossibleConvertions(board, oppositeColor, oppositePlayerPossibleMoves);
                //число стабильных фишек на доске игрока
                int stability = (this.GetStableDiscsCount(board, color) - this.GetStableDiscsCount(board, oppositeColor)) * board.Size * 2 / 3;

                return(mobility + stability);
            }
        }
Esempio n. 3
0
        private void InvertDirection(
            int rowIndex, int columnIndex,
            int rowIndexChange, int columnIndexChange,
            DiscColor color,
            ref int invertedDiscsCount)
        {
            DiscColor opositeColor = DiscColor.GetOpposite(color);

            rowIndex    += rowIndexChange;
            columnIndex += columnIndexChange;
            while (this[rowIndex, columnIndex] == opositeColor)
            {
                this.mFieldColors[rowIndex, columnIndex] = color;
                invertedDiscsCount++;

                rowIndex    += rowIndexChange;
                columnIndex += columnIndexChange;
            }
        }
Esempio n. 4
0
        // kiem tra xem co danh dc khong
        private bool CheckDirection(int rowIndex, int columnIndex, int rowIndexChange, int columnIndexChange, DiscColor color)
        {
            bool areOpositeColorDiscsFound = false;

            rowIndex    += rowIndexChange;
            columnIndex += columnIndexChange;
            while ((rowIndex >= 0) && (rowIndex < this.Size) && (columnIndex >= 0) && (columnIndex < this.Size))
            {
                if (areOpositeColorDiscsFound)
                {
                    if (this[rowIndex, columnIndex] == color)
                    {
                        return(true);
                    }
                    else if (this[rowIndex, columnIndex] == DiscColor.None)
                    {
                        return(false);
                    }
                }
                else
                {
                    DiscColor opositeColor = DiscColor.GetOpposite(color);
                    if (this[rowIndex, columnIndex] == opositeColor)
                    {
                        areOpositeColorDiscsFound = true;
                    }
                    else
                    {
                        return(false);
                    }
                }

                rowIndex    += rowIndexChange;
                columnIndex += columnIndexChange;
            }

            return(false);
        }
Esempio n. 5
0
        //проверка направлени¤
        private bool CheckDirection(int rowIndex, int columnIndex, int rowIndexChange, int columnIndexChange, DiscColor color)
        {
            bool areOpositeColorDiscsFound = false;//поверка найден ли противоположный цвет
            rowIndex += rowIndexChange;
            columnIndex += columnIndexChange;
            while ((rowIndex >= 0) && (rowIndex < this.Size) && (columnIndex >= 0) && (columnIndex < this.Size))
            {
                if (areOpositeColorDiscsFound)//если найдена клетка с противоположным цветом
                {
                    if (this[rowIndex, columnIndex] == color)
                    {
                        return true;
                    }
                    else if (this[rowIndex, columnIndex] == DiscColor.None)
                    {
                        return false;
                    }
                }
                else
                {
                    DiscColor opositeColor = DiscColor.GetOpposite(color);
                    if (this[rowIndex, columnIndex] == opositeColor)
                    {
                        areOpositeColorDiscsFound = true;
                    }
                    else
                    {
                        return false;
                    }
                }

                rowIndex += rowIndexChange;
                columnIndex += columnIndexChange;
            }

            return false;
        }
Esempio n. 6
0
        private int GetNextMove(Board board, bool isMaximizing, int currentDepth, int alpha, int beta, out int resultRowIndex, out int resultColumnIndex)
        {
            resultRowIndex    = 0;
            resultColumnIndex = 0;

            DiscColor    color           = isMaximizing ? this.Player.Color : DiscColor.GetOpposite(this.Player.Color);
            bool         playerSkipsMove = false;
            List <int[]> possibleMoves   = new List <int[]>();

            bool isFinalMove = (currentDepth >= this.MaxDepth) || this.Player.Game.IsStopped || this.Player.Game.IsPaused;

            if (!isFinalMove)
            {
                possibleMoves = this.GetPossibleMoves(board, color);
                if (possibleMoves.Count == 0)
                {
                    playerSkipsMove = true;
                    possibleMoves   = this.GetPossibleMoves(board, DiscColor.GetOpposite(color));
                }

                isFinalMove = (possibleMoves.Count == 0);
            }

            if (isFinalMove)
            {
                resultRowIndex    = -1;
                resultColumnIndex = -1;
                return(this.EvaluateBoard(board));
            }
            else
            {
                int bestBoardValue      = isMaximizing ? MIN_BOARD_VALUE : MAX_BOARD_VALUE;
                int bestMoveRowIndex    = -1;
                int bestMoveColumnIndex = -1;

                foreach (int[] nextMove in possibleMoves)
                {
                    int rowIndex    = nextMove[0];
                    int columnIndex = nextMove[1];

                    Board nextBoard = (Board)board.Clone();
                    nextBoard.SetFieldColor(rowIndex, columnIndex, color);

                    bool nextIsMaximizing = playerSkipsMove ? isMaximizing : !isMaximizing;

                    int dummyIndex; // values of resultRowIndex and resultColumnIndex are not needed in recursive function calls
                    int currentBoardValue = this.GetNextMove(nextBoard, nextIsMaximizing, currentDepth + 1, alpha, beta, out dummyIndex, out dummyIndex);
                    if (isMaximizing)
                    {
                        if (currentBoardValue > bestBoardValue)
                        {
                            bestBoardValue      = currentBoardValue;
                            bestMoveRowIndex    = rowIndex;
                            bestMoveColumnIndex = columnIndex;

                            if (bestBoardValue > alpha)
                            {
                                alpha = bestBoardValue;
                            }

                            if (bestBoardValue >= beta)
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        if (currentBoardValue < bestBoardValue)
                        {
                            bestBoardValue      = currentBoardValue;
                            bestMoveRowIndex    = rowIndex;
                            bestMoveColumnIndex = columnIndex;

                            if (bestBoardValue < beta)
                            {
                                beta = bestBoardValue;
                            }

                            if (bestBoardValue <= alpha)
                            {
                                break;
                            }
                        }
                    }
                }

                resultRowIndex    = bestMoveRowIndex;
                resultColumnIndex = bestMoveColumnIndex;
                return(bestBoardValue);
            }
        }
Esempio n. 7
0
        //процедура для осуществления следующего хода. алгоритм АВ-отсечения. ищет лучший ход. возвращает BestBoardValue в виде числа (вероятности)
        private int GetNextMove(Board board, bool isMaximizing, int currentDepth, int alpha, int beta, out int resultRowIndex, out int resultColumnIndex)
        {
            resultRowIndex    = 0;
            resultColumnIndex = 0;
            //цвет фишки
            DiscColor    color           = isMaximizing ? this.Player.Color : DiscColor.GetOpposite(this.Player.Color);//если true DiskColor = Player.Color иначе противоположный цвет
            bool         playerSkipsMove = false;
            List <int[]> possibleMoves   = new List <int[]>();
            //проверка на последний ход
            bool isFinalMove = (currentDepth >= this.MaxDepth) || this.Player.Game.IsStopped || this.Player.Game.IsPaused;

            //если ход не последний
            if (!isFinalMove)
            {                                 //получение возможных ходов.
                possibleMoves = this.GetPossibleMoves(board, color);
                if (possibleMoves.Count == 0) //если нет возможных ходов
                {
                    playerSkipsMove = true;
                    possibleMoves   = this.GetPossibleMoves(board, DiscColor.GetOpposite(color));//получить список возможных ходов для противоположного игрока
                }

                isFinalMove = (possibleMoves.Count == 0); //проверка на последний ход (если список пуст вернет true)
            }
            //если используем на самом "дне" глубины подсчета
            if (isFinalMove)
            {
                resultRowIndex    = -1;
                resultColumnIndex = -1;
                return(this.EvaluateBoard(board));//возвращает оценочную эвристическую функцию (mobility+stability)
            }
            else//если макс. глубине не достигнута
            {                                                                               //поиск наилучшего хода (просмотр дерева)
                int bestBoardValue      = isMaximizing ? MIN_BOARD_VALUE : MAX_BOARD_VALUE; //в начале bestBoardValue присваивается + или - бесконечность
                int bestMoveRowIndex    = -1;                                               //инициализация координат лучшего хода
                int bestMoveColumnIndex = -1;

                foreach (int[] nextMove in possibleMoves)
                {
                    int rowIndex    = nextMove[0];
                    int columnIndex = nextMove[1];

                    Board nextBoard = (Board)board.Clone();                //копия доски
                    nextBoard.SetFieldColor(rowIndex, columnIndex, color); //установка фишек на доску

                    bool nextIsMaximizing = playerSkipsMove ? isMaximizing : !isMaximizing;

                    int dummyIndex; // значения resultRowIndex и resultColumnIndex не нуждаются в рекурсивном вызове функции
                    //рекурсивный вызов

                    int currentBoardValue = this.GetNextMove(nextBoard, nextIsMaximizing, currentDepth + 1, alpha, beta, out dummyIndex, out dummyIndex);
                    if (isMaximizing)
                    {
                        if (currentBoardValue > bestBoardValue)
                        {
                            bestBoardValue      = currentBoardValue;
                            bestMoveRowIndex    = rowIndex;
                            bestMoveColumnIndex = columnIndex;
                            //Найти оценку текущей ситуации, в предположении, что она находится между alpha и beta.
                            if (bestBoardValue > alpha)
                            {
                                alpha = bestBoardValue;
                            }

                            if (bestBoardValue >= beta)
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        if (currentBoardValue < bestBoardValue)
                        {
                            bestBoardValue      = currentBoardValue;
                            bestMoveRowIndex    = rowIndex;
                            bestMoveColumnIndex = columnIndex;

                            if (bestBoardValue < beta)

                            {
                                beta = bestBoardValue;
                            }

                            if (bestBoardValue <= alpha)
                            {
                                break;
                            }
                        }
                    }
                }

                resultRowIndex    = bestMoveRowIndex;
                resultColumnIndex = bestMoveColumnIndex;
                return(bestBoardValue);
            }
        }