- 论坛徽章:
- 0
|
今天找到了防止函数进入递归陷阱解决办法:
加入一个新的状态——LOCK。当刚进入一个格子的时候就把状态设置为LOCK,然后加一个判断语句,使得expand()只能展开初始状态的格子。这样就防止进入递归相互调用陷阱的死循环中。当递归函数即将结束退出的时候再把状态置为EXPLODED。
expand()函数的操作过程
1.确保格子有效
2.只会展开状态为INITIAL的格子
3.不是炸弹
4.加锁
5.递归调用
6.展开自己(改变状态和背景颜色)
哈哈,试验了一下,好像可以了。只是现在还有一点问题——游戏结束的问题。把自己的心态调整好——不要着急……
class MineTable extends JPanel implements MouseListener
{
static final int BEGINNER=10 , MIDDLE=40 , ADVANCED=100;
static final int INITIAL=0 , EXPANDED=1 , FLAG=2 , LOCK=3;
static final int PROCEED=0 , EXPLODED=-1 , WIN=1;
int gamestatus=PROCEED;
int grid , grade , total , marked;
//logic form
boolean bomb[][];
int status[][];
//human form
JButton humantable[];
Color defaultcolor;
void map()//generate random map
{
int row,col;
//initial logic table set all grid non mine
for(int i=0; igrid; i++)
{
for(int j=0; jgrid; j++)
{
this.bomb[j] = false;
this.status[j] = INITIAL;
}
}
//set mines
for(int k=0; kgrade; k++)
{
row = (int) (Math.random()*grid);
col = (int) (Math.random()*grid);
if(bomb[row][col] == true)//this grid has been marked as a bomb,so it can not be counted
k--;
else
bomb[row][col] = true;
}
}
//if this grid is valid
boolean isValid(int row , int col)
{
if(row0 || row>(grid-1))
return false;
else if(col0 || col>(grid-1))
return false;
return true;
}
boolean isBomb(int row , int col)
{
if(bomb[row][col] == true)
return true;
else
return false;
}
//computer how many bomb in it's circle
int computeBomb(int row , int col)
{
int number=0;
//up_left
if(isValid((row-1),(col-1)))
if(this.bomb[row-1][col-1] == true)
number++;
//up_middle
if(isValid((row-1),(col)))
if(this.bomb[row-1][col] == true)
number++;
//up_right
if(isValid((row-1),(col+1)))
if(this.bomb[row-1][col+1] == true)
number++;
//left
if(isValid((row),(col-1)))
if(this.bomb[row][col-1] == true)
number++;
//right
if(isValid((row),(col+1)))
if(this.bomb[row][col+1] == true)
number++;
//down_left
if(isValid((row+1),(col-1)))
if(this.bomb[row+1][col-1] == true)
number++;
//down_middle
if(isValid((row+1),(col)))
if(this.bomb[row+1][col] == true)
number++;
//down_right
if(isValid((row+1),(col+1)))
if(this.bomb[row+1][col+1] == true)
number++;
return(number);
}
//set number
void showBomb(int row , int col)
{
String number="";
number = String.valueOf(computeBomb(row,col));
humantable[row*grid+col].setText(number);
}
//this function is only for debug
void showMap(int row , int col)
{
String bmb="";
String number="";
number = String.valueOf(computeBomb(row,col));
if(isBomb(row,col))
bmb = "Y";
else
bmb = "N";
humantable[row*grid+col].setText(bmb + number);
}
int computeFlag(int row , int col)
{
int number=0;
//up_left
if(isValid((row-1),(col-1)))
if(this.status[row-1][col-1] == FLAG)
number++;
//up_middle
if(isValid((row-1),(col)))
if(this.status[row-1][col] == FLAG)
number++;
//up_right
if(isValid((row-1),(col+1)))
if(this.status[row-1][col+1] == FLAG)
number++;
//left
if(isValid((row),(col-1)))
if(this.status[row][col-1] == FLAG)
number++;
//right
if(isValid((row),(col+1)))
if(this.status[row][col+1] == FLAG)
number++;
//down_left
if(isValid((row+1),(col-1)))
if(this.status[row+1][col-1] == FLAG)
number++;
//down_middle
if(isValid((row+1),(col)))
if(this.status[row+1][col] == FLAG)
number++;
//down_right
if(isValid((row+1),(col+1)))
if(this.status[row+1][col+1] == FLAG)
number++;
return(number);
}
//mark the mine
void flag(int row , int col)
{
status[row][col] = FLAG;
this.marked++;
humantable[row*grid+col].setBackground(Color.RED);
}
//unmark the mine
void unflag(int row , int col)
{
status[row][col] = INITIAL;
this.marked--;
humantable[row*grid+col].setBackground(defaultcolor);
}
//expand the mine
void expand(int row , int col)
{
if(isValid(row,col))
{
if(this.status[row][col] == INITIAL)
{
if(isBomb(row,col))
gamestatus = EXPLODED;
else // it's not a bomb itself
{
this.status[row][col] = LOCK; //add lock to the grid
if ((computeBomb(row,col)) - computeFlag(row,col) != 0) // there are many bombs around this grid
{
this.status[row][col] = EXPANDED;
this.humantable[row*grid+col].setBackground(new Color(217, 217, 217));
this.showBomb(row,col);
this.marked++;
}
else // there is no bomb around this grid
{
this.expand(row-1,col-1); //up_left
this.expand(row-1,col); //up_middle
this.expand(row-1,col+1); //up_right
this.expand(row,col-1); //left
this.expand(row,col+1); //right
this.expand(row+1,col-1); //down_left
this.expand(row+1,col); //down_middle
this.expand(row+1,col+1); //down_right
this.status[row][col] = EXPANDED; //unlock the grid
this.marked++;
this.humantable[row*grid+col].setBackground(new Color(217, 217, 217));
}
}
}
}
}
MineTable(int level)
{
switch(level)
{
case BEGINNER:
grade = level;
grid = 9;
total = grid*grid;
marked = 0;
break;
case MIDDLE:
grade = level;
grid = 16;
total = grid*grid;
marked = 0;
break;
case ADVANCED:
grade = level;
grid = 30;
total = grid*grid;
marked = 0;
break;
default:
grade = BEGINNER;
grid = 9;
total = grid*grid;
marked = 0;
}
bomb = new boolean[grid][grid];
status = new int[grid][grid];
humantable = new JButton[total];
defaultcolor = new Color(255);
this.setLayout(new GridLayout(grid,grid));
map();
for (int index = 0; indextotal; index++)
{
humantable[index] = new JButton();
humantable[index].setBackground(Color.WHITE);
humantable[index].addMouseListener(this);
this.add(humantable[index]);
//this.showMap(index/grid , index%grid);
}
validate();
defaultcolor = humantable[0].getBackground(); //get buttom default color
}
/*Mouse Event */
public void mousePressed(MouseEvent e)
{
int row , col;
for(int i=0; itotal; i++)
{
if(e.getSource().equals(humantable))
{
row = i/grid;
col = i%grid;
if((e.getModifiers() == InputEvent.BUTTON1_MASK) && (status[row][col] == INITIAL))
this.expand(row,col);
else if((e.getModifiers() == InputEvent.BUTTON3_MASK) && (status[row][col] == INITIAL) )
this.flag(row,col);
else if((e.getModifiers() == InputEvent.BUTTON3_MASK) && (status[row][col] == FLAG) )
this.unflag(row,col);
}
}
}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
}
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/15262/showart_322745.html |
|