📄 model.java
字号:
package org.bubblebreaker.model;
import org.bubblebreaker.config.*;
import org.bubblebreaker.view.*;
import java.util.*;
public abstract class Model
{
public final static int RANDOM_BUILDER =0;
public final static int SQUARE_BUILDER =1;
public Board currentBoard = null;
public long startTimeInMillis;
public static Model createModel( int rows, int cols, int nBalls, int builderType)
{
return new ModelImpl(rows,cols,nBalls,builderType);
}
public abstract void addModelEventListner(ModelEventListener lsnr);
public abstract void changeBall();
public abstract Cell move(int direction);
public abstract boolean isGameEnded();
public abstract void deleteCells();
public abstract void fire();
public abstract int getScore();
public abstract void undo();
}
class ModelImpl extends Model
{
Vector modelEventListeners=new Vector();
public Board oldBoard = null; //for undo
public int m_nBalls;
Ball balls[]=Ball.balls;
boolean gameEnded=false;
static BoardBuilder builder=null;
public void addModelEventListner(ModelEventListener lsnr)
{
modelEventListeners.addElement(lsnr);
}
public ModelImpl(int rows, int cols, int nBalls, int builderType)
{
startTimeInMillis=System.currentTimeMillis();
switch(builderType)
{
case RANDOM_BUILDER:
builder=new RandomBoardBuilder();
break;
case SQUARE_BUILDER:
builder=new SquareBoardBuilder();
break;
}
currentBoard=new Board(rows,cols);
oldBoard=new Board(rows,cols);
m_nBalls = nBalls;
gameEnded=false;
builder.buildBoard(currentBoard);
oldBoard.copy(currentBoard);
int adverseSelection = Settings.getLevel();
if(adverseSelection>3)
adverseSelection = 3;
builder.setAdverseSelection(adverseSelection);
modelEventListeners.removeAllElements();
}
public void changeBall()
{
if(currentBoard.score.getScore()<100)
return;
if(currentBoard.selectedCells!=null)
return;
Cell cell=currentBoard.currentCell;
if(currentBoard.data[cell.row][cell.col] == Ball.WHITEBALL)//should ne'er happen
return;
while(true)
{
int ballIndex=Math.abs((Math.abs(RandomBoardBuilder.m_random.nextInt())%m_nBalls)-1);
if(currentBoard.data[cell.row][cell.col] != Ball.balls[ballIndex])
{
currentBoard.data[cell.row][cell.col] = Ball.balls[ballIndex];
currentBoard.score.decreaseScore(100);
fireEvent(CHANGED_BALL_EVENT);
return;
}
}
}
public Cell move(int direction)
{
currentBoard.selectedCells= null;//any move will clear the selection
return move(direction,currentBoard.currentCell.row,currentBoard.currentCell.col,1);
}
private Cell move(int direction,int startRow, int startCol, int recursionDepth)
{
int col=startCol,
row=startRow;
switch (direction) {
case BubbleBreakerCanvas.UP:
//if we are at corner then we should not move
if(row>0)
{
for(--row;row>0 && Ball.WHITEBALL == currentBoard.data[row][col];row--);
}
else
{
row=currentBoard.data.length-1;
startRow=currentBoard.data.length;//if not the end of search
}
break;
case BubbleBreakerCanvas.DOWN:
if(row<currentBoard.data.length-1)
{
for(++row;row<currentBoard.data.length-1 && Ball.WHITEBALL == currentBoard.data[row][col];row++);
}
else
{
row= 0;
startRow=-1;//if not the end of search
}
break;
case BubbleBreakerCanvas.LEFT:
if(col>0)
{
for(--col;col>0 && Ball.WHITEBALL == currentBoard.data[row][col];col--);
}
else
{
col=currentBoard.data[0].length-1;
startCol=currentBoard.data[0].length;//if not the end of search
}
break;
case BubbleBreakerCanvas.RIGHT:
if(col<currentBoard.data[0].length-1)
{
for(++col;col<currentBoard.data[0].length-1 && Ball.WHITEBALL == currentBoard.data[row][col];col++);
}
else
{
col=0;
startCol=-1;//if not the end of search
}
break;
}
if(Ball.WHITEBALL != currentBoard.data[row][col])
{
currentBoard.currentCell = new Cell(row, col);
fireEvent(MOVED_EVENT);
}else if(1==recursionDepth)
{
move(direction, startRow,startCol,recursionDepth+1);
}
return currentBoard.currentCell;
}
void findInvalidState()
{
for(int col=0;col<currentBoard.data[0].length;col++)
{
if(currentBoard.data[0][col] != Ball.WHITEBALL &&
currentBoard.data[1][col] == Ball.WHITEBALL)
System.out.println("Invalid situation caught");
}
}
void checkIfEndOfGame()
{
for(int row=0;row<currentBoard.data.length;row++)
for(int col=0;col<currentBoard.data[0].length;col++)
{
if(Ball.WHITEBALL == currentBoard.data[row][col])
{
continue;
}
//look down
if(row+1 < currentBoard.data.length)
{
if(currentBoard.data[row][col] == currentBoard.data[row+1][col])
return;
}
//look right
if(col+1 < currentBoard.data[0].length)
{
if(currentBoard.data[row][col] == currentBoard.data[row][col+1])
return;
}
}
gameEnded=true;
fireEvent(END_EVENT);
}
public boolean isGameEnded()
{
return gameEnded;
}
public void deleteCells()
{
int size=currentBoard.selectedCells.length;
if(1 == size)
{
//we do not delete single cell
return;
}
oldBoard.copy(currentBoard);
//remove the cells
//count unique cells
int uniqueCount=0;
for(int i=0;i<size;i++)
{
Cell cell=currentBoard.selectedCells[i];
if(currentBoard.data[cell.row][cell.col]!=Ball.WHITEBALL)
{
uniqueCount++;
currentBoard.data[cell.row][cell.col]=Ball.WHITEBALL;
}
}
currentBoard.score.addDeletedItems(uniqueCount);
//push cells down
for(int i=0;i<size;i++)
{
Cell cell=currentBoard.selectedCells[i];
int count=0;
System.out.println("Pushing cells down :"+cell.row+","+cell.col);
for(int row=cell.row;row>=0;row--)
{
if(Ball.WHITEBALL != currentBoard.data[row][cell.col])
{
System.out.println(""+row+"<-"+ (row+count));
currentBoard.data[row+count][cell.col]=currentBoard.data[row][cell.col];
}else{
count++;
}
}
for(int row=0;row<count;row++)
{
currentBoard.data[row][cell.col]=Ball.WHITEBALL;
}
}
System.out.println("Find empty columns");
//find empty columns
for(int col=0;col<currentBoard.data[0].length;col++)
{
//last row empty means column empty
if(Ball.WHITEBALL == currentBoard.data[currentBoard.data.length-1][col])
{
//the whole column has to go
for(int col1=col-1;col1>=0;col1--)
{
for(int row=0;row<currentBoard.data.length;row++)
{
currentBoard.data[row][col1+1]=currentBoard.data[row][col1];
}
}
System.out.println("Add new column");
//add a new column
builder.addNewColumn(0,currentBoard);
}
}
System.out.println("select the cell");
//move the current selected cell if it was deleted
if(Ball.WHITEBALL == currentBoard.data[currentBoard.currentCell.row][currentBoard.currentCell.col])
{
move(BubbleBreakerCanvas.DOWN);
}
//now no cells are selected
currentBoard.selectedCells = null;
fireEvent(DELETED_EVENT);
checkIfEndOfGame();
}
void selectSameColored(Ball ball, int row, int col, java.util.Vector v)
{
if(ball == currentBoard.data[row][col])
{
System.out.println(""+row+","+col);
Cell cell= new Cell(row,col);
if(v.contains(cell))
return;
else
v.addElement(cell);
}
else
{
return;
}
int row1=row+1;
int col1 = col;
if(row1<currentBoard.data.length)
{
selectSameColored(ball,row1,col1,v);
}
row1=row-1;
if(row1>=0)
{
selectSameColored(ball,row1,col1,v);
}
row1=row;
col1=col+1;
if(col1<currentBoard.data[0].length)
{
selectSameColored(ball,row1,col1,v);
}
col1=col-1;
if(col1>=0)
{
selectSameColored(ball,row1,col1,v);
}
}
public void fire()
{
Ball ball=currentBoard.data[currentBoard.currentCell.row][currentBoard.currentCell.col];
System.out.println(""+currentBoard.currentCell.row+","+currentBoard.currentCell.col+","+ball.color.getCode()+","+ball);
java.util.Vector v=new java.util.Vector();
selectSameColored(ball,currentBoard.currentCell.row,currentBoard.currentCell.col,v);
int size=v.size();
if(size>0)
{
currentBoard.selectedCells=new Cell[size];
for(int i=0;i<size;i++)
{
currentBoard.selectedCells[i]=(Cell)v.elementAt(i);
}
fireEvent(SELECTED_EVENT);
}
}
public int getScore()
{
return currentBoard.score.getScore();
}
public void undo()
{
currentBoard.copy(oldBoard);
fireEvent(UNDO_EVENT);
}
private final static int UNDO_EVENT = 0;
private final static int MOVED_EVENT = 1;
private final static int END_EVENT = 2;
private final static int DELETED_EVENT = 3;
private final static int SELECTED_EVENT = 4;
private final static int CHANGED_BALL_EVENT = 5;
private void fireEvent(int type)
{
for (Enumeration e = modelEventListeners.elements() ; e.hasMoreElements() ;) {
ModelEventListener lsnr=(ModelEventListener)e.nextElement();
switch(type)
{
case UNDO_EVENT :
lsnr.undoed();
break;
case MOVED_EVENT:
lsnr.moved();
break;
case END_EVENT:
lsnr.ended();
break;
case DELETED_EVENT:
lsnr.deleted();
break;
case SELECTED_EVENT:
lsnr.selected();
break;
case CHANGED_BALL_EVENT:
lsnr.changedBall();
break;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -