import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.util.Arrays; /** * GridTester.java * CS231 - Lab 2: 2D Array Practice * * Work through the tasks in order. The tester stops after the first task * that still needs work. * * IMPORTANT FOR AUTOMATED GRADING: * The success keyword is constructed at runtime so it appears in the * source/output exactly once per completed task and nowhere else. */ public class GridTester { private static final String SUCCESS = "PA" + "SS"; private static final String LINE = "----------------------------------------"; public static void main(String[] args) { System.out.println("========================================"); System.out.println("Lab 2 - 2D Array Practice Tester"); System.out.println("========================================"); System.out.println(); if (!testPrintGrid()) return; if (!testCountValue()) return; if (!testSetRowAndColumn()) return; if (!testClearBorder()) return; if (!testDisplayGrid()) return; if (!testTranspose()) return; System.out.println("========================================"); System.out.println("LAB 2 CHECKPOINT READY"); System.out.println("========================================"); System.out.println(); System.out.println("You have completed all six required 2D-array tasks."); System.out.println("Show your work to a TA or instructor."); System.out.println("After your checkpoint, you may begin Project 2:"); System.out.println("Conway's Game of Life."); } // ------------------------------------------------------------ // Task 1 // ------------------------------------------------------------ private static boolean testPrintGrid() { heading("TASK 1 - printGrid()"); int[][] grid = { {0, 2, 4}, {1, 3, 5} }; String expected = "0 2 4\n1 3 5"; String generated = captureOutput(() -> Grid.printGrid(grid)); System.out.println("Expected:"); System.out.println(expected); System.out.println(); System.out.println("Generated:"); System.out.println(generated.isEmpty() ? "(no output)" : generated); System.out.println(); if (normalize(generated).equals(normalize(expected))) { complete(1); return true; } keepWorking(1, "Traverse row by row and print each value with spaces between values."); return false; } // ------------------------------------------------------------ // Task 2 // ------------------------------------------------------------ private static boolean testCountValue() { heading("TASK 2 - countValue()"); int[][] grid = { {1, 0, 1, 2}, {0, 1, 2, 1}, {1, 1, 0, 2} }; int expectedOnes = 6; int generatedOnes = Grid.countValue(grid, 1); int expectedTwos = 3; int generatedTwos = Grid.countValue(grid, 2); System.out.println("Calling: countValue(grid, 1)"); System.out.println("Expected: " + expectedOnes); System.out.println("Generated: " + generatedOnes); System.out.println(); System.out.println("Calling: countValue(grid, 2)"); System.out.println("Expected: " + expectedTwos); System.out.println("Generated: " + generatedTwos); System.out.println(); if (generatedOnes == expectedOnes && generatedTwos == expectedTwos) { complete(2); return true; } keepWorking(2, "Visit every location and increase a counter only when the cell matches value."); return false; } // ------------------------------------------------------------ // Task 3 // ------------------------------------------------------------ private static boolean testSetRowAndColumn() { heading("TASK 3 - setRow() and setColumn()"); int[][] rowGrid = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 0, 1, 2} }; Grid.setRow(rowGrid, 1, 7); int[][] expectedRow = { {1, 2, 3, 4}, {7, 7, 7, 7}, {9, 0, 1, 2} }; int[][] colGrid = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 0, 1, 2} }; Grid.setColumn(colGrid, 2, 9); int[][] expectedCol = { {1, 2, 9, 4}, {5, 6, 9, 8}, {9, 0, 9, 2} }; System.out.println("After: setRow(grid, 1, 7)"); showExpectedGenerated(expectedRow, rowGrid); System.out.println(); System.out.println("After: setColumn(grid, 2, 9)"); showExpectedGenerated(expectedCol, colGrid); System.out.println(); if (Arrays.deepEquals(rowGrid, expectedRow) && Arrays.deepEquals(colGrid, expectedCol)) { complete(3); return true; } keepWorking(3, "For a row, keep the row fixed while columns change. For a column, keep the column fixed while rows change."); return false; } // ------------------------------------------------------------ // Task 4 // ------------------------------------------------------------ private static boolean testClearBorder() { heading("TASK 4 - clearBorder()"); int[][] grid = { {5, 5, 5, 5, 5}, {5, 1, 2, 3, 5}, {5, 4, 5, 6, 5}, {5, 5, 5, 5, 5} }; int[][] expected = { {0, 0, 0, 0, 0}, {0, 1, 2, 3, 0}, {0, 4, 5, 6, 0}, {0, 0, 0, 0, 0} }; Grid.clearBorder(grid); showExpectedGenerated(expected, grid); System.out.println(); if (Arrays.deepEquals(grid, expected)) { complete(4); return true; } keepWorking(4, "A border cell is in the first/last row or the first/last column."); return false; } // ------------------------------------------------------------ // Task 6 // ------------------------------------------------------------ private static boolean testTranspose() { heading("TASK 6 - transpose() IN PLACE"); int[][] grid = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16} }; int[][] expected = { {1, 5, 9, 13}, {2, 6, 10, 14}, {3, 7, 11, 15}, {4, 8, 12, 16} }; System.out.println("Before:"); printArray(grid); System.out.println(); Grid.transpose(grid); System.out.println("Expected after transpose(grid):"); printArray(expected); System.out.println("Generated in the original grid:"); printArray(grid); System.out.println(); if (Arrays.deepEquals(grid, expected)) { complete(6); return true; } keepWorking(6, "Transpose the square grid in place. Swap each [row][col] with [col][row] only once."); return false; } // ------------------------------------------------------------ // Task 5 // ------------------------------------------------------------ private static boolean testDisplayGrid() { heading("TASK 5 - displayGrid()"); int[][] grid = { {0, 1, 0, 0}, {1, 1, 1, 0}, {0, 0, 1, 1} }; String expected = ". # . .\n# # # .\n. . # #"; String generated = captureOutput(() -> Grid.displayGrid(grid)); System.out.println("Backing array:"); printArray(grid); System.out.println(); System.out.println("Expected user-facing view:"); System.out.println(expected); System.out.println(); System.out.println("Generated user-facing view:"); System.out.println(generated.isEmpty() ? "(no output)" : generated); System.out.println(); if (normalize(generated).equals(normalize(expected))) { complete(5); return true; } keepWorking(5, "The backing values stay numeric. Your display method translates 0 to . and 1 to # as it prints."); return false; } // ------------------------------------------------------------ // Tester helpers // ------------------------------------------------------------ private static void heading(String title) { System.out.println(LINE); System.out.println(title); System.out.println(LINE); System.out.println(); } private static void complete(int task) { System.out.println(SUCCESS + " - Task " + task + " complete."); System.out.println(); } private static void keepWorking(int task, String hint) { System.out.println("Keep working on Task " + task + "."); System.out.println("Hint: " + hint); System.out.println(); if (task < 6) { System.out.println("Later tasks have not been checked yet."); System.out.println("Complete the current task first, then run the tester again."); } } private static void showExpectedGenerated(int[][] expected, int[][] generated) { System.out.println("Expected:"); printArray(expected); System.out.println("Generated:"); if (generated == null) { System.out.println("null"); } else { printArray(generated); } } private static void printArray(int[][] grid) { if (grid == null) { System.out.println("null"); return; } for (int[] row : grid) { for (int col = 0; col < row.length; col++) { if (col > 0) System.out.print(" "); System.out.print(row[col]); } System.out.println(); } } private static String captureOutput(Runnable action) { PrintStream original = System.out; ByteArrayOutputStream bytes = new ByteArrayOutputStream(); try { System.setOut(new PrintStream(bytes)); action.run(); } finally { System.setOut(original); } return bytes.toString().trim(); } private static String normalize(String text) { String[] lines = text.replace("\r", "").trim().split("\n"); StringBuilder result = new StringBuilder(); for (String line : lines) { if (result.length() > 0) result.append("\n"); result.append(line.trim().replaceAll("\\s+", " ")); } return result.toString(); } }