// the method removes tiles with zero value and shift remainig in the selected row to the left
        private void ShiftTiles(QuantumTile[] row)
        {
            var temp = 0;

            while (temp != row.Length)
            {
                if (row[temp].TileSet.Count == 0)
                {
                    for (var j = temp; j < row.Length; j++)
                    {
                        if (row[j].TileSet.Count != 0)
                        {
                            row[temp] = row[j];
                            row[j]    = new QuantumTile();
                            break;
                        }
                    }
                    temp++;
                }
                else
                {
                    temp++;
                }
            }
        }
        private QuantumTile[][] Initialize()
        {
            var board = new QuantumTile[_rowLength][];

            for (var i = 0; i < _rowLength; i++)
            {
                board[i] = new[] { new QuantumTile(), new QuantumTile(), new QuantumTile(), new QuantumTile() };
            }
            return(board);
        }
        // transpose board and then rotate it 90 degrees counter clock-wise
        private void TransposeAndRotateBoard(QuantumTile[][] board)
        {
            var length = board[0].Length;
            var retVal = new QuantumTile[length][];

            for (var x = 0; x < length; x++)
            {
                retVal[x] = board.Select(p => p[x]).ToArray();
                Array.Reverse(retVal[x]);
            }
            CopyToBoard(retVal);
        }
        // return tile as a result of two adjacent tiles
        private QuantumTile GetMatchOfTiles(QuantumTile tile1, QuantumTile tile2)
        {
            var matchedTile = new QuantumTile();

            var tileArray = tile1.TileSet.ToArray();

            foreach (var t in tileArray)
            {
                if (tile2.TileSet.Contains(t))
                {
                    matchedTile.TileSet.Add(2 * t);
                    Score += 2 * t;
                }
            }
            return(matchedTile);
        }
        // the method moves selected row to the letf and returns resultant merged row
        private QuantumTile[] MoveRow(QuantumTile[] row)
        {
            ShiftTiles(row);

            var subResults        = new QuantumTile[3][];
            var matched           = false;
            var countOfSubResults = 0;

            for (var i = 0; i < 3; i++)
            {
                subResults[i] = new[] { new QuantumTile(), new QuantumTile(), new QuantumTile() };
            }

            var temp = GetMatchOfTiles(row[0], row[1]);

            if (temp.TileSet.Count != 0)
            {
                matched = true;
                subResults[countOfSubResults][0] = temp;
                subResults[countOfSubResults][1] = row[2];
                subResults[countOfSubResults][2] = row[3];
            }

            temp = GetMatchOfTiles(row[1], row[2]);
            if (temp.TileSet.Count != 0)
            {
                matched = true;
                countOfSubResults++;
                subResults[countOfSubResults][0] = row[0];
                subResults[countOfSubResults][1] = temp;
                subResults[countOfSubResults][2] = row[3];
            }

            temp = GetMatchOfTiles(row[2], row[3]);
            if (temp.TileSet.Count != 0)
            {
                matched = true;
                countOfSubResults++;
                subResults[countOfSubResults][0] = row[0];
                subResults[countOfSubResults][1] = row[1];
                subResults[countOfSubResults][2] = temp;
            }
            return(matched == false ? row : MergeRowResults(subResults));
        }