Back to project page android-simlple-minefield.
The source code is released under:
Apache License
If you think the Android project android-simlple-minefield listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.trabo.minefield; /*from w ww. j a v a 2 s . co m*/ import android.graphics.Point; import com.trabo.minefield.utils.MineGridUtils; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author Andriy Petruk <andrii.petruk{at}gmail.com> * @date 23.06.14. */ public class MineModel { private ModelState mCurrentState = ModelState.NOT_STARTED; enum ModelState { NOT_STARTED, STARTED, FINISHED } private final int mWidth; private final int mHeight; private final Map<Point, Cell> mCellData; private final int mNumberFreeCells; private final List<Point> mBombCells; private MineFieldListener mMineFieldListener; private int mCurrentUnmarked; private int mOpenedCells; public MineModel(int width, int height, int numberOfMines) { mWidth = width; mHeight = height; mCurrentUnmarked = numberOfMines; mCellData = new HashMap<Point, Cell>(mWidth * mHeight); mBombCells = new ArrayList<Point>(numberOfMines); mNumberFreeCells = mHeight * mWidth - numberOfMines; fillData(numberOfMines); } private void fillData(int numberOfMines) { int[][] mineFieldData = MineGridUtils.generateMineField(mHeight, mWidth, numberOfMines); for (int y = 0; y < mHeight; y++) { for (int x = 0; x < mWidth; x++) { mCellData.put(new Point(x, y), new Cell(mineFieldData[y][x])); if (mineFieldData[y][x] == MineGridUtils.MINE_CELL) { mBombCells.add(new Point(x, y)); } } } } public int getWidth() { return mWidth; } public int getHeight() { return mHeight; } public void hitCell(Point cellPoint) { Cell cell = mCellData.get(cellPoint); if (mCurrentState == ModelState.FINISHED || cell.getState() != Cell.State.CLOSED) { return; } if (cell.isMine()) { mCurrentState = ModelState.FINISHED; mMineFieldListener.onLoseGame(mBombCells); return; } if (mCurrentState == ModelState.NOT_STARTED) { mMineFieldListener.onStartGame(); mCurrentState = ModelState.STARTED; } if (cell.getValue() == 0) { openZeroArea(cellPoint, new ArrayList<Point>(mNumberFreeCells)); } else { addOpenedCell(cellPoint); } } public void highlightCell(Point cell) { if (mCellData.get(cell).getState() != Cell.State.OPENED) { return; } List<Point> neighbours = MineGridUtils.getNeighbourPointsInGrid(cell, mWidth, mHeight); List<Point> closedNeighbours = new ArrayList<Point>(neighbours.size()); for (Point neighbour : neighbours) { if (mCellData.get(neighbour).getState() == Cell.State.CLOSED) { closedNeighbours.add(neighbour); } } if (closedNeighbours.size() == 1) { hitCell(closedNeighbours.get(0)); } else if (closedNeighbours.size() > 1) { mMineFieldListener.onHighLightCells(closedNeighbours.toArray(new Point[closedNeighbours.size()])); } } private void openZeroArea(Point cellPoint, List<Point> visited) { if (!isValidPoint(cellPoint) || visited.contains(cellPoint) || mCellData.get(cellPoint).getState() != Cell.State.CLOSED) { return; } addOpenedCell(cellPoint); if (mCellData.get(cellPoint).getValue() == 0) { visited.add(cellPoint); List<Point> neighbours = MineGridUtils.getNeighbourPointsInGrid(cellPoint, mWidth, mHeight); for (Point neighbour : neighbours) { openZeroArea(neighbour, visited); } } } private void addOpenedCell(Point cellPoint) { Cell cell = mCellData.get(cellPoint); if (cell.openCell()) { cell.setState(Cell.State.OPENED); mMineFieldListener.onOpenCell(cellPoint, cell.getValue()); mOpenedCells++; if (isGameCompleted()) { mCurrentState = ModelState.FINISHED; mMineFieldListener.onWinGame(mBombCells); } } } private boolean isValidPoint(Point point) { return point.y >= 0 && point.x >= 0 && point.y < mHeight && point.x < mWidth; } private boolean isGameCompleted() { return mOpenedCells >= mNumberFreeCells; } public void setListener(MineFieldListener mineFieldListener) { mMineFieldListener = mineFieldListener; } public void markFlag(Point cellPoint) { if (mCurrentState == ModelState.FINISHED) { return; } Cell cell = mCellData.get(cellPoint); if (cell.flagCell()) { mCurrentUnmarked--; mMineFieldListener.onMarkCell(cellPoint, mCurrentUnmarked); } else if (cell.unFlagCell()) { mCurrentUnmarked++; mMineFieldListener.onUnMarkCell(cellPoint, mCurrentUnmarked); } } public int getCurrentUnmarked() { return mCurrentUnmarked; } private static class Cell { enum State { CLOSED, OPENED, FLAG } private final int mValue; private State mState; Cell(int value) { mValue = value; mState = State.CLOSED; } int getValue() { return mValue; } boolean isMine() { return mValue == MineGridUtils.MINE_CELL; } State getState() { return mState; } void setState(State state) { mState = state; } boolean openCell() { if (mState == State.CLOSED) { mState = State.OPENED; return true; } return false; } boolean flagCell() { if (mState == State.CLOSED) { mState = State.FLAG; return true; } return false; } boolean unFlagCell() { if (mState == State.FLAG) { mState = State.CLOSED; return true; } return false; } } }