public Matrix(int size, int[,] matrix = null)
        {
            if (size <= 0)
            {
                throw new ArgumentOutOfRangeException(
                    "size", "Size should be a positive number");
            }

            this.size = size;
            if (matrix == null)
            {
                this.data = new int[size, size];
            }
            else
            {
                bool isMatrixEmpty = matrix.GetLength(0) == 0 ||
                    matrix.GetLength(1) == 0;
                if (isMatrixEmpty)
                {
                    throw new ArgumentException("Matrix is empty", "data");
                }

                this.data = matrix;
            }

            this.step = size;
            this.currentNumber = 1;
            this.previousCell = new Cell(0, 0);
            this.nextCell = new Cell(1, 1);
        }
        private static void FillMatrix(int[,] matrix, Cell startCell)
        {
            var currentCell = startCell;
            int direction = (int)Directions.DownRight;

            while (IsCellAvailable(matrix, currentCell))
            {
                matrix[currentCell.X, currentCell.Y] = currentCell.CellValue;

                while (!IsNextCellAvailable(matrix, currentCell, direction) &&
                       HasPossibleWalk(matrix, currentCell, direction))
                {
                    direction = (direction + 1) % DirectionsCount;
                }

                currentCell.X += DirX[direction];
                currentCell.Y += DirY[direction];
                currentCell.CellValue++;
            }

            var nextStartCell = FindFirstEmptyCell(matrix);
            if (nextStartCell != null)
            {
                nextStartCell.CellValue = currentCell.CellValue;
                FillMatrix(matrix, nextStartCell);
            }
        }
        public void TestNotEqualOperator()
        {
            Cell a = new Cell(4, 5);
            Cell b = new Cell(4, 6);

            Assert.IsTrue(a != b);
        }
        public void TestAdditionOperator()
        {
            Cell a = new Cell(4, 5);
            Cell b = new Cell(4, 6);
            Cell result = a + b;

            Assert.AreEqual(new Cell(8, 11), result);
        }
        public void TestCellConstructor()
        {
            int x = 2;
            int y = 3;
            Cell cell = new Cell(x, y);

            Assert.AreEqual(x, cell.X);
            Assert.AreEqual(y, cell.Y);
        }
示例#6
0
        private void FillMatrix()
        {
            var currentCell = new Cell(0, 0);
            var currentCellValue = 1;

            while (currentCell != null)
            {
                this.Field[currentCell.X, currentCell.Y] = currentCellValue;
                currentCell = this.Move(currentCell) ?? this.FindFirstEmptyCell();

                currentCellValue++;
            }
        }
示例#7
0
        private void FillMatrix()
        {
            var currentCell = new Cell(0, 0);
            var currentCellValue = 1;

            while (currentCell != null)
            {
                this.Field[currentCell.Row, currentCell.Col] = currentCellValue;
                currentCell = this.GetNextCell(currentCell) ?? this.FindFirstPossibleCell();

                currentCellValue++;
            }
        }
示例#8
0
        private Cell Move(Cell cell)
        {
            for (int i = this.currentTargetCellIndex; i < this.targetCells.Length + this.currentTargetCellIndex; i++)
            {
                Cell nextCell = cell + this.targetCells[i % this.targetCells.Length];
                if (this.IsValidDestination(nextCell))
                {
                    this.currentTargetCellIndex = i % this.targetCells.Length;
                    return nextCell;
                }
            }

            return null;
        }
        private static bool HasPossibleWalk(int[,] matrix, Cell currentCell, int direction)
        {
            for (int i = 0; i < DirectionsCount; i++)
            {
                direction = (direction + 1) % DirectionsCount;

                if (IsNextCellAvailable(matrix, currentCell, direction))
                {
                    return true;
                }
            }

            return false;
        }
示例#10
0
        private Cell GetNextCell(Cell cell)
        {
            for (int ind = this.cellIndex; ind < this.target.Length + this.cellIndex; ind++)
            {
                Cell nextCell = cell + this.target[ind % this.target.Length];
                if (this.IsValidDestination(nextCell))
                {
                    this.cellIndex = ind % this.target.Length;
                    return nextCell;
                }
            }

            return null;
        }
        private static Cell FindFirstEmptyCell(int[,] matrix)
        {
            for (int row = 0; row < matrix.GetLength(0); row++)
            {
                for (int col = 0; col < matrix.GetLength(1); col++)
                {
                    if (matrix[row, col] == 0)
                    {
                        Cell firstEmptyCell = new Cell(row, col);
                        return firstEmptyCell;
                    }
                }
            }

            return null;
        }
示例#12
0
        private void FillMatrix()
        {
            var currentCell = new Cell(0, 0);
            var currentCellValue = 1;

            while (currentCellValue <= this.size * this.size)
            {
                this.Field[currentCell.X, currentCell.Y] = currentCellValue;
                currentCell = this.Move(currentCell) ?? this.MoveToFirstEmptyCell();

                //if (currentCell == null)
                //{
                //    currentCell = this.FindFirstEmptyCell();
                //}

                currentCellValue++;
            }
        }
示例#13
0
        private Cell FindFirstEmptyCell()
        {
            Cell result = new Cell(0, 0);

            for (int row = 0; row < this.Field.GetLength(0); row++)
            {
                for (int column = 0; column < this.Field.GetLength(0); column++)
                {
                    if (this.Field[row, column] == 0)
                    {
                        this.currentTargetCellIndex = 0;
                        result.X = row;
                        result.Y = column;
                        return result;
                    }
                }
            }

            return null;
        }
示例#14
0
        private Cell FindFirstPossibleCell()
        {
            Cell possibleCell = new Cell(0, 0);

            for (int row = 0; row < this.Field.GetLength(0); row++)
            {
                for (int col = 0; col < this.Field.GetLength(0); col++)
                {
                    if (this.Field[row, col] == 0)
                    {
                        this.cellIndex = 0;
                        possibleCell.Row = row;
                        possibleCell.Col = col;
                        return possibleCell;
                    }
                }
            }

            return null;
        }
示例#15
0
        private Cell FindFirstEmptyCell()
        {
            Cell result = new Cell(0, 0);

            for (int i = 0; i < this.Field.GetLength(0); i++)
            {
                for (int j = 0; j < this.Field.GetLength(0); j++)
                {
                    if (this.Field[i, j] == 0)
                    {
                        this.currentTargetCellIndex = 0;
                        result.X = i;
                        result.Y = j;
                        return result;
                    }
                }
            }

            return null;
        }
示例#16
0
        private bool AreAddedCellsInRange(Cell previousCell, Cell nextCell)
        {
            Cell result = previousCell + nextCell;
            bool isCellOutOfRange = result.X >= size || result.X < 0 ||
                result.Y >= size || result.Y < 0;

            return isCellOutOfRange || data[result.X, result.Y] != 0;
        }
示例#17
0
        bool AreThereFreeNeighbours(Cell cell)
        {
            Cell[] directions = new Cell[]
            {
                new Cell(1, 1),
                new Cell(1, 0),
                new Cell(1, -1),
                new Cell(0, -1),
                new Cell(-1, -1),
                new Cell(-1, 0),
                new Cell(-1, 1),
                new Cell(0, 1)
            };

            for (int i = 0; i < DIRECTION_COUNT; i++)
            {
                directions[i] = CalculateCellCoordinates(cell, directions[i]);
                bool isCellFree = this.data[cell.X + directions[i].X,
                    cell.Y + directions[i].Y] == 0;

                if (isCellFree)
                {
                    return true;
                }
            }

            return false;
        }
        private static bool IsNextCellAvailable(int[,] matrix, Cell currentCell, int direction)
        {
            var nextX = currentCell.X + DirX[direction];
            var nextY = currentCell.Y + DirY[direction];
            var nextCell = new Cell(nextX, nextY);

            return IsCellAvailable(matrix, nextCell);
        }
示例#19
0
 private bool IsValidDestination(Cell cellToCheck)
 {
     return cellToCheck.X >= 0 && cellToCheck.X < this.Field.GetLength(0) && cellToCheck.Y >= 0
            && cellToCheck.Y < this.Field.GetLength(0) && this.Field[cellToCheck.X, cellToCheck.Y] == 0;
 }
示例#20
0
        private Cell CalculateCellCoordinates(Cell cell, Cell direction)
        {
            Cell result = cell + direction;
            bool isXOutOfRange = result.X >= this.data.GetLength(0) ||
                result.X < 0;
            if (isXOutOfRange)
            {
                direction.X = 0;
            }

            bool isYOutOfRange = result.Y >= this.data.GetLength(0) ||
                result.Y < 0;
            if (isYOutOfRange)
            {
                direction.Y = 0;
            }

            return direction;
        }
示例#21
0
        public void WalkInMatrix()
        {
            PerformLongestWalk();
            this.previousCell = FindNextFreeCell();

            if (this.previousCell != new Cell(0, 0))
            {
                this.currentNumber++;
                this.nextCell = new Cell(1, 1);
                PerformLongestWalk();
            }
        }
示例#22
0
 private bool IsValidDestination(Cell cell)
 {
     return cell.X >= 0 && cell.X < this.size &&
            cell.Y >= 0 && cell.Y < this.size &&
            this.Field[cell.X, cell.Y] == 0;
 }
示例#23
0
        Cell FindNextFreeCell()
        {
            Cell cell = new Cell(0, 0);

            for (int i = 0; i < this.data.GetLength(0); i++)
            {
                for (int j = 0; j < this.data.GetLength(0); j++)
                {
                    if (this.data[i, j] == 0)
                    {
                        return new Cell(i, j);
                    }
                }
            }

            return cell;
        }
示例#24
0
        private Cell MoveToFirstEmptyCell()
        {
            Cell result = new Cell(0, 0);

            for (int i = 0; i < this.size; i++)
            {
                for (int j = 0; j < this.size; j++)
                {
                    if (this.Field[i, j] == 0)
                    {
                        currentDirectionIndex = 0;
                        result.X = i;
                        result.Y = j;
                        return result;
                    }
                }
            }

            return null;
        }
示例#25
0
        private bool IsValidDestination(Cell cell)
        {
            var isValidRow = cell.Row >= 0 && cell.Row < this.Field.GetLength(0);
            var isValidCol = cell.Col >= 0 && cell.Col < this.Field.GetLength(1);
            var isValidDestination = isValidCol && isValidRow;

            if (isValidDestination)
            {
                isValidDestination = this.Field[cell.Row, cell.Col] == 0;
            }

            return isValidDestination;
        }
示例#26
0
        private void PerformLongestWalk()
        {
            while (true)
            {
                data[previousCell.X, previousCell.Y] = currentNumber;

                if (!AreThereFreeNeighbours(previousCell))
                {
                    break;
                }

                if (AreAddedCellsInRange(previousCell, nextCell))
                {
                    while (AreAddedCellsInRange(previousCell, nextCell))
                    {
                        MoveCellInDirection(ref nextCell);
                    }
                }

                previousCell += nextCell;
                currentNumber++;
            }
        }
 public void TestEmptyCellConstructor()
 {
     Cell cell = new Cell();
     Assert.AreEqual(0, cell.X);
     Assert.AreEqual(0, cell.Y);
 }
示例#28
0
        private Cell Move(Cell cell)
        {
            for (int i = this.currentDirectionIndex; i < this.currentDirectionIndex + numberOfDirections; i++)
            {
                var nextCell = cell + this.directions[i % numberOfDirections];
                if (this.IsValidDestination(nextCell))
                {
                    this.currentDirectionIndex = i % numberOfDirections;
                    return nextCell;
                }
            }

            return null;
        }
        private static bool IsCellAvailable(int[,] matrix, Cell currentCell)
        {
            bool isCellAvailable = currentCell.X >= 0 && currentCell.X < matrix.GetLength(0) &&
                                   currentCell.Y >= 0 && currentCell.Y < matrix.GetLength(1) &&
                                   matrix[currentCell.X, currentCell.Y] == 0;

            return isCellAvailable;
        }
示例#30
0
        static void MoveCellInDirection(ref Cell cell)
        {
            Cell[] directions = new Cell[]
            {
                new Cell(1, 1),
                new Cell(1, 0),
                new Cell(1, -1),
                new Cell(0, -1),
                new Cell(-1, -1),
                new Cell(-1, 0),
                new Cell(-1, 1),
                new Cell(0, 1)
            };

            int cellCount = 0;

            for (int i = 0; i < DIRECTION_COUNT; i++)
            {
                if (directions[i].X == cell.X && directions[i].Y == cell.Y)
                {
                    cellCount = i;
                    break;
                }
            }

            if (cellCount == 7)
            {
                cell = directions[0];
                return;
            }

            cell = directions[cellCount + 1];
        }