Java 尝试为洪水填充游戏开发一个使用堆栈的撤销功能
我正在开发一个使用模型-视图-控制器方法的洪水填充游戏。现在我被困在构建一个可以存储游戏模型对象克隆的堆栈中Java 尝试为洪水填充游戏开发一个使用堆栈的撤销功能,java,stack,Java,Stack,我正在开发一个使用模型-视图-控制器方法的洪水填充游戏。现在我被困在构建一个可以存储游戏模型对象克隆的堆栈中 public class GameModel implements Cloneable { /** * predefined values to capture the color of a DotInfo */ public static final int COLOR_0 = 0; public static final int COLOR_1
public class GameModel implements Cloneable {
/**
* predefined values to capture the color of a DotInfo
*/
public static final int COLOR_0 = 0;
public static final int COLOR_1 = 1;
public static final int COLOR_2 = 2;
public static final int COLOR_3 = 3;
public static final int COLOR_4 = 4;
public static final int COLOR_5 = 5;
public static final int NUMBER_OF_COLORS = 6;
/**
* The current selection color
*/
private int currentSelectedColor;
/**
* The size of the game.
*/
private int sizeOfGame;
/**
* A 2 dimentionnal array of sizeOfGame*sizeOfGame recording the state of each dot
*/
private DotInfo[][] model;
/**
* The number of steps played since the last reset
*/
private int numberOfSteps;
/**
* The number of captered dots
*/
private int numberCaptured;
/**
* Random generator
*/
private Random generator;
/**
* Constructor to initialize the model to a given size of board.
*
* @param size
* the size of the board
*/
public GameModel(int size) {
generator = new Random();
sizeOfGame = size;
reset();
}
/**
* Resets the model to (re)start a game. The previous game (if there is one)
* is cleared up .
*/
public void reset(){
model = new DotInfo[sizeOfGame][sizeOfGame];
for(int i = 0; i < sizeOfGame; i++){
for(int j = 0; j < sizeOfGame; j++){
model[i][j] = new DotInfo(i,j,generator.nextInt(NUMBER_OF_COLORS));
}
}
numberOfSteps =0;
}
/**
* Getter method for the size of the game
*
* @return the value of the attribute sizeOfGame
*/
public int getSize(){
return sizeOfGame;
}
/**
* returns the color of a given dot in the game
*
* @param i
* the x coordinate of the dot
* @param j
* the y coordinate of the dot
* @return the status of the dot at location (i,j)
*/
public int getColor(int i, int j){
return isCaptured(i, j) ? currentSelectedColor : model[i][j].getColor();
}
/**
* returns true is the dot is captured, false otherwise
*
* @param i
* the x coordinate of the dot
* @param j
* the y coordinate of the dot
* @return the status of the dot at location (i,j)
*/
public boolean isCaptured(int i, int j){
return model[i][j].isCaptured();
}
/**
* Sets the status of the dot at coordinate (i,j) to captured
*
* @param i
* the x coordinate of the dot
* @param j
* the y coordinate of the dot
*/
public void capture(int i, int j){
model[i][j].setCaptured(true);
numberCaptured++;
}
/**
* Getter method for the current number of steps
*
* @return the current number of steps
*/
public int getNumberOfSteps(){
return numberOfSteps;
}
/**
* Setter method for currentSelectedColor
*
* @param val
* the new value for currentSelectedColor
*/
public void setCurrentSelectedColor(int val) {
currentSelectedColor = val;
}
/**
* Getter method for currentSelectedColor
*
* @return currentSelectedColor
*/
public int getCurrentSelectedColor() {
return currentSelectedColor ;
}
/**
* Getter method for the model's dotInfo reference
* at location (i,j)
*
* @param i
* the x coordinate of the dot
* @param j
* the y coordinate of the dot
*
* @return model[i][j]
*/
public DotInfo get(int i, int j) {
return model[i][j];
}
/**
* The metod <b>step</b> updates the number of steps. It must be called
* once the model has been updated after the payer selected a new color.
*/
public void step(){
numberOfSteps++;
}
/**
* The metod <b>isFinished</b> returns true iff the game is finished, that
* is, all the dats are captured.
*
* @return true if the game is finished, false otherwise
*/
public boolean isFinished(){
return numberCaptured == sizeOfGame*sizeOfGame;
}
public GameModel clone(){
try {
return (GameModel)super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
/**
* Builds a String representation of the model
*
* @return String representation of the model
*/
public String toString(){
StringBuffer b = new StringBuffer();
for(int i = 0; i < sizeOfGame; i++){
for(int j = 0; j < sizeOfGame; j++){
b.append(getColor(i, j) + " ");
}
b.append("\n");
}
return b.toString();
}
}
公共类游戏模型实现可克隆{
/**
*捕获点信息颜色的预定义值
*/
公共静态最终整数颜色_0=0;
公共静态最终整数颜色_1=1;
公共静态最终整数颜色_2=2;
公共静态最终整数颜色_3=3;
公共静态最终整数颜色_4=4;
公共静态最终整数颜色_5=5;
公共静态最终整数颜色=6;
/**
*当前选择的颜色
*/
私有int currentSelectedColor;
/**
*游戏的大小。
*/
私有int-sizeOfGame;
/**
*sizeOfGame*sizeOfGame的二维数组,记录每个点的状态
*/
私有DotInfo[][]模型;
/**
*自上次重置后播放的步数
*/
私有整数步数;
/**
*捕获点的数量
*/
私人国际号码;
/**
*随机发生器
*/
专用随机发生器;
/**
*构造函数将模型初始化为给定大小的板。
*
*@param大小
*董事会的规模
*/
公共游戏模型(整数大小){
生成器=新随机数();
sizeOfGame=大小;
重置();
}
/**
*重置模型以(重新)开始游戏。上一个游戏(如果有)
*一切都搞定了。
*/
公共无效重置(){
模型=新点信息[sizeOfGame][sizeOfGame];
对于(int i=0;i
正如您所看到的,我已经实现了cloneable并定义了覆盖抽象类的克隆方法
我正在尝试克隆模型,以便控制器可以在其actionPerformed undo方法中使用该函数
public class GameController implements ActionListener{
/**
* Reference to the view of the board
*/
private GameView gameView;
/**
* Reference to the model of the game
*/
private GameModel gameModel;
private GameModel oldMove;
private int size;
private int i;
private int j;
private Stack<DotInfo> stack;
private boolean setting1;
private boolean setting2;
Stack<GameModel> steps;
/**
* Constructor used for initializing the controller. It creates the game's view
* and the game's model instances
*
* @param size
* the size of the board on which the game will be played
*/
public GameController(int size) {
gameModel = new GameModel(size);
gameView = new GameView(gameModel, this);
reset();
}
/**
* resets the game
*/
public void reset(){
steps= new GenericLinkedStack<GameModel>();
gameModel.reset();
flood();
gameView.update();
setting1 = false;
setting2 = false;
}
/**
* Callback used when the user clicks a button (reset or quit)
*
* @param e
* the ActionEvent
*/
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof DotButton) {
if(gameModel.getNumberOfSteps()==0){
int row = ((DotButton)(e.getSource())).getRow();
int column = ((DotButton)(e.getSource())).getColumn();
gameModel.capture(row,column);
}
selectColor(((DotButton)(e.getSource())).getColor());
} else if (e.getSource() instanceof JButton) {
JButton clicked = (JButton)(e.getSource());
if (clicked.getText().equals("Quit")) {
System.exit(0);
} else if (clicked.getText().equals("Reset")){
reset();
} else if (clicked.getText().equals("Redo")) {
} else if (clicked.getText().equals("Undo")) {
steps.pop();
gameView.update();
} else if (clicked.getText().equals("Settings")) {
gameView.settingsMenu();
}
} else if (e.getSource() instanceof JRadioButton) {
JRadioButton clickedR = (JRadioButton)(e.getSource());
if (clickedR.getText().equals("Torus")) {
setting1 = true;
}
if (clickedR.getText().equals("Diagonal")) {
setting2 = true;
}
}
}
/**
* <b>selectColor</b> is the method called when the user selects a new color.
* If that color is not the currently selected one, then it applies the logic
* of the game to capture possible locations. It then checks if the game
* is finished, and if so, congratulates the player, showing the number of
* moves, and gives to options: start a new game, or exit
* @param color
* the newly selected color
*/
public void selectColor(int color){
steps.push(gameModel.clone());
if(color != gameModel.getCurrentSelectedColor()) {
gameModel.setCurrentSelectedColor(color);
flood();
gameModel.step();
gameView.update();
finished();
}
}
/**
* <b>flood</b> is the method that computes which new dots should be ``captured''
* when a new color has been selected. The Model is updated accordingly
*/
private void flood() {
size = gameModel.getSize()-1;
stack = new GenericLinkedStack<DotInfo>();
for(int i =0; i < gameModel.getSize(); i++) {
for(int j =0; j < gameModel.getSize(); j++) {
if(gameModel.isCaptured(i,j)) {
stack.push(gameModel.get(i,j));
}
}
}
DotInfo dotInfo;
while(!stack.isEmpty()){
dotInfo = stack.pop();
i = dotInfo.getX();
j = dotInfo.getY();
orthogonal();
if (setting1 == true) {
torus();
}
if (setting2 == true) {
diagonal();
}
}
}
/**
* <b>shouldBeCaptured</b> is a helper method that decides if the dot
* located at position (i,j), which is next to a captured dot, should
* itself be captured
* @param i
* row of the dot
* @param j
* column of the dot
*/
private boolean shouldBeCaptured(int x, int y) {
return (!gameModel.isCaptured(x, y) && (gameModel.getColor(x,y) == gameModel.getCurrentSelectedColor())) ? true : false;
}
private void captureAndStack(int x, int y) {
gameModel.capture(x, y);
stack.push(gameModel.get(x,y));
}
private void finished() {
if(gameModel.isFinished()) {
if (gameView.finishedMenu() == 0) {
reset();
} else {
System.exit(0);
}
}
}
公共类GameController实现ActionListener{
/**
*参考委员会的意见
*/
私人游戏视图游戏视图;
/**
*参考游戏的模型
*/
私人博弈模型;
私人游戏模式;
私有整数大小;
私人互联网i;
私人int j;
私有堆栈;
私有布尔设置1;
私有布尔设置2;
堆叠步骤;
/**
*用于初始化控制器的构造函数。它创建游戏的视图
*以及游戏的模型实例
*
*@param大小
*游戏将在其上进行的棋盘的大小
*/
公共游戏控制器(整数大小){
gameModel=新gameModel(尺寸);
gameView=新gameView(gameModel,此);
重置();
}
/**
*重置游戏
*/
公共无效重置(){
步骤=新建GenericLinkedStack();
gameModel.reset();
洪水();
gameView.update();
设置1=错误;
设置2=错误;
}
/**
*用户单击按钮时使用的回调(重置或退出)
*
*@param e
*行动事件
*/
已执行的公共无效操作(操作事件e){
if(例如getSource()instanceof DotButton){
如果(gameModel.getNumberOfSteps()==0){
int r