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 (!CheckIfFreeCellExists(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 (CheckIfPositionAfterChangeIsOutOfMatrix(n, position.Row, currentDirectionX) ||
                        CheckIfPositionAfterChangeIsOutOfMatrix(n, position.Col, currentDirectionY) ||
                         matrix[position.Row + currentDirectionX, position.Col + currentDirectionY] != 0)
                {
                    ChangeDirection(ref currentDirectionX, ref currentDirectionY);
                }

                position.Update(currentDirectionX, currentDirectionY);
                value++;
            }

            return matrix;
        }
        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;
                    }
                }
            }
        }