Esempio n. 1
0
        public byte[] GetOptimalStep(byte[,] playField, HashSet <byte[]> CellsToCheck, int depth)
        {
            Dictionary <byte[], int> iscores = new Dictionary <byte[], int>();

            foreach (byte[] cell in CellsToCheck)
            {
                byte[,] b           = (byte[, ])playField.Clone();
                b[cell[0], cell[1]] = 1;
                int s = algorithm.Evaluate(b, cell, 1);
                iscores[cell] = s;
            }
            var items            = from i in iscores orderby i.Value descending select new { coordinates = i.Key, estimation = i.Value };
            var cellsToCheckList = items.Take(10).ToList();

            if (cellsToCheckList[0].estimation > 430000)
            {
                return(cellsToCheckList[0].coordinates);
            }
            Dictionary <byte[], int> scores = new Dictionary <byte[], int>();

            Parallel.ForEach(cellsToCheckList, cell =>
            {
                int score = algorithm.EvaluateCell((byte[, ])playField.Clone(), cell.coordinates, 1, (byte)depth);
                lock (scores)
                {
                    scores.Add(cell.coordinates, score);
                }
            });
            var item = (from entry in scores orderby entry.Value descending select entry).FirstOrDefault();

            return(item.Key);
        }
Esempio n. 2
0
        public IList <byte[, ]> Expand(byte[,] state)
        {
            IList <byte[, ]> ret = new List <byte[, ]>();
            int x = -1, y = -1;
            int lenghtX = state.GetLength(0);
            int lenghtY = state.GetLength(1);

            for (int i = 0; i < lenghtX; i++)
            {
                for (int j = 0; j < lenghtY; j++)
                {
                    if (state[i, j] == 0)
                    {
                        x = i;
                        y = j;
                    }
                }
            }

            if (x == -1 || y == -1)
            {
                throw new Exception();
            }

            if (x + 1 < lenghtX)
            {
                byte[,] subRet   = (byte[, ])state.Clone();
                subRet[x, y]     = subRet[x + 1, y];
                subRet[x + 1, y] = 0;
                ret.Add(subRet);
            }
            if (x - 1 >= 0)
            {
                byte[,] subRet   = (byte[, ])state.Clone();
                subRet[x, y]     = subRet[x - 1, y];
                subRet[x - 1, y] = 0;
                ret.Add(subRet);
            }
            if (y + 1 < lenghtY)
            {
                byte[,] subRet   = (byte[, ])state.Clone();
                subRet[x, y]     = subRet[x, y + 1];
                subRet[x, y + 1] = 0;
                ret.Add(subRet);
            }
            if (y - 1 >= 0)
            {
                byte[,] subRet   = (byte[, ])state.Clone();
                subRet[x, y]     = subRet[x, y - 1];
                subRet[x, y - 1] = 0;
                ret.Add(subRet);
            }

            return(ret);
        }
Esempio n. 3
0
        //----------------


        public IList <byte[, ]> Expand(byte[,] state)
        {
            int size     = state.GetLength(0);
            int distance = CheckDistance(state);

            byte[] findZero = find(0, state);                         //znajdz lokalizacje pustego miejsca (0)
            byte[,] newState = new byte[size, size];                  //kwadrat
            List <byte[, ]> ListOfNewStates = new List <byte[, ]>(4); //max. 4 mozliwosci
            byte            x;

            if (findZero[1] > 0)
            {
                newState = (byte[, ])state.Clone();
                x        = state[findZero[0], findZero[1] - 1]; //wartosc ktora zamieniamy z zerem

                newState[findZero[0], findZero[1] - 1] = 0;     // newstate[pierwsza koordynate zera, druga koordynata]
                newState[findZero[0], findZero[1]]     = x;
                ListOfNewStates.Add(newState);
            }
            if (findZero[0] > 0)
            {
                newState = (byte[, ])state.Clone();
                x        = state[findZero[0] - 1, findZero[1]]; //wartosc ktora zamieniamy z zerem

                newState[findZero[0] - 1, findZero[1]] = 0;
                newState[findZero[0], findZero[1]]     = x;
                ListOfNewStates.Add(newState);
            }
            if (findZero[0] < size - 1)
            {
                newState = (byte[, ])state.Clone();
                x        = state[findZero[0] + 1, findZero[1]]; //wartosc ktora zamieniamy z zerem

                newState[findZero[0] + 1, findZero[1]] = 0;
                newState[findZero[0], findZero[1]]     = x;
                ListOfNewStates.Add(newState);
            }
            if (findZero[1] < size - 1)
            {
                newState = (byte[, ])state.Clone();
                x        = state[findZero[0], findZero[1] + 1]; //wartosc ktora zamieniamy z zerem

                newState[findZero[0], findZero[1] + 1] = 0;
                newState[findZero[0], findZero[1]]     = x;
                ListOfNewStates.Add(newState);
            }
            return(ListOfNewStates);
        }
Esempio n. 4
0
        private byte[,] Skeleton(byte[,] originalBright, int border, byte brightness)
        {
            byte[,] erosenImg = (byte[, ])originalBright.Clone();
            byte[,] OCbright;
            byte[,] res = new byte[pictureBox1.Width, pictureBox1.Height];
            byte diff;
            int  flag = 1;

            while (flag != 0)
            {
                flag      = 0;
                erosenImg = EroseImage(erosenImg, border, 0);
                OCbright  = OpeningClosing(erosenImg, border);
                for (int x = border; x < pictureBox1.Width - border; x++)
                {
                    for (int y = border; y < pictureBox1.Height - border; y++)
                    {
                        diff = (byte)(erosenImg[x, y] - OCbright[x, y]);
                        if (diff == brightness)
                        {
                            flag++;
                        }
                        res[x, y] += diff;
                    }
                }
            }
            return(res);
        }
Esempio n. 5
0
    /// <summary>
    /// Clones the current Board.
    /// </summary>
    /// <returns>A copy of the current Board.</returns>
    public Board Clone()
    {
        Board cloned = (Board)this.MemberwiseClone();

        cloned.cells = (byte[, ])cells.Clone();
        return(cloned);
    }
Esempio n. 6
0
 public void InitializePathFindingVariables(byte[] rawMapData, int bytesPerRow, long cols, long rows)
 {
     processedFullSizeMapDataForPathFinding = new byte[cols * Terrain.MapCellSizeI, rows *Terrain.MapCellSizeI];
     Terrain.PopulatePathfindingGrid(rawMapData, bytesPerRow, cols, rows, processedFullSizeMapDataForPathFinding);
     processedFullSizeMapDataForExploration = processedFullSizeMapDataForPathFinding.Clone() as byte[, ];
     IdIslands(rawMapData, bytesPerRow, cols, rows);
 }
Esempio n. 7
0
        private void FrmRaw_Load(object sender, EventArgs e)
        {
            // 이미지 불러오기
            using (OpenFileDialog dialog = new OpenFileDialog())
            {
                dialog.InitialDirectory = @"C:\Temp\Pet_RAW";
                dialog.Filter           = "Raw Image|*.raw;";

                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    // 가로세로 계산
                    _width   = _height = (int)Math.Sqrt((double)(new FileInfo(dialog.FileName)).Length);
                    _inImage = new byte[_height, _width];

                    // 이미지를 읽어서 배열에 저장
                    using (BinaryReader br = new BinaryReader(new FileStream(dialog.FileName, FileMode.Open)))
                    {
                        for (int i = 0; i < _height; i++)
                        {
                            for (int k = 0; k < _width; k++)
                            {
                                _inImage[k, i] = br.ReadByte();
                            }
                        }
                    }

                    // 화면에 출력
                    _outImage = (byte[, ])_inImage.Clone();
                    Display(_width, _height);
                }
            }
        }
Esempio n. 8
0
        static byte[,] evolve(byte[,] data)
        {
            int w = data.GetLength(0), h = data.GetLength(1);

            byte[,] field = (byte[, ])data.Clone();

            byte friendly_neighborhood = 0;

            for (int i = 0; i < w; i++)
            {
                for (int j = 0; j < h; j++)
                {
                    friendly_neighborhood = (byte)(data[next(i - 1, w), next(j - 1, h)] + data[i, next(j - 1, h)] + data[next(i + 1, w), next(j - 1, h)] + data[next(i - 1, w), j] + data[next(i + 1, w), j] + data[next(i - 1, w), next(j + 1, h)] + data[i, next(j + 1, h)] + data[next(i + 1, w), next(j + 1, h)]);

                    if (data[i, j] == 1)
                    {
                        field[i, j] = (byte)((friendly_neighborhood == 2 || friendly_neighborhood == 3) ? 1 : 0);
                    }
                    else
                    {
                        field[i, j] = (byte)((friendly_neighborhood == 3) ? 1 : 0);
                    }
                }
            }

            return(field);
        }
Esempio n. 9
0
        public List lineList;        //list of lines

        public Coloumn(int inpWidth, int inpHeight, byte[,] input)
        {
            //
            // TODO: Add constructor logic here
            //
            this.lineList = new List();
            this.height   = inpHeight;
            this.width    = inpWidth;

            //array = new byte[height, width];
            this.array = (byte[, ])input.Clone();

            colImage = new Bitmap(width, height);

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (this.array[y, x] == 0)
                    {
                        colImage.SetPixel(x, y, System.Drawing.Color.Black);
                    }
                    else
                    {
                        colImage.SetPixel(x, y, System.Drawing.Color.Red);
                    }
                } //for
            }     //for
        }         //cunstructor
Esempio n. 10
0
        public static Tuple <int, int> GetMaxScoreMove(byte[,] board, byte tile)
        {
            // A much more naive version of AI compared to GetAIMove or MinimaxAlphaBeta.
            // This function just selects the move with highest score.
            // This is the "easy" AI mode.
            List <Tuple <int, int> > validMoves = GetValidMoves(board, tile);

            if (validMoves.Count > 0)
            {
                int bestScore             = int.MinValue;
                Tuple <int, int> bestMove = validMoves[0];
                foreach (Tuple <int, int> move in validMoves)
                {
                    byte[,] childBoard = board.Clone() as byte[, ];
                    MakeMove(childBoard, move, tile);
                    int nodeScore = GetScore(board, tile) * rng.Next(-5, 5);
                    if (nodeScore > bestScore)
                    {
                        bestScore = nodeScore;
                        bestMove  = move;
                    }
                }
                return(bestMove);
            }
            return(null);
        }
        public static byte[,] dilation(byte[,] slika)
        {
            int w = slika.GetLength(1);
            int h = slika.GetLength(0);

            byte[,] retVal = (byte[, ])slika.Clone();
            int[] ii = { 0, 1, 1, 1, 0, -1, -1, -1 };
            int[] jj = { 1, 1, 0, -1, -1, -1, 0, 1 };
            int   n  = ii.Length;

            for (int y = 1; y < h - 1; y++)
            {
                for (int x = 1; x < w - 1; x++)
                {
                    Boolean b = false;
                    for (int t = 0; t < n; t++)
                    {
                        if (slika[y + ii[t], x + jj[t]] == 0) // BAR JEDNA CRNA TACKA
                        {
                            b = true;
                            break;
                        }
                    }
                    if (b == true)
                    {
                        retVal[y, x] = 0;
                    }
                    else
                    {
                        retVal[y, x] = 255;
                    }
                }
            }
            return(retVal);
        }
Esempio n. 12
0
        public void initialize(int inpHeight, int inpWidth, int inpBaseLine, byte [,] input)
        {
            this.height   = inpHeight;
            this.width    = inpWidth;
            this.baseLine = inpBaseLine;

            this.ligatureLsit = new List();
            this.D_templates  = new List();
            this.diacritics   = new List();

            array = (byte[, ])input.Clone();

            lineImage = new Bitmap(this.width, this.height);

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (this.array[y, x] == 0)
                    {
                        lineImage.SetPixel(x, y, System.Drawing.Color.Black);
                    }
                    else
                    {
                        lineImage.SetPixel(x, y, System.Drawing.Color.Red);
                    }
                }        //for
            }            //for
        }
Esempio n. 13
0
        /// <summary>
        /// Clone the glyph.
        /// </summary>
        ///
        /// <returns>Returns clone of the glyph.</returns>
        ///
        /// <remarks><para><note>It is user's responsibility to clone <see cref="UserData"/> property if it is
        /// set to reference type object.</note></para></remarks>
        ///
        public object Clone( )
        {
            Glyph clone = new Glyph(name, (byte[, ])data.Clone( ));

            clone.userData = userData;

            return(clone);
        }
Esempio n. 14
0
        public void ComparesArraysCorrectly()
        {
            byte[,] array1 = { { 1, 2 }, { 2, 3 }, { 4, 5 } };
            byte[,] array2 = array1.Clone() as byte[, ];
            bool equal = ByteExtension.AreEqual(array1, array2);

            Assert.IsTrue(equal);
        }
Esempio n. 15
0
        public void finalizeAssemblerFuncSharp(byte[,] resultArray)
        {
            this.preBitmap  = curBitmap;
            this.pixelArray = (byte[, ])resultArray.Clone();
            Bitmap bmp = createBitmapFromPixelArray(this.pixelArray, this.bitmapInfo.SizeX, this.bitmapInfo.SizeY);

            this.curBitmap = convertTo24bpp(bmp);
        }
Esempio n. 16
0
        /// <summary>
        /// Метод возвращает сгенерированную конфигурацию
        /// </summary>
        /// <returns></returns>
        public byte[,] gen()
        {
            if (trigger0)
            {
                return((byte[, ])Cells.Clone());
            }

            return(null);
        }
Esempio n. 17
0
        public byte[,] Solve(byte[,] input, int[][] xClues, int[][] yClues) //0=white, 1=black
        {
            int xDimension = input.GetLength(0);
            int yDimension = input.GetLength(1);

            if (xClues.Length != xDimension)
            {
                throw new ArgumentException("Wrong number of X clues");
            }
            if (yClues.Length != yDimension)
            {
                throw new ArgumentException("Wrong number of Y clues");
            }

            //Generate possibilities
            List <List <byte[]> > xPossibilities = Possibilities(xClues, yDimension);
            List <List <byte[]> > yPossibilities = Possibilities(yClues, xDimension);

            var output = (byte[, ])input.Clone();

            for (int i = 0; i < xDimension; i++)
            {
                for (int j = 0; j < yDimension; j++)
                {
                    if (output[i, j] == 0)
                    {
                        output[i, j] = 2;                    //2 = unknown
                    }
                }
            }
            bool[] xSolved = new bool[xDimension];
            bool[] ySolved = new bool[yDimension];

            //Loop
            while (xSolved.Contains(false) || ySolved.Contains(false))
            {
                //For each column
                for (int i = 0; i < xDimension; i++)
                {
                    var column = GetColumn(output, i);
                    (var result, bool solved) = Prune(column, xPossibilities[i]);
                    xSolved[i] = solved;
                    InsertColumn(output, result, i);
                }

                //For each row
                for (int j = 0; j < yDimension; j++)
                {
                    var row = GetRow(output, j);
                    (var result, bool solved) = Prune(row, yPossibilities[j]);
                    ySolved[j] = solved;
                    InsertRow(output, result, j);
                }
            }

            return(output);
        }
Esempio n. 18
0
 //*******************************CLASS METHODS*************************************/
 //create a shape class using byte array passed in as arguments (also finds rotations)
 public Shape(byte[,] map, System.Drawing.Color c1, System.Drawing.Color c2)
 {
     rotations = new List <byte[, ]>();
     rotations.Add((byte[, ])map.Clone());
     findAllRotations();
     MaxHeight = map.GetLength(0) > map.GetLength(1) ? map.GetLength(0) : map.GetLength(1);
     this.c1   = c1;
     this.c2   = c2;
 }
Esempio n. 19
0
        public static byte[,] Copy(byte[,] board)
        {
            if (board == null)
            {
                throw new ArgumentNullException(nameof(board));
            }

            byte[,] n = board.Clone() as byte[, ];
            return(n);
        }
Esempio n. 20
0
        /// <summary>
        /// Загрузка формы
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            step = new CA_Step(CellAutomaton.CellularAutomaton);


            glControl1.Size = new Size(n * (squareDim + 1), hScrollBar1.Location.Y - glControl1.Location.Y);   //617 is magic number | n * (squareDim + 1)
            cameraChanged();

            //Фон
            // panel1.BackColor = Color.Black;

            //Заполняем матрицу
            CellAutomaton.FillMatrix(Cells);
            memarr = (byte[, ])Cells.Clone();

            //Генерация поколений выключена
            GenerationTimer.Enabled = false;

            //Конвеевская жизнь по умолчанию. S/B 23/3
            rulesChListBox.SetItemChecked(2, true);
            rulesChListBox.SetItemChecked(3, true);
            rulesChListBox.SetItemChecked(12, true);

            //Правила
            GetArrayOfRules();

            ToolStrip_timebtn.Text = DELAY + GenerationTimer.Interval;

            cellC = Color.FromArgb(0, 255, 0); //Зеленый цвет
            backC = Color.Black;

            hScrollBar1.Width  = glControl1.Width;
            vScrollBar1.Height = glControl1.Height;
            ScrollBarsInitialize();

            thorChB.Checked = true;

            toolStripLabel_steps.Text = "Число шагов: " + 0;
            toolStripLabel_X.Text     = "X: " + 0;
            toolStripLabel_Y.Text     = "Y: " + 0;

            FullSize();
        }
        public StructureTemplate(byte[,] map, string id)
        {
            Id = id;
            if (map is null)
            {
                throw new ArgumentNullException(nameof(map));
            }

            StructureMap = (byte[, ])map.Clone();
        }
        /// <summary>
        /// Create a new wall grid out of a 2d array of 0s and 1s.
        /// </summary>
        /// <param name="walls">Must contain 0s corresponding to floors and 1s corresponding to walls.</param>
        /// <param name="position">Location in world coordinates of coordinate (0,0) in the walls array. Mainly used to ensure
        /// chunks line up if breaking a grid into multiple pieces.</param>
        public WallGrid(byte[,] walls, Vector3 position, int scale = 1)
        {
            ValidateWalls(walls);

            Position   = position;
            Scale      = scale;
            Length     = walls.GetLength(0);
            Width      = walls.GetLength(1);
            this.walls = (byte[, ])walls.Clone();
        }
Esempio n. 23
0
        public ImageData Clone()
        {
            ImageData cb = new ImageData();

            cb.A = (byte[, ])_alpha.Clone();
            cb.B = (byte[, ])_blue.Clone();
            cb.G = (byte[, ])_green.Clone();
            cb.R = (byte[, ])_red.Clone();
            return(cb);
        }
Esempio n. 24
0
            /// <summary>
            /// Instanciate a new key.
            /// </summary>
            /// <param name="isPrivate">Defines whether or not this key is private.</param>
            /// <param name="fragments">Matrix containing the fragments of the key.</param>
            /// <param name="size">Size of the key.</param>
            public Key(bool isPrivate, byte[,] fragments, int size = 4)
            {
                if (fragments.GetLength(0) + fragments.GetLength(1) != size)
                {
                    throw new ArgumentException("Given array does not match the given size.", "fragments");
                }

                this.IsPrivate = isPrivate;
                this.Version   = (Version)size;
                this.Fragments = fragments.Clone() as byte[, ];
            }
Esempio n. 25
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DoubleArrayChromosome"/> class.
 /// </summary>
 ///
 /// <param name="chromosomeGenerator">Chromosome generator - random number generator, which is
 /// used to initialize chromosome's genes, which is done by calling <see cref="Generate"/> method
 /// or in class constructor.</param>
 /// <param name="mutationMultiplierGenerator">Mutation multiplier generator - random number
 /// generator, which is used to generate random multiplier values, which are used to
 /// multiply chromosome's genes during mutation.</param>
 /// <param name="mutationAdditionGenerator">Mutation addition generator - random number
 /// generator, which is used to generate random addition values, which are used to
 /// add to chromosome's genes during mutation.</param>
 /// <param name="values">Values used to initialize the chromosome.</param>
 ///
 /// <remarks><para>The constructor initializes the new chromosome with specified <paramref name="values">values</paramref>.
 /// </para></remarks>
 ///
 /// <exception cref="ArgumentOutOfRangeException">Invalid length of values array.</exception>
 ///
 public MusicChromosome(byte[,] values, int tracks, int length)
 {
     // save parameters
     this.chromosomeGenerator         = new AForge.Math.Random.StandardGenerator( );
     this.mutationMultiplierGenerator = new AForge.Math.Random.StandardGenerator();
     this.mutationAdditionGenerator   = new AForge.Math.Random.StandardGenerator();
     this.length = length;
     this.tracks = tracks;
     // copy specified values
     val = (byte[, ])values.Clone();
 }
Esempio n. 26
0
        public static Tuple <int, int> GetAIMove(byte[,] board, int depth, byte tile)
        {
            // The "convienence" function that allows us to use our AI algorithm.
            List <Tuple <int, int> > validMoves = GetValidMoves(board, tile);

            validMoves = validMoves.OrderBy(a => rng.Next(-10, 10)).ToList();
            if (validMoves.Count > 0)
            {
                int bestScore;
                if (tile == Black)
                {
                    bestScore = int.MinValue;
                }
                else if (tile == White)
                {
                    bestScore = int.MaxValue;
                }
                else
                {
                    return(null);
                }
                Tuple <int, int> bestMove = validMoves[0];
                if (GetScore(board, Black) + GetScore(board, White) > 55)
                {
                    depth = 100;
                }
                foreach (Tuple <int, int> move in validMoves)
                {
                    byte[,] childBoard = board.Clone() as byte[, ];
                    MakeMove(childBoard, move, tile);
                    int nodeScore;
                    if (tile == Black)
                    {
                        nodeScore = MinimaxAlphaBeta(childBoard, depth - 1, int.MinValue, int.MaxValue, OtherTile(tile), false);
                        if (nodeScore > bestScore)
                        {
                            bestScore = nodeScore;
                            bestMove  = move;
                        }
                    }
                    else
                    {
                        nodeScore = MinimaxAlphaBeta(childBoard, depth - 1, int.MinValue, int.MaxValue, OtherTile(tile), true);
                        if (nodeScore < bestScore)
                        {
                            bestScore = nodeScore;
                            bestMove  = move;
                        }
                    }
                }
                return(bestMove);
            }
            return(null);
        }
Esempio n. 27
0
 public static byte[,] MergeFields(byte[,] TargetField, byte[,] Merger)
 {
     byte[,] NewVoxels = (byte[, ])TargetField.Clone();
     for (int i = 0; i < TargetField.GetLength(0) && i < Merger.GetLength(0); i++)
     {
         for (int j = 0; j < TargetField.GetLength(1) && j < Merger.GetLength(1); j++)
         {
             NewVoxels[i, j] = Merger[i, j];
         }
     }
     return(NewVoxels);
 }
Esempio n. 28
0
    // Use this for initialization
    void Start()
    {
        //Setup Texture
        m_Texture            = new Texture2D(m_Widht, m_Height);
        m_Texture.name       = "GameOfLifeTexture";
        m_Texture.filterMode = FilterMode.Point;

        m_Old    = new byte[m_Widht, m_Height];
        m_Update = (byte[, ])m_Old.Clone();

        GenerateRandomGrid();
    }
Esempio n. 29
0
        public DuyetDiemAnhChu(byte[,] arr, Bitmap bitmap)
        {
            this.bitmap = bitmap;
            var phanNguong = new HandleThreshold(128);

            phanNguong.ConvertImage(arr);
            this.Arr = arr.Clone() as byte[, ];
            arrr     = arr;

            ChieuAnhSangTayPhai();
            TimToaDoHinhChieu();
        }
Esempio n. 30
0
        public static int MinimaxAlphaBeta(byte[,] board, int depth, int a, int b, byte tile, bool isMaxPlayer)
        {
            // The heart of our AI. Minimax algorithm with alpha-beta pruning to speed up computation.
            // Higher search depths = greater difficulty.
            if (depth == 0 || GetWinner(board) != Empty)
            {
                return(Evaluation(board));
            }
            int bestScore;

            if (isMaxPlayer)
            {
                bestScore = int.MinValue;
            }
            else
            {
                bestScore = int.MaxValue;
            }
            List <Tuple <int, int> > validMoves = GetValidMoves(board, tile);

            if (validMoves.Count > 0)
            {
                foreach (Tuple <int, int> move in validMoves)
                {
                    byte[,] childBoard = board.Clone() as byte[, ];
                    MakeMove(childBoard, move, tile);
                    int nodeScore = MinimaxAlphaBeta(childBoard, depth - 1, a, b, OtherTile(tile), !isMaxPlayer);
                    if (isMaxPlayer)
                    {
                        bestScore = Math.Max(bestScore, nodeScore);
                        a         = Math.Max(bestScore, a);
                    }
                    else
                    {
                        bestScore = Math.Min(bestScore, nodeScore);
                        b         = Math.Min(bestScore, b);
                    }
                    if (b <= a)
                    {
                        break;
                    }
                }
            }
            else
            {
                return(MinimaxAlphaBeta(board, depth, a, b, OtherTile(tile), !isMaxPlayer));
            }
            return(bestScore);
        }