From 387b137dabfe1d2979c6f93fc6361675b6f25a66 Mon Sep 17 00:00:00 2001 From: emancilla77 Date: Mon, 27 Oct 2025 15:24:13 -0400 Subject: [PATCH] Added stub methods in LightsOutGame.java --- LightsOutGame.java | 217 +++++++++++++++++++++++++++++++++-- build/jar/ConsoleGameHub.jar | Bin 0 -> 21236 bytes 2 files changed, 207 insertions(+), 10 deletions(-) create mode 100644 build/jar/ConsoleGameHub.jar diff --git a/LightsOutGame.java b/LightsOutGame.java index a1935da..410163f 100644 --- a/LightsOutGame.java +++ b/LightsOutGame.java @@ -1,30 +1,227 @@ import java.util.Optional; +import java.io.PrintStream; +import java.io.InputStream; +import java.util.Random; /** * A logic puzzle where each cell on a grid can be either "on" or "off". * Selecting a cell toggles it and its immediate neighbors. * The goal is to turn all the lights off in as few moves as possible. - *
+ *
  * Consider a model using a grid of booleans.
  * Implement toggling logic on that grid.
- * 
+ * * @version 1 */ -class LightsOutGame implements Game { + +public class LightsOutGame implements Game { + /** Input source (injected for testing). */ + private final InputStream in; + + /** Output sink (defaults to System.out). */ + private final PrintStream out; + + /** Current board state. */ + private final LightsOutBoard board; + + /** Copy of original board used for restart. */ + private final LightsOutBoard boardCopy; + + /** Pseudo-random generator for board creation. */ + private final Random rng = new Random(); + + /** Default number of rows for the board. */ + private static final int DEFAULT_ROWS = 5; + + /** Default number of columns for the board. */ + private static final int DEFAULT_COLS = 5; + + /** + * No-argument constructor that delegates to the InputStream constructor. + */ + public LightsOutGame() { + //Stub: Write constructor + } + + /** + * Constructor that accepts an InputStream + * for testability and uses a default board size. + * @param inputStream the input stream to read commands from + * (must not be null) + */ + public LightsOutGame(final InputStream inputStream) { + //Stub:Write constructor + } + /** + * Full constructor that accepts an input + * stream and a pre-constructed board. + * This constructor supports deterministic tests + * by allowing an injected board. + * @param inputStream the input stream to read + * commands from (must not be null) + * @param initialBoard the initial board to use + * for the game (must not be null) + */ + public LightsOutGame(final InputStream inputStream, + final LightsOutBoard initialBoard) { + //Stub: Write constructor + } + /** + * {@inheritDoc} + */ @Override public String getName() { return "Lights Out"; } + /** + * Entry point for playing the game. This stub prints + * the welcome text and returns empty. + * + * @return an Optional containing the number of moves + * if the player solved the board; empty otherwise + */ @Override public Optional play() { - System.out.println("Welcome to Lights Out!"); - System.out.println("The tiles have an 'on' or 'off' function."); - System.out.println("Selecting a tile will change its state."); - System.out.println("Tiles also change the state of neighboring tiles."); - System.out.println("Turning them 'off' or 'on' as well."); - System.out.println("Grid must be lit in as few turns as possible."); - System.out.println("Good luck!"); + out.println("Welcome to Lights Out!"); + out.println("The tiles have an 'on' or 'off' function."); + out.println("Selecting a tile will change its state."); + out.println("Tiles also change the state of neighboring tiles."); + out.println("Turning them 'off' or 'on' as well."); + out.println("Grid must be lit in as few turns as possible."); + out.println("Good luck!"); return Optional.empty(); } + /** + * Parse a player's move from free-form input + * such as "2,3", "2 3", or "(2, 3)". + * + * @param input the raw input string from the player + * @return an Optional containing a two-element int + * array [row, col] when parsing succeeds; empty otherwise + */ + private Optional parseMove(final String input) { + return Optional.empty(); + } + /** + * Internal representation of the lights-out board. + */ + static class LightsOutBoard { + /** Grid of cells; true means "on", false means "off". */ + private final boolean[][] grid; + + /** Number of rows in the grid. */ + private final int rows; + + /** Number of columns in the grid. */ + private final int cols; + + /** + * Create a board with default dimensions (5x5). + */ + LightsOutBoard() { + //Stub: Write constructor + } + /** + * Create a board with the specified number of rows and columns. + * + * @param numRows the number of rows + * @param numColumns the number of columns + */ + LightsOutBoard(final int numRows, final int numColumns) { + //Stub: Write constructor + } + /** + * Copy constructor. + * + * @param other the board to copy + */ + LightsOutBoard(final LightsOutBoard other) { + //Stub: Write constructor + } + /** + * Toggle the specified cell and its immediate orthogonal neighbors. + * Boundary cells only toggle neighbors that exist. + * + * @param row the row index to toggle + * @param column the column index to toggle + * @return true if the board is fully off after the toggle; + * false otherwise + */ + public boolean toggle(final int row, final int column) { + return false; + } + /** + * Produce a labeled ASCII representation of the board. + * + * @return a multi-line string containing the board display + */ + public String display() { + return ""; + } + + /** + * Retrieve the state of a cell. + * + * @param row the row index + * @param column the column index + * @return true if the cell is on; false if it is off + */ + boolean getCell(final int row, final int column) { + return false; + } + + /** + * Set the state of a cell. + * + * @param row the row index + * @param column the column index + * @param value true to set the cell on; false for off + */ + void setCell(final int row, final int column, final boolean value) { + //Stub: Write cell setter + } + /** + * Check whether all lights on the board are off. + * + * @return true when all cells are false; false otherwise + */ + public boolean isSolved() { + return false; + } + + /** + * Helper that produces solvable boards (stubbed). + */ + static class BoardGenerator { + /** + * Generate a board that is guaranteed + * solvable (stubbed implementation). + * + * @param rows the number of rows + * @param cols the number of columns + * @param rng the random generator to use + * @return a solvable LightsOutBoard (currently a fresh empty board) + */ + public LightsOutBoard generateSolvable(final int rows, + final int cols, final Random rng); + } + + /** + * Solver implementation (stubbed). + */ + static class LightsOutSolver { + /** + * Determine whether the provided board + * has a solution (stubbed implementation). + * + * @param board the board to analyze + * @return true if the board is solvable, otherwise false + */ + public boolean isSolvable(final LightsOutBoard board) { + //Stub: implement solver + return true; + } + } + } } diff --git a/build/jar/ConsoleGameHub.jar b/build/jar/ConsoleGameHub.jar new file mode 100644 index 0000000000000000000000000000000000000000..098b62e651ac8738595950ee9de1f745301b2504 GIT binary patch literal 21236 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 literal 0 HcmV?d00001