免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 802 | 回复: 0
打印 上一主题 下一主题

java扫雷——Day7 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-06-16 16:13 |只看该作者 |倒序浏览
昨天晚上发现了异常的原因——没有对边界进行判断!
这样递归调用的时候,函数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
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP