📄 model.java
字号:
/*
* Created on Mar 27, 2005
*
* TODO the model of MVC structure. when model data are changed, call the view
* to show result to user
*/
package model;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import java.util.Observable;
import javax.swing.Timer;
/**
* @author mqqqvpppm
*
* TODO the model of MVC structure. when model data are changed, call the view
* to show result to user
*
*/
public class Model extends Observable {
//for debug
public void view() {
for (int y = 0; y != height; ++y) {
for (int x = 0; x != width; ++x) {
if (matrix[y][x].isMine())
System.out.print("m ");
else
System.out.print(matrix[y][x].getValue() + " ");
}
System.out.println(" ");
}
}
public Model(int width, int height, int mineNumber, int type) {
//matrix = new ModelCellProperty[height][width];
//ret = new ArrayList();
notifingObject = new NotifingObject();
cellNotifingObject = new CellNotifingObject();
timer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (freezed || isNewGame || time >= 1000)
return;
++time;
notifyTimerChanged();
}
});
restart(width, height, mineNumber, type);
}
public void restart(int width, int height, int mineNumber, int type) {
unclickedNumber = height * width - mineNumber;
freezed = false;
// gameOver = false;
isNewGame = true;
isFirstClicking = true;
time = 0;
markedMineNumber = 0;
// notifyTimerChanged();
int x = 0;
int y = 0;
if (width == this.width && height == this.height
&& mineNumber == this.mineNumber) {
for (y = 0; y != height; ++y) {
for (x = 0; x != width; ++x) {
matrix[y][x].clear();
}
}
// setMineAndNumber();
notifyRestartChanged();
return;
}
this.width = width;
this.height = height;
this.mineNumber = mineNumber;
this.type = type;
time = 0;
//unclickedNumber = height * width - mineNumber;
matrix = new ModelCellProperty[height][width];
//if(matrix[y][x] == null){
for (y = 0; y != height; ++y) {
for (x = 0; x != width; ++x) {
matrix[y][x] = new ModelCellProperty();
}
}
//}
//unlockedNumber = 0;
// setMineAndNumber();
notifyRestartChanged();
}
public void unlockAll(Location aLocation) {
Release release = new Release();
release.go(aLocation);
}
public void unlockOne(Location location) {
GetMarkedMineNumber aGMMN = new GetMarkedMineNumber();
aGMMN.go(location);
if (aGMMN.getNumber() == matrix[location.y][location.x].getValue()) {
SetClicked aSC = new SetClicked();
aSC.go(location);
}
}
//public void unlockACell(Location location){
//++unlockedNumber;
//--remanentMineNumber;
// setClickedButton( location );
//}
private void setMineAndNumber() {
int x = 0;
int y = 0;
Random XRandom = new Random();
Random YRandom = XRandom;
for (int i = 0; i != mineNumber; i++) {
x = XRandom.nextInt(width);
y = YRandom.nextInt(height);
if (matrix[y][x].isMine() == true) {
--i;
continue;
}
matrix[y][x].setMine(true);
matrix[y][x].setNumber(false);
SetNumber aSN = new SetNumber();
aSN.go(new Location(x, y));
}
//view();
}
// public void setGameOver(boolean val) {
// gameOver = val;
// notifyGameoverChanged();
// }
//
// public boolean isGameOver() {
// return gameOver;
// }
private class Release extends Traverse {
Release() {
super();
}
void run(int x, int y) {
Location tempLocation = new Location(x, y);
if (matrix[y][x].isMarkedMine() || matrix[y][x].isClickedButton()
|| matrix[y][x].isMine()) {
return;
}
if (matrix[y][x].isNumber()) {
//unlockACell(tempLocation);
setClickedButton(tempLocation);
//setTraversed(true, tempLocation);
//ret.add(tempLocation);
} else { //if( !matrix[y][x].isNumber() &&
// !matrix[y][x].isTraversed() ){
// unlockACell(tempLocation);
setClickedButton(tempLocation);
//setTraversed(true, tempLocation);
//ret.add(tempLocation);
go(tempLocation);
}
}
private Location aLocation;
}
private class SetClicked extends Traverse {
SetClicked() {
super();
}
void run(int x, int y) {
if (matrix[y][x].isClickedButton())
return;
if (!matrix[y][x].isMarkedMine()) {
Location tempLocation = new Location(x, y);
if (!isNumber(tempLocation) && !isMine(tempLocation)) {
unlockAll(tempLocation);
} else {
//unlockACell( tempLocation );
setClickedButton(tempLocation);
}
}
}
}
private class GetMarkedMineNumber extends Traverse {
GetMarkedMineNumber() {
super();
number = 0;
}
void run(int x, int y) {
if (matrix[y][x].isMarkedMine())
++number;
}
public int getNumber() {
return number;
}
private int number;
}
private class SetNumber extends Traverse {
SetNumber() {
super();
}
void run(int x, int y) {
// if (!matrix[y][x].isMine()) {
matrix[y][x].setValue(matrix[y][x].getValue() + 1);
matrix[y][x].setNumber(true);
// }
}
}
//public Object[] getRet(){
// return ret.toArray();
//}
protected ModelCellProperty[][] getMatrix() {
return matrix;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public int getMineNumber() {
return mineNumber;
}
public int getTime() {
return time;
}
public int getValue(Location location) {
return matrix[location.y][location.x].getValue();
}
//private boolean isTraversed(Location location){
// return matrix[location.y][location.x].isTraversed();
//}
public boolean isClickedButton(Location location) {
return matrix[location.y][location.x].isClickedButton();
}
public boolean isMark(Location location) {
return matrix[location.y][location.x].isMark();
}
public boolean isMarkedMine(Location location) {
return matrix[location.y][location.x].isMarkedMine();
}
public boolean isMine(Location location) {
return matrix[location.y][location.x].isMine();
}
public boolean isNumber(Location location) {
return matrix[location.y][location.x].isNumber();
}
public void setClickedButton(Location location) {
if(isFirstClicking){
new Traverse(){
void run(int x, int y) {
matrix[y][x].setMine(true);
}
}.go(location);
setMineAndNumber();
new Traverse(){
void run(int x, int y) {
matrix[y][x].setMine(false);
}
}.go(location);
isFirstClicking = false;
}
matrix[location.y][location.x].setClickedButton(true);
if (isMine(location)) {
notifyGameoverChanged();
return;
}
notifyCellChanged(location);
--unclickedNumber;
if (unclickedNumber == 0 && markedMineNumber == mineNumber)
notifyWinChanged();
}
public int getMarkedMineNumber() {
return markedMineNumber;
}
public int getType(){
return type;
}
public void setTime(int time) {
this.time = time;
notifyTimerChanged();
}
public void setMarkedMineNumber(int markedMineNumber) {
this.markedMineNumber = markedMineNumber;
notifyCellChanged(new Location(0, 0));
}
public void setMark(boolean val, Location location) {
matrix[location.y][location.x].setMark(val);
notifyCellChanged(location);
}
// public void setType(int type){
// this.type = type;
// }
public void setMarkedMine(boolean val, Location location) {
if (val == true)
++markedMineNumber;
else
--markedMineNumber;
matrix[location.y][location.x].setMarkedMine(val);
notifyCellChanged(location);
if (unclickedNumber == 0 && markedMineNumber == mineNumber)
notifyWinChanged();
}
public boolean isFreezed(){
return freezed;
}
private void setMine(boolean val, Location location) {
matrix[location.y][location.x].setMine(val);
}
private void setNumber(boolean val, Location location) {
matrix[location.y][location.x].setMine(val);
}
//private void setTraversed(boolean val, Location location){
// matrix[location.y][location.x].setTraversed(val);
//}
public void setValue(int val, Location location) {
matrix[location.y][location.x].setValue(val);
}
private void notifyCellChanged(Location location) {
if (freezed == true)
return;
if (isNewGame) {
time = 0;
timer.restart();
isNewGame = false;
}
cellNotifingObject.setLocation(location);
cellNotifingObject.setType(NotifingObject.TYPE_CELLCHANGED);
setChanged();// Model notify view
notifyObservers(cellNotifingObject);
}
private void notifyRestartChanged() {
freezed = false;
//notifingObject.setLocation(null);
notifingObject.setType(NotifingObject.TYPE_RESTART);
setChanged();
notifyObservers(notifingObject);
}
private void notifyWinChanged() {
if (freezed == true)
return;
freezed = true;
// time = 0;
// notifyTimerChanged();
//notifingObject.setLocation(null);
notifingObject.setType(NotifingObject.TYPE_WIN);
setChanged();
notifyObservers(notifingObject);
}
private void notifyGameoverChanged() {
//notifingObject.setLocation(null);
if (freezed == true)
return;
// time = 0;
// notifyTimerChanged();
notifingObject.setType(NotifingObject.TYPE_GAMEOVER);
setChanged();
notifyObservers(notifingObject);
freezed = true;
}
private void notifyTimerChanged() {
notifingObject.setType(NotifingObject.TYPE_TIME);
setChanged();
notifyObservers(notifingObject);
}
public static final int TYPE_EASY = 0;
public static final int TYPE_HARD = 1;
public static final int TYPE_HELL = 2;
public static final int TYPE_CUSTOM = 3;
/**
* @author mqqqvpppm
*
* TODO To change the template for this generated type comment go to Window -
* Preferences - Java - Code Style - Code Templates
*/
private abstract class Traverse {
Traverse() {
//ret.clear();
firstTimeTarget = true;
}
abstract void run(int x, int y);
void go(Location aLocation) {
int y = 0;
int x = 0;
if (firstTimeTarget) {
x = aLocation.x;
y = aLocation.y;
run(x, y);
firstTimeTarget = false;
}
y = aLocation.y + 1;
if (isValidY(y))
run(aLocation.x, y);
y = aLocation.y - 1;
if (isValidY(y))
run(aLocation.x, y);
x = aLocation.x + 1;
if (isValidX(x))
run(x, aLocation.y);
x = aLocation.x - 1;
if (isValidX(x))
run(x, aLocation.y);
x = aLocation.x + 1;
y = aLocation.y + 1;
if (isValidX(x) && isValidY(y))
run(x, y);
x = aLocation.x - 1;
y = aLocation.y - 1;
if (isValidX(x) && isValidY(y))
run(x, y);
x = aLocation.x + 1;
y = aLocation.y - 1;
if (isValidX(x) && isValidY(y))
run(x, y);
x = aLocation.x - 1;
y = aLocation.y + 1;
if (isValidX(x) && isValidY(y))
run(x, y);
}
private boolean isValidX(int coordinate) {
if (coordinate < 0 || coordinate >= width)
return false;
return true;
}
private boolean isValidY(int coordinate) {
if (coordinate < 0 || coordinate >= height)
return false;
return true;
}
}
private boolean firstTimeTarget;
private boolean isNewGame;
// private boolean gameOver;
private int type;
private int time;
private boolean freezed;
//private ArrayList ret;
private ModelCellProperty matrix[][];
private int width;
private int height;
private int mineNumber;
private int unclickedNumber;
private int markedMineNumber;
private NotifingObject notifingObject;
private CellNotifingObject cellNotifingObject;
private Timer timer;
private boolean isFirstClicking;
//private int unlockedNumber;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -