The MineSweeper class

  1: import java.io.*;
  2: 
  3: /**
  4:  * A basic implementation of the MineSweeper game, using a TextBoard for
  5:  * display purposes and a StringTokenizer to parse commands entered at the
  6:  * keyboard.  No support yet for anything fancy like high score tables (or
  7:  * graphics :)  We do, however, time how long it takes you to finish the
  8:  * game.
  9:  */
 10: public class MineSweeper {
 11: 
 12:   // The game board
 13:   private Board board;
 14: 
 15:   // Tokenizer for commands
 16:   private StreamTokenizer tok;
 17: 
 18:   // Various flags used by play() and doCommand()
 19:   private boolean done, quit, win;
 20: 
 21:   // Contents of last cell revealed
 22:   private int lastCell;
 23: 
 24: 
 25:   /**
 26:    * Create and initialise a new game of the given dimensions.
 27:    */
 28:   public MineSweeper(int width, int height, int mines) {
 29:     // Create the game board
 30:     board = new TextBoard(width, height, mines);
 31: 
 32:     // Set up the command tokenizer
 33:     tok = new StreamTokenizer(new InputStreamReader(System.in));
 34: 
 35:     done = win = quit = false;
 36:   }
 37: 
 38: 
 39:   /**
 40:    * Main game loop.
 41:    */
 42:   public void play() throws IOException {
 43:     // Start the clock
 44:     long startTime = System.currentTimeMillis();
 45: 
 46:     // Loop until game over, for whatever reason
 47:     while (!done) {
 48: 
 49:       // Redraw board
 50:       board.draw();
 51: 
 52:       // Get next command
 53:       System.out.print("Command: ");
 54:       System.out.flush();
 55:       tok.nextToken();
 56: 
 57:       // Dispatch on command
 58:       switch (tok.ttype) {
 59:        case StreamTokenizer.TT_WORD:
 60:         doCommand();
 61:         break;
 62:        case StreamTokenizer.TT_EOL:
 63:         continue;
 64:        case StreamTokenizer.TT_EOF:
 65:         done = quit = true;
 66:         break;
 67:        default:
 68:         System.out.println("Unknown command -- try 'help'");
 69:       }
 70: 
 71:       // Check whether the game is up.  If the number of unknown cells = the
 72:       // number of mines, you must have won (by finding all the mines).  If,
 73:       // on the other hand, you revealed a mine, time to die :(
 74:       if (board.getUnknown() == board.getMines()) {
 75:         done = win = true;
 76:       }
 77:       else if (lastCell == Board.MINE) {
 78:         done = true;
 79:       }
 80: 
 81:       // Suck any remaining crap out of the input stream.  I'm not sure that
 82:       // this works properly (not on my machine, at least).
 83:       System.in.skip(System.in.available());
 84:     }
 85: 
 86:     // Game over, one way or another.  Figure out how long it took
 87:     long elapsedTime = System.currentTimeMillis() - startTime;
 88: 
 89:     // Reveal everything, just so the stats are correct
 90:     for (int i = 0; i < board.getWidth(); i++) {
 91:       for (int j = 0; j < board.getHeight(); j++) {
 92:         board.reveal(i, j);
 93:       }
 94:     }
 95: 
 96:     // Redraw the board and print out some messages
 97:     board.draw();
 98:     if (win) {
 99:       System.out.println("Congratulations -- you found all the mines!");
100:     }
101:     else if (!quit) {
102:       System.out.println("Bad luck -- you stepped on a mine!");
103:     }
104:     System.out.println("Total game time: "+(elapsedTime/1000)+" seconds");
105:   }
106: 
107: 
108:   /**
109:    * Process commands.  'Help' gives a summary of the huge range of available
110:    * commands.
111:    */
112:   private void doCommand() throws IOException {
113:     int x, y;
114: 
115:     if (tok.sval.equals("reveal")) {
116:       // Reveal a cell (and perhaps some around it)
117:       tok.nextToken();
118:       x = (int)tok.nval;
119:       tok.nextToken();
120:       y = (int)tok.nval;
121:       lastCell = board.reveal(x, y);
122:       if (lastCell == 0) {
123:         board.revealMore(x, y);
124:       }
125:     }
126:     else if (tok.sval.equals("mark")) {
127:       // Mark a cell
128:       tok.nextToken();
129:       x = (int)tok.nval;
130:       tok.nextToken();
131:       y = (int)tok.nval;
132:       board.mark(x, y);
133:     }
134:     else if (tok.sval.equals("unmark")) {
135:       // Unmark a cell
136:       tok.nextToken();
137:       x = (int)tok.nval;
138:       tok.nextToken();
139:       y = (int)tok.nval;
140:       board.unmark(x, y);
141:     }
142:     else if (tok.sval.equals("help")) {
143:       // Print some help
144:       System.out.println("reveal  ");
145:       System.out.println("mark  ");
146:       System.out.println("unmark  ");
147:       System.out.println("help");
148:       System.out.println("quit");
149:     }
150:     else if (tok.sval.equals("quit")) {
151:       // Quit and die
152:       quit = done = true;
153:     }
154:     else {
155:       System.out.println("Unknown command -- try 'help'");
156:     }
157:   }
158: 
159: 
160:   /**
161:    * Main program to start and run a new game.  Expects three command line
162:    * parameters: width, height and mine count.
163:    */
164:   public static void main(String[] args) throws IOException {
165: 
166:     MineSweeper game;
167: 
168:     if (args.length < 3) {
169:       System.out.println("Usage: java MineSweeper   ");
170:       System.exit(0);
171:     }
172:     else {
173:       int width = Integer.parseInt(args[0]);
174:       int height = Integer.parseInt(args[1]);
175:       int mines = Integer.parseInt(args[2]);
176:       game = new MineSweeper(width, height, mines);
177:       game.play();
178:     }
179:   }
180: }
    

Scott Mitchell
Last modified: Thu Nov 5 21:33:08 GMT 1998