- 论坛徽章:
- 0
|
昨天晚上发现了异常的原因——没有对边界进行判断!
这样递归调用的时候,函数expand(i-1,j);可能超出数组的范围,造成异常。并且昨天都是第一次就点击的最边上的格子,所以上来就出错了。
下午到机房加了一个判断,修改了这个问题。再点击的时候果然没有异常了。但是又多了一个新的错误(也许本来由于数组越界没有显现出来)——堆栈溢出!
真让人郁闷。在JC下面还不方便调试。
跟着计算机思路走了一遍,发现了问题!!!expand()函数之间相互调用,造成了死循环!
我2天才想出来的算法啊!就这么over了。气死了,7天都还没有写出来,真是垃圾死了!
回去睡觉……
class MineTable extends JPanel implements MouseListener
{
static final int BEGINNER=10 , MIDDLE=40 , ADVANCED=100;
static final int INITIAL=0 , EXPANDED=-1 , FLAG=1;
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 it is bound
boolean isBeyond(int row , int col)
{
if(row0 || row>(grid-1))
return true;
else if(col0 || col>(grid-1))
return true;
return false;
}
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(!isBeyond((row-1),(col-1)))//没有越界
if(this.bomb[row-1][col-1] == true)
number++;
//up_middle
if(!isBeyond((row-1),(col)))
if(this.bomb[row-1][col] == true)
number++;
//up_right
if(!isBeyond((row-1),(col+1)))
if(this.bomb[row-1][col+1] == true)
number++;
//left
if(!isBeyond((row),(col-1)))
if(this.bomb[row][col-1] == true)
number++;
//right
if(!isBeyond((row),(col+1)))
if(this.bomb[row][col+1] == true)
number++;
//down_left
if(!isBeyond((row+1),(col-1)))
if(this.bomb[row+1][col-1] == true)
number++;
//down_middle
if(!isBeyond((row+1),(col)))
if(this.bomb[row+1][col] == true)
number++;
//down_right
if(!isBeyond((row+1),(col+1)))
if(this.bomb[row+1][col+1] == true)
number++;
return(number);
}
//set number
void displayBomb(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(!isBeyond((row-1),(col-1)))//it's not bound
if(this.status[row-1][col-1] == FLAG)
number++;
//up_middle
if(!isBeyond((row-1),(col)))
if(this.status[row-1][col] == FLAG)
number++;
//up_right
if(!isBeyond((row-1),(col+1)))
if(this.status[row-1][col+1] == FLAG)
number++;
//left
if(!isBeyond((row),(col-1)))
if(this.status[row][col-1] == FLAG)
number++;
//right
if(!isBeyond((row),(col+1)))
if(this.status[row][col+1] == FLAG)
number++;
//down_left
if(!isBeyond((row+1),(col-1)))
if(this.status[row+1][col-1] == FLAG)
number++;
//down_middle
if(!isBeyond((row+1),(col)))
if(this.status[row+1][col] == FLAG)
number++;
//down_right
if(!isBeyond((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;
humantable[row*grid+col].setBackground(Color.RED);
}
//unmark the mine
void unflag(int row , int col)
{
status[row][col] = INITIAL;
humantable[row*grid+col].setBackground(defaultcolor);//这里因该是按钮的默认颜色,但是我不知道
}
//expand the mine
void expand(int row , int col)
{
if(!isBeyond(row,col))
{
if(isBomb(row,col))
{
gamestatus = EXPLODED;
}
// - computeFlag(row,col)
else if ((computeBomb(row,col))== 0)
{
this.status[row][col] = EXPANDED;
this.humantable[row*grid+col].setBackground(new Color(217, 217, 217));
this.displayBomb(row,col);
}
else
{
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
}
}
}
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].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_322587.html |
|