184 lines
5.7 KiB
Java
184 lines
5.7 KiB
Java
/*
|
|
* 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;
|
|
}
|
|
|
|
|
|
|
|
}
|