/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package minesweeper.gamestate; import java.util.Random; import minesweeper.random.DefaultRNG; import minesweeper.random.RNG; import minesweeper.settings.GameSettings; import minesweeper.structure.Location; /** * A Version of Minesweeper which ensures the first click is not a mine * @author David */ public class GameStateStandardWith8 extends GameStateModelViewer { private final int[][] board; private RNG rng; public GameStateStandardWith8(GameSettings gameSettings) { this(gameSettings, new Random().nextLong()); } public GameStateStandardWith8(GameSettings gameSettings, long seed) { super(gameSettings, seed); this.board = new int[width][height]; this.rng = DefaultRNG.getRNG(seed); } // in this gamestate we are building the board ourselves @Override protected void startHandle(Location m) { int i=0; Location locationOf8 = null; boolean placed8 = false; while (!placed8) { int y1 = 1 + (int) rng.random(this.height - 2); int x1 = 1 + (int) rng.random(this.width - 2); locationOf8 = new Location(x1, y1); // place the 8 mines around a single tile if (!locationOf8.equals(m) && !locationOf8.isAdjacent(m)) { for (int k=0; k < DX.length; k++) { int x2 = x1 + DX[k]; int y2 = y1 + DY[k]; //System.out.println("Mine added at " + x2 + "," + y2); board[x2][y2] = GameStateModel.MINE; i++; // tell all the surrounding squares they are next to a mine for (int j=0; j < DX.length; j++) { if (x2 + DX[j] >= 0 && x2 + DX[j] < this.width && y2 + DY[j] >= 0 && y2 + DY[j] < this.height) { if (board[x2+DX[j]][y2+DY[j]] != GameStateModel.MINE) { board[x2+DX[j]][y2+DY[j]]++; } } } } placed8 = true; } } while (i < mines) { int y1 = (int) rng.random(this.height); int x1 = (int) rng.random(this.width); Location l1 = new Location(x1, y1); // if the location is NOT the first square pressed // and the location is not already a mine then place a mine here if (!l1.equals(m) && !l1.equals(locationOf8)) { if (board[x1][y1] != GameStateModel.MINE) { //System.out.println("Mine added at " + x1 + "," + y1); board[x1][y1] = GameStateModel.MINE; i++; // tell all the surrounding squares they are next to a mine for (int j=0; j < DX.length; j++) { if (x1 + DX[j] >= 0 && x1 + DX[j] < this.width && y1 + DY[j] >= 0 && y1 + DY[j] < this.height) { if (board[x1+DX[j]][y1+DY[j]] != GameStateModel.MINE) { board[x1+DX[j]][y1+DY[j]]++; } } } } } } } // in this gamestate there is nothing to do @Override protected void placeFlagHandle(Location m) { } @Override protected int queryHandle(int x, int y) { return board[x][y]; } // in this gamestate we need to expand the clear if no mines are adjacent @Override protected boolean clearSquareHitMine(Location m) { // if there are no mines next to this location expand reveal if (board[m.x][m.y] == 0) { explode(m); //clearSurround(m); } if (board[m.x][m.y] == GameStateModel.MINE) { return true; } else { return false; } //return board[m.x][m.y]; } @Override public int privilegedQuery(Location m, boolean showMines) { int result = query(m); if (result == GameStateModel.MINE) { // if we can see a mine using query it must be exploded return GameStateModel.EXPLODED_MINE; } if (showMines && result == GameStateModel.HIDDEN && board[m.x][m.y] == GameStateModel.MINE) { result = GameStateModel.MINE; } if (showMines && result == GameStateModel.FLAG && board[m.x][m.y] != GameStateModel.MINE ) { result = GameStateModel.BAD_FLAG; } return result; } @Override public String showGameKey() { return "Seed = " + seed + " (" + rng.shortname() + ")"; } @Override public boolean supports3BV() { return true; } @Override protected boolean clearSurroundHandle(Location m) { // otherwise, clear around this revealed square for (int j=0; j < DX.length; j++) { if (m.x + DX[j] >= 0 && m.x + DX[j] < this.width && m.y + DY[j] >= 0 && m.y + DY[j] < this.height) { clearSquare(new Location(m.x+DX[j], m.y+DY[j])); } } return true; } }