Android Open Source - android-simlple-minefield Mine Model






From Project

Back to project page android-simlple-minefield.

License

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.

Java Source Code

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;
        }
    }
}




Java Source Code List

com.trabo.minefield.CellOnTouchListener.java
com.trabo.minefield.GameActivity.java
com.trabo.minefield.HighScoresActivity.java
com.trabo.minefield.MainActivity.java
com.trabo.minefield.MineFieldListener.java
com.trabo.minefield.MineModel.java
com.trabo.minefield.MinefieldAdapter.java
com.trabo.minefield.MinefieldView.java
com.trabo.minefield.utils.AppContract.java
com.trabo.minefield.utils.AppUtils.java
com.trabo.minefield.utils.MineGridUtils.java