/** * Simple extension of class Board that provides a textual representation of * the MineSweeper game board on System.out. */ public class TextBoard extends Board { // Maximum length of string to hold column/row numbers private int colLength, rowLength; // Printable versions of column and row numbers private String[] colNums, rowNums; // Spacing for column-header lines private String spacer; /** * Create a new TextBoard of size width*height and containing numMines * mines. */ public TextBoard(int width, int height, int numMines) { // Don't forget to initialise the superclass! super(width, height, numMines); // Allocate storage for column and row number, and work out how long the // respective strings need to be. Note that the largest column/row number // is actually one less than width/height, respectivaly. colLength = Integer.toString(width-1).length(); rowLength = Integer.toString(height-1).length(); colNums = new String[width]; rowNums = new String[height]; // Generate column numbers. These are all padded out to colLength for // ease of printing later on. The numbers are right-justified within the // string. for (int i = 0; i < width; i++) { StringBuffer col = new StringBuffer(Integer.toString(i)); while (col.length() < colLength) { col.insert(0, ' '); } colNums[i] = col.toString(); } // Generate a spacer for column numbers. Just a string of spaces that // takes up the same space as a row number, for aligning the column // headers correctly. StringBuffer spaces = new StringBuffer(); for (int i = 0; i < rowLength + 2; i++) { spaces.append(' '); } spacer = spaces.toString(); // Generate row numbers. Exactly the same procedure as the column // numbers, except that we are extra spaces around the number to make the // display more readable. for (int i = 0; i < height; i++) { StringBuffer row = new StringBuffer(Integer.toString(i)); while (row.length() <= rowLength) { row.insert(0, ' '); } row.append(' '); rowNums[i] = row.toString(); } } /** * Draw the current state of the board on System.out, as follows: * - An unknown cell is indicated by '#' * - A marked cell is indicated by 'X' * - A revealed mine is indicated by '*' * - A revealed empty cell contains a digit indicating the number of * immediate neighbours containing mines, or '.' if there are no such * neighbours. */ public void draw() { // Some space System.out.println(); // Do column numbers. We print these out vertically, 'bottom-justified'. // Note the use of the spacer defined in the constructor. for (int i = 0; i < colLength; i++) { System.out.print(spacer); for (int j = 0; j < width; j++) { System.out.print(colNums[j].charAt(i)); } System.out.println(); } // Some more space System.out.println(); // Do rows, complete with numbers for (int i = 0; i < height; i++) { // Print row number. We do this again at the end of the row in case the // board is huge and hard to read. System.out.print(rowNums[i]); // Print something appropriate for the cell for (int j = 0; j < width; j++) { switch (board[j][i]) { case UNKNOWN: System.out.print("#"); break; case MARKED: System.out.print("X"); break; case MINE: System.out.print("*"); break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: System.out.print(board[j][i]); break; case 0: System.out.print("."); break; } } System.out.println(rowNums[i]); } // Some more space System.out.println(); // Do column numbers, again in case the board is humongous and hard to // read. for (int i = 0; i < colLength; i++) { System.out.print(spacer); for (int j = 0; j < width; j++) { System.out.print(colNums[j].charAt(i)); } System.out.println(); } // Some more space (surprise) System.out.println(); // Display the number of mines left to find. This number reflects the // number of marked mines, any of which might of course be wrong! System.out.println("Mines remaining: " + (getMines() - getMarked())); // Yet more spacing System.out.println(); } }