/// <summary> /// Show ArgumentNullException and ArgumentException messages using Log4Net. /// </summary> public static void ShowExceptions() { BasicConfigurator.Configure(); try { int size = 3; int[,] matrix = new int[size, size]; int currentValue = 1; Cell cell = new Cell(0, 0); Direction direction = PossibleDirections.GetInitialDirection(); currentValue = MatrixTraversal.FillMatrix(matrix, currentValue, cell, direction); cell = MatrixTraversal.FindEmptyCell(matrix); currentValue++; direction = PossibleDirections.GetInitialDirection(); MatrixTraversal.FillMatrix(matrix, currentValue, cell, direction); } catch (ArgumentNullException ane) { exceptionError.Error( "This message is thrown by method Log4Net.ShowExceptions() \r\n" + ane.Message); } catch (ArgumentException ae) { exceptionError.Error( "This message is thrown by method Log4Net.ShowExceptions() \r\n" + ae.Message); } }
/// <summary> /// Traverse a matrix using console for input/output /// </summary> /// <remarks>Use Log4Net to show the exeption messages. /// The method Log4Net.ShowExceptions is designed to cause /// ArgumentNullException for demonstration</remarks> public static void Main() { BasicConfigurator.Configure(); try { int size = ConsoleIO.ReadInput(); int[,] matrix = new int[size, size]; int currentValue = 1; Cell cell = new Cell(0, 0); Direction direction = PossibleDirections.GetInitialDirection(); currentValue = MatrixTraversal.FillMatrix(matrix, currentValue, cell, direction); cell = MatrixTraversal.FindEmptyCell(matrix); if (currentValue < size * size) { currentValue++; direction = PossibleDirections.GetInitialDirection(); MatrixTraversal.FillMatrix(matrix, currentValue, cell, direction); } ConsoleIO.PrintMatrix(matrix); } catch (ArgumentNullException ane) { exceptionError.Error(ane.Message, ane); } catch (ArgumentException ae) { exceptionError.Error(ae.Message, ae); } // Designed to couse ArgumentNullException for demonstration // This method throws the ERROR messages on the console Log4Net.ShowExceptions(); }
/// <summary> /// Fill matrix with numbers /// operation /// </summary> /// <param name="matrix">2D array</param> /// <param name="startingCell">first empty cell</param> private static void FillMatrix(int[,] matrix, Cell startingCell) { var cell = startingCell; var index = 0; while (IsCellUsable(matrix, cell)) { matrix[cell.X, cell.Y] = cell.Value; while (!IsNextCellUsable(matrix, cell, index) && HasAvailableMove(matrix, cell, index)) { index = (index + 1) % DirectionX.Length; } cell.X += DirectionX[index]; cell.Y += DirectionY[index]; cell.Value++; } // Calls FillMatrix recursively with next empty cell if exists var nextCell = FindEmptyCell(matrix); if (nextCell != null) { nextCell.Value = cell.Value; FillMatrix(matrix, nextCell); } }
/// <summary> /// Assign cells in a matrix /// </summary> /// <param name="matrix">Matrix, which cells are going to be assigned</param> /// <param name="currentValue">Initial value to assign the first unassigned cell</param> /// <param name="cell">Initial cell from which start the assigning</param> /// <param name="direction">Initial direction to traverse the matrix</param> /// <exception cref="ArgumentNullException"> /// If there is not initialized input parameter</exception> /// <exception cref="ArgumentException"> /// If we try to assign a cell with non-positive value</exception> /// <returns>Value of last assigned cell</returns> public static int FillMatrix(int[,] matrix, int currentValue, Cell cell, Direction direction) { if (matrix == null || cell == null || direction == null) { throw new ArgumentNullException( "Invalid input! You cannot fill matrix using empty (null) parameter."); } if (currentValue < 1) { throw new ArgumentException( "Invalid input! You cannot fill matrix with non-positive number."); } matrix[cell.Row, cell.Column] = currentValue; while (IsPath(matrix, cell)) { direction = FindDirection(matrix, cell, direction); cell.Row += direction.X; cell.Column += direction.Y; currentValue++; matrix[cell.Row, cell.Column] = currentValue; } return currentValue; }
public void TestFillMatrixNegativeValue() { int[,] matrix = new int[3, 3]; int currentValue = -1; Cell cell = new Cell(0, 0); Direction direction = PossibleDirections.GetInitialDirection(); MatrixTraversal.FillMatrix(matrix, currentValue, cell, direction); }
/// <summary> /// Search for first empty cell in /// 2D array /// </summary> /// <param name="matrix">2D array</param> /// <returns>null if empty Cell does not exist, /// or new Cell</returns> private static Cell FindEmptyCell(int[,] matrix) { for (int row = 0; row <= matrix.GetUpperBound(0); row++) { for (int col = 0; col <= matrix.GetUpperBound(1); col++) { if (matrix[row, col] == 0) { var emptyCell = new Cell(row, col); return emptyCell; } } } return null; }
public void TestFillMatrixHalf() { int[,] matrix = new int[5, 5]; int currentValue = 1; Cell cell = new Cell(0, 0); Direction direction = PossibleDirections.GetInitialDirection(); MatrixTraversal.FillMatrix(matrix, currentValue, cell, direction); int[,] result = { {1,13,14,15,16}, {12,2,21,22,17}, {11,0,3,20,18}, {10,0,0,4,19}, {9,8,7,6,5} }; Assert.AreEqual(result[2, 3], matrix[2, 3]); Assert.AreEqual(result[0, 4], matrix[0, 4]); Assert.AreEqual(result[2, 1], matrix[2, 1]); Assert.AreEqual(result[3, 1], matrix[3, 1]); Assert.AreEqual(result[3, 2], matrix[3, 2]); }
public void TestFillMatrix() { int[,] matrix = new int[3, 3]; int currentValue = 1; Cell cell = new Cell(0, 0); Direction direction = PossibleDirections.GetInitialDirection(); MatrixTraversal.FillMatrix(matrix, currentValue, cell, direction); int[,] result = { {1,7,8}, {6,2,9}, {5,4,3}, }; Assert.AreEqual(result[0, 0], matrix[0, 0]); Assert.AreEqual(result[0, 1], matrix[0, 1]); Assert.AreEqual(result[0, 2], matrix[0, 2]); Assert.AreEqual(result[1, 0], matrix[1, 0]); Assert.AreEqual(result[1, 1], matrix[1, 1]); Assert.AreEqual(result[1, 2], matrix[1, 2]); Assert.AreEqual(result[2, 0], matrix[2, 0]); Assert.AreEqual(result[2, 1], matrix[2, 1]); Assert.AreEqual(result[2, 2], matrix[2, 2]); }
/// <summary> /// Search for unassigned cell /// </summary> /// <param name="matrix">Matrix, where the cell is searched</param> /// <exception cref="ArgumentNullException"> /// If we try to search in matrix, which is not initialized</exception> /// <returns>The first unassigned cell or null if thre is no such</returns> public static Cell FindEmptyCell(int[,] matrix) { if (matrix == null) { throw new ArgumentNullException( "Invalid input! You cannot search in empty matrix."); } Cell cell = new Cell(0, 0); for (int row = 0; row < matrix.GetLength(0); row++) { for (int column = 0; column < matrix.GetLength(0); column++) { if (matrix[row, column] == 0) { cell.Row = row; cell.Column = column; return cell; } } } return null; }
/// <summary> /// Check if next cell is usable /// </summary> /// <param name="matrix">2D array</param> /// <param name="cell">struct Cell</param> /// <param name="index">index of pattern array</param> /// <returns>boolean value</returns> private static bool IsNextCellUsable(int[,] matrix, Cell cell, int index) { var nextCell = new Cell() { X = cell.X + DirectionX[index], Y = cell.Y + DirectionY[index] }; return IsCellUsable(matrix, nextCell); }
/// <summary> /// Check if cell is usable, if it is inside /// the matrix and if its equale to zero /// </summary> /// <param name="matrix">2D array</param> /// <param name="cell">struct Cell </param> /// <returns>boolean value</returns> private static bool IsCellUsable(int[,] matrix, Cell cell) { bool isCellUsable = cell.X >= 0 && cell.X < matrix.GetLength(0) && cell.Y >= 0 && cell.Y < matrix.GetLength(1) && matrix[cell.X, cell.Y] == 0; return isCellUsable; }
public void TestValidCell() { Cell cell = new Cell(3, 3); Assert.AreEqual(3, cell.Row); Assert.AreEqual(3, cell.Column); }
public void TestCellNegativeRow() { Cell cell = new Cell(-3, 1); }
/// <summary> /// Find next possible direction to continue the traversal of a matrix /// </summary> /// <param name="matrix">Matrix to be traversed</param> /// <param name="cell">Cell from which is searching direction</param> /// <param name="direction">Current direction which could be changed</param> /// <returns>Next direction to traverse the matrix</returns> private static Direction FindDirection(int[,] matrix, Cell cell, Direction direction) { int size = matrix.GetLength(0); bool isOuterRow = cell.Row + direction.X >= size || cell.Row + direction.X < 0; bool isOuterColumn = cell.Column + direction.Y >= size || cell.Column + direction.Y < 0; while (isOuterRow || isOuterColumn || matrix[cell.Row + direction.X, cell.Column + direction.Y] != 0) { direction = PossibleDirections.GetNextPossibleDirection(direction); isOuterRow = cell.Row + direction.X >= size || cell.Row + direction.X < 0; isOuterColumn = cell.Column + direction.Y >= size || cell.Column + direction.Y < 0; } return direction; }
/// <summary> /// Change all directions which are leading outside the matrix /// </summary> /// <param name="possibleDirections">Current possible directions</param> /// <param name="matrix">Matrix to be traversed</param> /// <param name="cell">Cell from which is searching direction</param> private static void UpdatePossibleDirections(Direction[] possibleDirections, int[,] matrix, Cell cell) { for (int count = 0; count < possibleDirections.Length; count++) { int changedRow = cell.Row + possibleDirections[count].X; if (changedRow >= matrix.GetLength(0) || changedRow < 0) { possibleDirections[count].X = 0; } int changedColumn = cell.Column + possibleDirections[count].Y; if (changedColumn >= matrix.GetLength(0) || changedColumn < 0) { possibleDirections[count].Y = 0; } } }
/// <summary> /// Find if there is unassigned cell around current cell /// </summary> /// <param name="matrix">Matrix, where the cell is searched</param> /// <param name="cell">Cell around which is searching</param> /// <returns>Is or is not such cell</returns> private static bool IsPath(int[,] matrix, Cell cell) { var isPath = false; Direction[] possibleDirections = PossibleDirections.Generate(); UpdatePossibleDirections(possibleDirections, matrix, cell); for (int count = 0; count < possibleDirections.Length; count++) { int changedRow = cell.Row + possibleDirections[count].X; int changedColumn = cell.Column + possibleDirections[count].Y; if (matrix[changedRow, changedColumn] == 0) { isPath = true; } } return isPath; }
/// <summary> /// Check if there is avaliable /// move, (empty cell) /// </summary> /// <param name="matrix">2D array</param> /// <param name="cell">struct Cell</param> /// <param name="index">index of pattern array</param> /// <returns>boolean value</returns> private static bool HasAvailableMove(int[,] matrix, Cell cell, int index) { foreach (var element in DirectionX) { index = (index + 1) % DirectionX.Length; if (IsNextCellUsable(matrix, cell, index)) { return true; } } return false; }
public void TestCellNegativeColumn() { Cell cell = new Cell(3, -1); }
public void TestCellZero() { Cell cell = new Cell(0, 0); Assert.AreEqual(0, cell.Row); Assert.AreEqual(0, cell.Column); }