package com.netbeetle.minesweeper; public class Cell { private Cell[] neighbors = null; private double mineProbability = .5; private int probabilityQuality = 0; private boolean neighborsKnown = false; private boolean known = false; private boolean mine; private boolean guess = false; private boolean mineGuess = false; private int mines = 0; public Cell(boolean mine) { this.mine = mine; } public void setNeighbors(Cell[] neighbors) { this.neighbors = neighbors; updateMines(); } public Cell[] getNeighbors() { return neighbors; } public void setMineProbability(double probability) { mineProbability = probability; probabilityQuality = 0; normalizeProbability(); } public void adjustMineProbability(double probability) { mineProbability = ((mineProbability * probabilityQuality) + probability) / (probabilityQuality + 1); probabilityQuality++; normalizeProbability(); } private void normalizeProbability() { if (mineProbability > 1) mineProbability = 1; else if (mineProbability < 0) mineProbability = 0; } public double getMineProbability() { return mineProbability; } public boolean isKnown() { return known; } public boolean isMine() { return known && mine; } public boolean isEmpty() { return known && !mine; } public int getMines() { if (isEmpty()) return mines; return -1; } public void updateMines() { if (neighbors == null) return; mines = 0; for (int i = 0; i < neighbors.length; i++) { if (neighbors[i] == null) continue; if (neighbors[i].mine) mines++; } } public void guess(boolean mine) { if (known) return; guess = true; mineGuess = mine; } public void clearGuess() { guess = false; } public boolean hasGuess() { return guess; } public boolean getGuess() { return mineGuess; } public boolean reveal() { if (known) return !mine; guess = false; known = true; if (!mine && mines == 0) return revealNeighbors(); return !mine; } public boolean revealNeighbors() { for (int i = 0; i < neighbors.length; i++) { if (neighbors[i] == null) continue; if (neighbors[i].known) continue; if (neighbors[i].guess && neighbors[i].mineGuess) continue; if (!neighbors[i].reveal()) return false; } return true; } public boolean isSatisfiable() { if (neighbors == null) return false; if (!isEmpty()) return true; int existingMines = 0; int unknownCells = 0; for (int i = 0; i < neighbors.length; i++) { if (neighbors[i] == null) continue; if (neighbors[i].isMine()) existingMines++; else if (neighbors[i].guess) { if (neighbors[i].mineGuess) existingMines++; } else if (!neighbors[i].isKnown()) { unknownCells++; } } int minesNeeded = mines - existingMines; if (minesNeeded < 0 || minesNeeded > unknownCells) return false; return true; } public boolean isSatisfied() { if (neighbors == null) return false; if (!isEmpty()) return true; int existingMines = 0; for (int i = 0; i < neighbors.length; i++) { if (neighbors[i] == null) continue; if (neighbors[i].isMine()) existingMines++; else if (neighbors[i].guess) { if (neighbors[i].mineGuess) existingMines++; } } return mines - existingMines == 0; } public boolean areNeighborsSatisfiable() { if (neighbors == null) return false; //if (known) // return true; int existingMines = 0; int unknownCells = 0; for (int i = 0; i < neighbors.length; i++) { if (neighbors[i] == null) continue; if (!neighbors[i].isSatisfiable()) return false; } return true; } public boolean areNeighborsSatisfied() { if (neighbors == null) return false; //if (known) // return true; int existingMines = 0; int unknownCells = 0; for (int i = 0; i < neighbors.length; i++) { if (neighbors[i] == null) continue; if (!neighbors[i].isSatisfied()) return false; } return true; } public boolean hasEmptyNeighbors() { for (int i = 0; i < neighbors.length; i++) { if (neighbors[i] == null) continue; if (neighbors[i].isEmpty()) return true; } return false; } }