public static bool CanGoToPosition(this int[,] matrix, Position position) { bool isRowInRange = 0 <= position.Row && position.Row < matrix.GetLength(0); bool isColInRange = 0 <= position.Col && position.Col < matrix.GetLength(1); return isRowInRange && isColInRange && matrix[position.Row, position.Col] == 0; }
public static bool AreNeighbourCellsFilled(this int[,] matrix, Position position) { int upRow; int downRow; int leftCol; int rightCol; if (position.Row > 0) { upRow = position.Row - 1; } else { upRow = position.Row; } if (position.Row < matrix.GetLength(0) - 1) { downRow = position.Row + 1; } else { downRow = position.Row; } if (position.Col < matrix.GetLength(1) - 1) { rightCol = position.Col + 1; } else { rightCol = position.Col; } if (position.Col > 0) { leftCol = position.Col - 1; } else { leftCol = position.Col; } for (int i = upRow; i <= downRow; i++) { for (int j = leftCol; j <= rightCol; j++) { if (matrix[i, j] == 0) { return false; } } } return true; }
public bool CanWalkToPosition(Position position) { for (int i = 0; i < steps.Length; i++) { if (this.CheckIfPositionIsValid(position.Row + steps[i].Vertical, position.Column + steps[i].Horizontal)) { return true; } } return false; }
public static void RotateWalkInMatrix(int[,] matrix) { Position currentPosition = StartPosition; int currentDirection = 0; for (int step = 1; step <= matrix.GetLength(0) * matrix.GetLength(1); step++) { matrix[currentPosition.Y, currentPosition.X] = step; Position? newPosition = null; int newDirection = currentDirection; // Check all 8 directions for (int i = 0; i < Directions.Length; i++, newDirection++) { if (newDirection == Directions.Length) { newDirection = 0; } int nextYPos = currentPosition.Y + Directions[newDirection].Y; int nextXPos = currentPosition.X + Directions[newDirection].X; bool canMoveTo = nextYPos >= 0 && nextYPos < matrix.GetLength(0) && nextXPos >= 0 && nextXPos < matrix.GetLength(1) && matrix[nextYPos, nextXPos] == 0; if (canMoveTo) { newPosition = new Position(nextYPos, nextXPos); currentDirection = newDirection; break; } } if (!newPosition.HasValue) { var mostTopLeftEmptyCell = FindMostTopLeftEmptyCell(matrix); if (mostTopLeftEmptyCell.HasValue) { currentPosition = mostTopLeftEmptyCell.Value; currentDirection = 0; } } else { currentPosition = newPosition.Value; } } }
public void FillMatrix() { Position position = this.matrix.FindFirstEmptyCell(); Direction direction = Direction.DownRight; int rowMove = RotatingWalkUtils.ChangeByRow[(int)direction]; int colMove = RotatingWalkUtils.ChangeByColumn[(int)direction]; int cellValue = 1; while (cellValue <= this.Rows * this.Cols) { this.matrix[position.Row, position.Col] = cellValue; Position nextPosition = new Position(position.Row + rowMove, position.Col + colMove); if (!this.matrix.CanGoToPosition(nextPosition)) { bool areNeighbourCellsFilled = false; if (this.matrix.AreNeighbourCellsFilled(position)) { areNeighbourCellsFilled = true; position = this.matrix.FindFirstEmptyCell(); if (position == null) { break; } direction = Direction.DownRight; } else { Position newPosition = new Position(position.Row, position.Col); direction = this.matrix.FindNewPosition(direction, newPosition); } rowMove = RotatingWalkUtils.ChangeByRow[(int)direction]; colMove = RotatingWalkUtils.ChangeByColumn[(int)direction]; if (areNeighbourCellsFilled) { cellValue += 1; continue; } } position.Row += rowMove; position.Col += colMove; cellValue += 1; } }
public bool FindAvailablePosition(out Position position) { position = new Position(0, 0); for (int row = 0; row < this.matrix.GetLength(0); row++) { for (int column = 0; column < this.matrix.GetLength(1); column++) { if (this.matrix[row, column] == 0) { position.Row = row; position.Column = column; return true; } } } return false; }
public static int[,] FillMatrix(int n) { int[,] matrix = new int[n, n]; Position position = new Position(0, 0); int value = 1, currentDirectionX = 1, currentDirectionY = 1; while (value <= n * n) { matrix[position.Row, position.Col] = value; if (!IsFreeCellExists(matrix, position.Row, position.Col)) { value++; if (value > n * n) { break; } FindEmptyCellCoordinates(matrix, position); matrix[position.Row, position.Col] = value; currentDirectionX = 1; currentDirectionY = 1; } while (IsPositionOutOfMatrix(n, position.Row, currentDirectionX) || IsPositionOutOfMatrix(n, position.Col, currentDirectionY) || matrix[position.Row + currentDirectionX, position.Col + currentDirectionY] != 0) { ChangeDirection(ref currentDirectionX, ref currentDirectionY); } position.Update(currentDirectionX, currentDirectionY); value++; } return matrix; }
public static Direction FindNewPosition(this int[,] matrix, Direction direction, Position position) { for (int i = 0; i < DirectionCount; i++) { Direction currDirection = (Direction)(((int)direction + i) % DirectionCount); int currRow = position.Row + ChangeByRow[(int)currDirection]; int currCol = position.Col + ChangeByColumn[(int)currDirection]; Position newPosition = new Position(currRow, currCol); if (CanGoToPosition(matrix, newPosition)) { return currDirection; } } throw new InvalidOperationException("Matrix is already filled."); }
public void RotatingWalk() { this.Clear(); int count = 1; Position position = new Position(0, 0); Walk walk = new Walk(Directions.SE); while (true) { this.matrix[position.Row, position.Column] = count; if (!this.CanWalkToPosition(position)) { bool positionAvailable = this.FindAvailablePosition(out position); if (positionAvailable) { count++; this.matrix[position.Row, position.Column] = count; walk.Direction = Directions.SE; } else { break; } } while (!this.CheckIfPositionIsValid(position.Row + walk.Vertical, position.Column + walk.Horizontal)) { walk.ChangeDirection(); } position.UpdatePosition(walk); count++; } }
private static void FindEmptyCellCoordinates(int[,] matrix, Position position) { position.Row = 0; position.Col = 0; for (int row = 0; row < matrix.GetLength(0); row++) { for (int col = 0; col < matrix.GetLength(1); col++) { // if the cell is free if (matrix[row, col] == 0) { position.Row = row; position.Col = col; return; } } } }