扫雷算法及实现

来源:互联网 发布:mysql主从热备 编辑:程序博客网 时间:2024/04/28 15:52

//--------------------------------------------------------------------------
 private int[]      bStr ;//布雷数组
 private int    iEtat;//失败
 private int  iCpt ;//标记雷数

 private Image  buffer;
 private Graphics offScreen;
 private long  startTick ;//记时

 private Image[]  img ;  

 private int aWidth, aHeight;
    //--------------------------------------------------------------------------
 //default param 默认参数,在html没有指定参数时调用
 private int  m_bgcolor = 0 ;    //背景颜色
 public  int  m_mine = 99 ;  //雷数  
 public  int  m_ligne = 16 ;  //列数
 public  int  m_col = 30 ;  //行数
    //--------------------------------------------------------------------------
 private int     iMax ;

 // Font control variables 控制字体变量
 private Font wFont;
 private FontMetrics wMetrics;
 private int  iPas, iX ;


 public void init()
 {
  String param;
  //创建图片
  try {
   aWidth = size().width;
   aHeight = size().height;
   buffer = createImage (aWidth, aHeight);
   offScreen = buffer.getGraphics ();
  } catch (Exception e) {
   offScreen = null;
  }
  //以下几项返回HTML给定的参数值
  // nbMine : Numb   mines
  //----------------------------------------------------------------------
  param = getParameter("nbmine");
  if (param != null)
   m_mine = Integer.parseInt(param);

  // nbcol : Numb of Column
  //----------------------------------------------------------------------
  param = getParameter("nbcol");
  if (param != null)
   m_col = Integer.parseInt(param);

  // nbligne : Numb of Line
  //----------------------------------------------------------------------
  param = getParameter("nbligne");
  if (param != null)
   m_ligne = Integer.parseInt(param);


  // bgcolor: Back Ground Color
  //----------------------------------------------------------------------
  param = getParameter("bgcolor");
  if (param != null)
   m_bgcolor = Integer.parseInt(param);

  MediaTracker  trk = new MediaTracker(this) ;

  // bImg: Button Image 获得Img中的14张图片并把图片加载到媒体跟踪器
  //----------------------------------------------------------------------
  param = getParameter("bImg");
  img = new Image[13];
  if (param != null) {
   for (int i = 0 ; i < 13 ; i++) {
       img[i] = getImage(getCodeBase(), param + (i) + ".gif");
    trk.addImage(img[i], 0) ;
   }
  }
  else
   for (int i = 0 ; i < 13 ; i++)
       img[i] = null ;


  try   { trk.waitForAll() ; }
  catch (InterruptedException e) { }

  // Font
  //----------------------------------------------------------------------
  param = getParameter("fontsize");
  int iSize = 12 ;//默认12号字体
  if (param != null)
   iSize = Integer.parseInt(param);

  param = getParameter("font");
  if (param == null)
   param = new String("Arial") ;

  wFont = new Font(param, Font.BOLD, iSize);
  if (wFont == null) wFont = getFont() ;

  wMetrics = getFontMetrics(wFont);

  iPas = wMetrics.getHeight() * 2 ;
  newGame() ;
   

  }
  //----------------------------------------------------------------------
 
  // start :         random
  //----------------------------------------------------------------------
  public void newGame() {
      Random a ;
  int i = 0 ;
  int j = 0 ;
  int iE ;
  a = new Random() ;
  iEtat = 0 ;
  iCpt = m_mine ;
  int k = 0 ;

  iMax = m_ligne*m_col ;
  bStr = new int[iMax] ;

  iX = (aWidth - (m_col * 15)) / 2 ;//计算边框厚度
  if ( (m_col * 15) > aWidth ) iX = 0 ;

  for (i = 0 ; i < iMax; i++) bStr[i] = 10 ;

  // calculate the tick to wait for
  startTick = -1 ;

  i = 0 ;
  //开始布雷
  while ( i < m_mine) {
   j = (int)(iMax * a.nextDouble()) ;
   if ( (j < iMax) && (bStr[j] != 19 ) ) {
    iE = j % m_col ;
    bStr[j] = 19 ;
    i++ ;

    if (iE > 0) { // 不是第一列
     k = j-1-m_col ; // -31 左上方
     if ( k >= 0 ) 
      if ( bStr[k] != 19 ) bStr[k] += 1 ;
     k = j - 1 ;  // -1 左方
     if ( k >= 0 ) 
      if ( bStr[k] != 19 ) bStr[k] += 1 ;

     k = j+m_col-1 ; // +29  左下方
     if ( k < iMax ) 
      if ( bStr[k] != 19 ) bStr[k] += 1 ;
    }

    k = j - m_col ;//上方
    if ( k >= 0 ) 
     if ( bStr[k] != 19 ) bStr[k] += 1 ;
    k = j + m_col ;//下方
    if ( k < iMax ) 
     if ( bStr[k] != 19 ) bStr[k] += 1 ;

    if (iE < (m_col-1)) {  // 不是最后一列
     k = j-m_col+1 ;  // -29 右上方
     if ( k >= 0 ) 
      if ( bStr[k] != 19 ) bStr[k] += 1 ;
     k = j + m_col + 1 ; // +31 右下方
     if ( k < iMax ) 
      if ( bStr[k] != 19 ) bStr[k] += 1 ;
     k = j + 1 ;   // +1 右方
     if ( k < iMax ) 
      if ( bStr[k] != 19 ) bStr[k] += 1 ;
    }

   }
  }

    repaint();
    
  }

  // start :
  //----------------------------------------------------------------------
  public void start() {
    repaint();
  }


  // mouseDown :
  //----------------------------------------------------------------------
  public boolean mouseDown(Event e, int x, int y){
   int iC = (x-iX) / 15 ;
   int iL = (y-iPas) / 15 ;
   boolean rep = false ;

   if (1 == iEtat) {
    newGame() ;
          repaint() ;
    return(true);
   }

   if ( (y > iPas) && (x > iX) && (x < aWidth - iX))
   if ( (e.modifiers & Event.META_MASK) == Event.META_MASK) {//右键
    if ( bStr[(iL*m_col)+iC] > 9 ) {
   rep = true ;                 
   if ( bStr[(iL*m_col)+iC] < 20 ) { //右键设置雷块的旗帜
    if (iCpt > 0) {
     bStr[(iL*m_col)+iC] += 10 ;
     iCpt-- ;
    }
    else
     showStatus("Erreur trop de mines...");
   }
   else {
     bStr[(iL*m_col)+iC] -= 10 ;
     iCpt++ ;
   }
  }
  else
   rep = testCase((iL*m_col)+iC ) ;
  
   }
   else {       //左键
    if ( bStr[(iL*m_col)+iC] > 9) {
    if (startTick == -1)
       startTick = System.currentTimeMillis() ;
    bStr[(iL*m_col)+iC] -= 10 ;
    rep = true ;
    if (bStr[(iL*m_col)+iC] == 9) //遇雷
     iEtat = 1 ;
    if (bStr[(iL*m_col)+iC] == 0)  //无数字的块
     verifPos( (iL*m_col) + iC) ;
    }
   }

   if (rep)  repaint() ;

   return(true);
  }
  //----------------------------------------------------------------------

  public void verifPos(int j) {
  int iE = j % m_col ;
  int k ;

  if (iE > 0) { // 不是第一列
   k = j - m_col -1 ; // -31 左上方
   if ( k >= 0 ) 
    if (( bStr[k] > 9 ) && ( bStr[k] < 20 ) )  {
     bStr[k] -= 10 ;
     if (bStr[k] == 0) verifPos( k ) ;
       }
   k = j - 1 ;   // -1 左方
   if ( k >= 0 ) 
    if (( bStr[k] > 9 ) && ( bStr[k] < 20 ) )  {
     bStr[k] -= 10 ;
     if (bStr[k] == 0) verifPos( k ) ;
       }
   k = j + m_col - 1 ; // +29     左下方
   if ( k < iMax ) 
    if (( bStr[k] > 9 ) && ( bStr[k] < 20 ) )  {
     bStr[k] -= 10 ;
     if (bStr[k] == 0) verifPos( k ) ;
       }
  }

  k = j - m_col ; //上方
  if ( k >= 0 ) 
   if (( bStr[k] > 9 ) && ( bStr[k] < 20 ) )  {
    bStr[k] -= 10 ;
    if (bStr[k] == 0) verifPos( k ) ;
      }

  k = j + m_col ;//下方
  if ( k < iMax ) 
    if (( bStr[k] > 9 ) && ( bStr[k] < 20 ) )  {
     bStr[k] -= 10 ;
     if (bStr[k] == 0) verifPos( k ) ;
       }

  if (iE < (m_col-1)) { //
   k = j - m_col+1 ; // -29 右上方
   if ( k >= 0 ) 
    if (( bStr[k] > 9 ) && ( bStr[k] < 20 ) )  {
     bStr[k] -= 10 ;
     if (bStr[k] == 0) verifPos( k ) ;
       }

   k = j + m_col + 1 ; // +31 右下方
   if ( k < iMax ) 
    if (( bStr[k] > 9 ) && ( bStr[k] < 20 ) )  {
     bStr[k] -= 10 ;
     if (bStr[k] == 0) verifPos( k ) ;
       }

   k = j + 1 ;   // +1 右方
   if ( k < iMax ) 
    if (( bStr[k] > 9 ) && ( bStr[k] < 20 ) )  {
     bStr[k] -= 10 ;
     if (bStr[k] == 0) verifPos( k ) ;
       }
  }

  }

  public boolean testCase(int j) {
  int iE = j % m_col ;
  int i = 0 ;
  int k ;

  if (iE > 0) {  
   k = j - m_col - 1 ;   // -31
   if ( k >= 0 ) 
    if ( bStr[k] > 19 ) i++ ;
   k = j - 1 ;  // -1
   if ( k >= 0 ) 
    if ( bStr[k] > 19 ) i++ ;
   k = j + m_col - 1 ;  // +29
   if ( k < iMax ) 
    if ( bStr[k] > 19 ) i++ ;
  }

  k = j - m_col ;
  if ( k >= 0 ) 
    if ( bStr[k] > 19 ) i++ ;
  
  k = j + m_col ;
  if ( k < iMax ) 
    if ( bStr[k] > 19 ) i++ ;

  if (iE < (m_col-1) ) {
   k = j - m_col + 1 ;  // -29
   if ( k >= 0 ) 
    if ( bStr[k] > 19 ) i++ ;
   k = j + m_col + 1 ;  // +31
   if ( k < iMax ) 
    if ( bStr[k] > 19 ) i++ ;
   k = j + 1 ;   // +1
   if ( k < iMax ) 
    if ( bStr[k] > 19 ) i++ ;
  }

  if (i == bStr[j])  {
   verifPos(j) ;
   return true ;
  }
  else
   return false ;

  }

 

  //重画函数
  //----------------------------------------------------------------------
  public void paint (Graphics g) {
  update(g);
  } // end of paint
  //----------------------------------------------------------------------



  //----------------------------------------------------------------------
  public synchronized void update(Graphics g) {
  if (offScreen!=null) {
   paintApplet(offScreen);
   g.drawImage(buffer,0,0,this);
  } else
   paintApplet(g);
  }

  //----------------------------------------------------------------------


  //----------------------------------------------------------------------
  public void paintApplet(Graphics g) {

   int i = 0 ;
   int j = 0 ;
   int a = 0 ;
   int k = 0 ;

   g.setColor( new Color(m_bgcolor) );
   g.fillRect(0, 0, aWidth, aHeight) ;

   for (i = 0 ; i < m_ligne; i++) {
      for (j = 0 ; j < m_col; j++) {
    a = bStr[(i*m_col)+j] ;
    if ( (iEtat == 0) && (a == 9) ) iEtat = 1 ;
    if (iEtat == 1) {
     if (a == 19) a = 9 ;
     if ((a > 19) && (a != 29) ) {
      iEtat = 1 ;
      a = 41 ;
     }
    }
     
    if (a > 40) a = 12 ; else
    if (a > 19) a = 11 ; else
    if (a > 9) { a = 10 ; k++; }

    if (img[a] != null)
    g.drawImage(img[a], iX+(j*15), iPas + (i*15) , this) ;
   }
   }


   long thisTick ;

  // calculate the tick to wait for
   if (startTick != -1)
  thisTick = (System.currentTimeMillis() - startTick ) / 1000;
   else
  thisTick = 0 ;

   g.setColor( new Color(0) );
   g.fill3DRect(iPas,
         iPas/4,
       iPas,
       iPas/2,
       true ) ;

   g.fill3DRect(aWidth-iPas-iPas,
         iPas/4,
       iPas,
       iPas/2,
       true ) ;

   g.setFont( wFont );
   g.setColor( Color.green );

   g.drawString (" " + iCpt, iPas+5, iPas*2/3 ) ;
   g.drawString (" " + thisTick, aWidth-iPas-iPas+5, iPas*2/3 ) ;
   g.setColor( Color.black );
   if (k == 0) {
    iEtat = 1 ;
    g.drawString (" " + iCpt, iPas+5, (iPas*2/3) ) ;
    g.drawString ("Win", (aWidth/2)-5, (iPas*2/3) ) ;
   }
   else
    if (iEtat == 1)
    g.drawString ("Lose", (aWidth/2)-5, (iPas*2/3) ) ;
    else {
    g.setColor( new Color(0xC0C0C0) );
    g.fill3DRect( (aWidth / 2)-20, iPas/4, 40, iPas/2, true) ;
    g.setColor( new Color(0) );
    g.drawString ("?", (aWidth/2)-3, (iPas*2/3) ) ;
    }


  }

}

 

原创粉丝点击