当前位置: 代码迷 >> Android >> 探雷4Android(附源码)
  详细解决方案

探雷4Android(附源码)

热度:32   发布时间:2016-05-01 16:53:50.0
扫雷4Android(附源码)

扫雷4Android(附源码)

  最近由于项目需要学习了一下Android ,感觉汗不错。做了一个Android版的扫雷游戏。

游戏简介

 在此游戏中,我们使用一个块的网格,其中有一些随机的地雷

下面是效果图

?

一、应用程序布局

使用TableLayout布局控件。设置3行。

<?xml version="1.0" encoding="utf-8"?><TableLayout  xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:background="@drawable/back">    <TableRow>  <TextView android:id="@+id/timer" android:layout_column="0"   android:layout_width="fill_parent" android:layout_height="48px"   android:gravity="center_horizontal" android:padding="5dip"   android:textColor="#FFFFFF" android:textSize="35sp"      android:text=" 0" />  <ImageButton android:id="@+id/smiley"   android:layout_column="1" android:scaleType="center" android:padding="5dip"   android:layout_width="48px" android:background="@drawable/smiley_button_states"   android:layout_height="48px" />  <TextView android:id="@+id/minecount" android:layout_column="2"   android:layout_width="fill_parent" android:layout_height="48px"   android:gravity="center_horizontal" android:padding="5dip"   android:textColor="#FFFFFF" android:textSize="35sp" android:text="000" /> </TableRow>  <TableRow>  <TextView android:layout_column="0" android:layout_height="50px"   android:layout_width="fill_parent" android:layout_span="3"   android:padding="10dip" /> </TableRow>  <TableRow>  <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"   android:id="@+id/minefield" android:layout_width="260px"   android:layout_height="260px" android:gravity="bottom"   android:stretchColumns="*" android:layout_span="3" android:padding="5dip">  </TableLayout> </TableRow></TableLayout>

?

二、地雷块

Block.java

/** * 地雷的块,继承自Button * @author 记忆的永恒 * */public class Block extends Button { private boolean isCovered; // 块是否覆盖 private boolean isMined; // 下个块 private boolean isFlagged; // 是否将该块标记为一个潜在的地雷 private boolean isQuestionMarked; // 是否是块的问题标记 private boolean isClickable; // 是否可以单击 private int numberOfMinesInSurrounding; // 在附近的地雷数量块 public Block(Context context) {  super(context);  // TODO Auto-generated constructor stub } public Block(Context context, AttributeSet attrs) {  super(context, attrs);  // TODO Auto-generated constructor stub }  public Block(Context context, AttributeSet attrs, int defStyle)     {      super(context, attrs, defStyle);     } /**  * 设置默认参数  */ public void setDefaults() {  isCovered = true;  isMined = false;  isFlagged = false;  isQuestionMarked = false;  isClickable = true;  numberOfMinesInSurrounding = 0;    this.setBackgroundResource(R.drawable.square_blue);  setBoldFont(); } public void setNumberOfSurroundingMines(int number) {  this.setBackgroundResource(R.drawable.square_grey);  updateNumber(number); } public void setMineIcon(boolean enabled) {  this.setText("M");  if (!enabled) {   this.setBackgroundResource(R.drawable.square_grey);   this.setTextColor(Color.RED);  }  else {   this.setTextColor(Color.BLACK);  } } public void setFlagIcon(boolean enabled) {  this.setText("F");  if (!enabled) {   this.setBackgroundResource(R.drawable.square_grey);   this.setTextColor(Color.RED);  }  else {   this.setTextColor(Color.BLACK);  } } public void setQuestionMarkIcon(boolean enabled) {  this.setText("?");  if (!enabled) {   this.setBackgroundResource(R.drawable.square_grey);   this.setTextColor(Color.RED);  }  else {   this.setTextColor(Color.BLACK);  } } public void setBlockAsDisabled(boolean enabled) {  if (!enabled) {   this.setBackgroundResource(R.drawable.square_grey);  }  else {   this.setTextColor(R.drawable.square_blue);  } } public void clearAllIcons() {  this.setText(""); } private void setBoldFont() {  this.setTypeface(null, Typeface.BOLD); } public void OpenBlock() {  if (!isCovered) {   return;  }  setBlockAsDisabled(false);  isCovered = false;  if (hasMine()) {   setMineIcon(false);  }  else {   setNumberOfSurroundingMines(numberOfMinesInSurrounding);  } } public void updateNumber(int text) {  if (text != 0) {   this.setText(Integer.toString(text));   switch (text) {   case 1:    this.setTextColor(Color.BLUE);    break;   case 2:    this.setTextColor(Color.rgb(0, 100, 0));    break;   case 3:    this.setTextColor(Color.RED);    break;   case 4:    this.setTextColor(Color.rgb(85, 26, 139));    break;   case 5:    this.setTextColor(Color.rgb(139, 28, 98));    break;   case 6:    this.setTextColor(Color.rgb(238, 173, 14));    break;   case 7:    this.setTextColor(Color.rgb(47, 79, 79));    break;   case 8:    this.setTextColor(Color.rgb(71, 71, 71));    break;   case 9:    this.setTextColor(Color.rgb(205, 205, 0));    break;   }  } } public void plantMine() {  isMined = true; } public void triggerMine() {  setMineIcon(true);  this.setTextColor(Color.RED); } public boolean isCovered() {  return isCovered; } public boolean hasMine() {  return isMined; } public void setNumberOfMinesInSurrounding(int number) {  numberOfMinesInSurrounding = number; } public int getNumberOfMinesInSorrounding() {  return numberOfMinesInSurrounding; } public boolean isFlagged() {  return isFlagged; } public void setFlagged(boolean flagged) {  isFlagged = flagged; } public boolean isQuestionMarked() {  return isQuestionMarked; } public void setQuestionMarked(boolean questionMarked) {  isQuestionMarked = questionMarked; } public boolean isClickable() {  return isClickable; } public void setClickable(boolean clickable) {  isClickable = clickable; }} 三、主界面1.TableLayout动态添加行 mineField = (TableLayout)findViewById(R.id.MineField);private void showMineField(){  for (int row = 1; row < numberOfRowsInMineField + 1; row++)  {    TableRow tableRow = new TableRow(this);      tableRow.setLayoutParams(new LayoutParams((blockDimension + 2 * blockPadding) *         numberOfColumnsInMineField, blockDimension + 2 * blockPadding));    for (int column = 1; column < numberOfColumnsInMineField + 1; column++)    {      blocks[row][column].setLayoutParams(new LayoutParams(            blockDimension + 2 * blockPadding,            blockDimension + 2 * blockPadding));       blocks[row][column].setPadding(blockPadding, blockPadding, blockPadding, blockPadding);      tableRow.addView(blocks[row][column]);    }    mineField.addView(tableRow,new TableLayout.LayoutParams(          (blockDimension + 2 * blockPadding) * numberOfColumnsInMineField, blockDimension + 2 * blockPadding));    }}

?

2.定时器Handler

private Handler timer = new Handler();private int secondsPassed = 0;public void startTimer(){ if (secondsPassed == 0)   {    timer.removeCallbacks(updateTimeElasped);    // tell timer to run call back after 1 second    timer.postDelayed(updateTimeElasped, 1000);  }}public void stopTimer(){  // disable call backs  timer.removeCallbacks(updateTimeElasped);}// timer call back when timer is tickedprivate Runnable updateTimeElasped = new Runnable(){  public void run()  {    long currentMilliseconds = System.currentTimeMillis();    ++secondsPassed;    txtTimer.setText(Integer.toString(secondsPassed));    // add notification    timer.postAtTime(this, currentMilliseconds);    // notify to call back after 1 seconds    // basically to remain in the timer loop    timer.postDelayed(updateTimeElasped, 1000);  }};3.第一次点击private boolean isTimerStarted; // check if timer already started or notblocks[row][column].setOnClickListener(new OnClickListener(){  @Override  public void onClick(View view)  {    // start timer on first click    if (!isTimerStarted)    {      startTimer();      isTimerStarted = true;    }    ...  }});

?

4.第一次点击无雷

private boolean areMinesSet; // check if mines are planted in blocksblocks[row][column].setOnClickListener(new OnClickListener(){  @Override  public void onClick(View view)  {    ...    // set mines on first click    if (!areMinesSet)    {      areMinesSet = true;      setMines(currentRow, currentColumn);    }  }});private void setMines(int currentRow, int currentColumn){  // set mines excluding the location where user clicked  Random rand = new Random();  int mineRow, mineColumn;  for (int row = 0; row < totalNumberOfMines; row++)  {    mineRow = rand.nextInt(numberOfColumnsInMineField);    mineColumn = rand.nextInt(numberOfRowsInMineField);    if ((mineRow + 1 != currentColumn) || (mineColumn + 1 != currentRow))    {      if (blocks[mineColumn + 1][mineRow + 1].hasMine())      {        row--; // mine is already there, don't repeat for same block      }      // plant mine at this location      blocks[mineColumn + 1][mineRow + 1].plantMine();    }    // exclude the user clicked location    else    {      row--;    }  }  int nearByMineCount;  // count number of mines in surrounding blocks   ...}

?

5.点击雷块的效果

private void rippleUncover(int rowClicked, int columnClicked){  // don't open flagged or mined rows  if (blocks[rowClicked][columnClicked].hasMine() || blocks[rowClicked][columnClicked].isFlagged())  {    return;  }  // open clicked block  blocks[rowClicked][columnClicked].OpenBlock();  // if clicked block have nearby mines then don't open further  if (blocks[rowClicked][columnClicked].getNumberOfMinesInSorrounding() != 0 )  {    return;  }  // open next 3 rows and 3 columns recursively  for (int row = 0; row < 3; row++)  {    for (int column = 0; column < 3; column++)    {      // check all the above checked conditions      // if met then open subsequent blocks      if (blocks[rowClicked + row - 1][columnClicked + column - 1].isCovered()          && (rowClicked + row - 1 > 0) && (columnClicked + column - 1 > 0)          && (rowClicked + row - 1 < numberOfRowsInMineField + 1)           && (columnClicked + column - 1 < numberOfColumnsInMineField + 1))      {        rippleUncover(rowClicked + row - 1, columnClicked + column - 1 );      }     }  }  return;}

?

6.以问好标记空白

blocks[row][column].setOnLongClickListener(new OnLongClickListener(){  public boolean onLongClick(View view)  {    // simulate a left-right (middle) click    // if it is a long click on an opened mine then    // open all surrounding blocks    ...    // if clicked block is enabled, clickable or flagged    if (blocks[currentRow][currentColumn].isClickable() &&         (blocks[currentRow][currentColumn].isEnabled() || blocks[currentRow][currentColumn].isFlagged()))    {      // for long clicks set:      // 1. empty blocks to flagged      // 2. flagged to question mark      // 3. question mark to blank      // case 1. set blank block to flagged      if (!blocks[currentRow][currentColumn].isFlagged() && !blocks[currentRow][currentColumn].isQuestionMarked())      {        blocks[currentRow][currentColumn].setBlockAsDisabled(false);        blocks[currentRow][currentColumn].setFlagIcon(true);        blocks[currentRow][currentColumn].setFlagged(true);        minesToFind--; //reduce mine count        updateMineCountDisplay();      }      // case 2. set flagged to question mark      else if (!blocks[currentRow][currentColumn].isQuestionMarked())      {        blocks[currentRow][currentColumn].setBlockAsDisabled(true);        blocks[currentRow][currentColumn].setQuestionMarkIcon(true);        blocks[currentRow][currentColumn].setFlagged(false);        blocks[currentRow][currentColumn].setQuestionMarked(true);        minesToFind++; // increase mine count        updateMineCountDisplay();      }      // case 3. change to blank square      else      {        blocks[currentRow][currentColumn].setBlockAsDisabled(true);        blocks[currentRow][currentColumn].clearAllIcons();        blocks[currentRow][currentColumn].setQuestionMarked(false);        // if it is flagged then increment mine count        if (blocks[currentRow][currentColumn].isFlagged())        {          minesToFind++; // increase mine count          updateMineCountDisplay();        }        // remove flagged status        blocks[currentRow][currentColumn].setFlagged(false);      }            updateMineCountDisplay(); // update mine display    }    return true;  }});

?

7.记录胜负

// check status of the game at each stepif (blocks[currentRow + previousRow][currentColumn + previousColumn].hasMine()){  // oops game over  finishGame(currentRow + previousRow, currentColumn + previousColumn);}// did we win the gameif (checkGameWin()){  // mark game as win  winGame();}private boolean checkGameWin(){  for (int row = 1; row < numberOfRowsInMineField + 1; row++)  {    for (int column = 1; column < numberOfColumnsInMineField + 1; column++)    {      if (!blocks[row][column].hasMine() && blocks[row][column].isCovered())      {        return false;      }    }  }  return true;}

??

8.完整代码

?

MinesweeperGame.javapackage com.VertexVerveInc.Games;import java.util.Random;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.util.Log;import android.view.Gravity;import android.view.View;import android.view.View.OnClickListener;import android.view.View.OnLongClickListener;import android.widget.ImageButton;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.TableLayout;import android.widget.TableRow;import android.widget.TextView;import android.widget.Toast;import android.widget.TableRow.LayoutParams;public class MinesweeperGame extends Activity { private TextView txtMineCount; private TextView txtTimer; private ImageButton btnSmile; private TableLayout mineField; private Block blocks[][]; // blocks for mine field private int blockDimension = 24; // width of each block private int blockPadding = 2; // padding between blocks private int numberOfRowsInMineField = 9; private int numberOfColumnsInMineField = 9; private int totalNumberOfMines = 10; // timer to keep track of time elapsed private Handler timer = new Handler(); private int secondsPassed = 0; private boolean isTimerStarted; // check if timer already started or not private boolean areMinesSet; // check if mines are planted in blocks private boolean isGameOver; private int minesToFind; // number of mines yet to be discovered /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.test);    txtMineCount = (TextView) findViewById(R.id.minecount);       txtTimer = (TextView) findViewById(R.id.timer);           btnSmile = (ImageButton) findViewById(R.id.smiley);       btnSmile.setOnClickListener(new OnClickListener()       {        @Override        public void onClick(View view)        {         endExistingGame();         startNewGame();        }       });              mineField = (TableLayout)findViewById(R.id.minefield);              showDialog("Click smiley to start New Game", 2000, true, false);        } private void startNewGame() {  createMineField();  // display all blocks in UI  showMineField();  minesToFind = totalNumberOfMines;  isGameOver = false;  secondsPassed = 0; } private void createMineField() {  // we take one row extra row for each side  // overall two extra rows and two extra columns  // first and last row/column are used for calculations purposes only  // x|xxxxxxxxxxxxxx|x  // ------------------  // x| |x  // x| |x  // ------------------  // x|xxxxxxxxxxxxxx|x  // the row and columns marked as x are just used to keep counts of near  // by mines  blocks = new Block[numberOfRowsInMineField + 2][numberOfColumnsInMineField + 2];  for (int row = 0; row < numberOfColumnsInMineField + 2; row++) {   for (int column = 0; column < numberOfColumnsInMineField + 2; column++) {    blocks[row][column] = new Block(this);    blocks[row][column].setDefaults();    // pass current row and column number as final int's to event    // listeners    // this way we can ensure that each event listener is associated    // to    // particular instance of block only    final int currentRow = row;    final int currentColumn = column;    blocks[row][column].setOnClickListener(new OnClickListener() {     @Override     public void onClick(View v) {      // start timer on first click      if (!isTimerStarted) {       startTimer();       isTimerStarted = true;      }      // set mines on first click      if (!areMinesSet) {       areMinesSet = true;       setMines(currentRow, currentColumn);      }      // this is not first click      // check if current block is flagged      // if flagged the don't do anything      // as that operation is handled by LongClick      // if block is not flagged then uncover nearby blocks      // till we get numbered mines      if (!blocks[currentRow][currentColumn].isFlagged()) {       // open nearby blocks till we get numbered blocks       rippleUncover(currentRow, currentColumn);       // did we clicked a mine       if (blocks[currentRow][currentColumn].hasMine()) {        // Oops, game over        finishGame(currentRow, currentColumn);       }       // check if we win the game       if (checkGameWin()) {        // mark game as win        winGame();       }      }     }    });    // add Long Click listener    // this is treated as right mouse click listener    blocks[row][column]      .setOnLongClickListener(new OnLongClickListener() {       public boolean onLongClick(View view) {        // simulate a left-right (middle) click        // if it is a long click on an opened mine then        // open all surrounding blocks        if (!blocks[currentRow][currentColumn]          .isCovered()          && (blocks[currentRow][currentColumn]            .getNumberOfMinesInSorrounding() > 0)          && !isGameOver) {         int nearbyFlaggedBlocks = 0;         for (int previousRow = -1; previousRow < 2; previousRow++) {          for (int previousColumn = -1; previousColumn < 2; previousColumn++) {           if (blocks[currentRow + previousRow][currentColumn             + previousColumn]             .isFlagged()) {            nearbyFlaggedBlocks++;           }          }         }         // if flagged block count is equal to nearby         // mine count         // then open nearby blocks         if (nearbyFlaggedBlocks == blocks[currentRow][currentColumn]           .getNumberOfMinesInSorrounding()) {          for (int previousRow = -1; previousRow < 2; previousRow++) {           for (int previousColumn = -1; previousColumn < 2; previousColumn++) {            // don't open flagged blocks            if (!blocks[currentRow              + previousRow][currentColumn              + previousColumn]              .isFlagged()) {             // open blocks till we get             // numbered block             rippleUncover(               currentRow                 + previousRow,               currentColumn                 + previousColumn);             // did we clicked a mine             if (blocks[currentRow               + previousRow][currentColumn               + previousColumn]               .hasMine()) {              // oops game over              finishGame(                currentRow                  + previousRow,                currentColumn                  + previousColumn);             }             // did we win the game             if (checkGameWin()) {              // mark game as win              winGame();             }            }           }          }         }         // as we no longer want to judge this         // gesture so return         // not returning from here will actually         // trigger other action         // which can be marking as a flag or         // question mark or blank         return true;        }        // if clicked block is enabled, clickable or        // flagged        if (blocks[currentRow][currentColumn]          .isClickable()          && (blocks[currentRow][currentColumn]            .isEnabled() || blocks[currentRow][currentColumn]            .isFlagged())) {         // for long clicks set:         // 1. empty blocks to flagged         // 2. flagged to question mark         // 3. question mark to blank         // case 1. set blank block to flagged         if (!blocks[currentRow][currentColumn]           .isFlagged()           && !blocks[currentRow][currentColumn]             .isQuestionMarked()) {          blocks[currentRow][currentColumn]            .setBlockAsDisabled(false);          blocks[currentRow][currentColumn]            .setFlagIcon(true);          blocks[currentRow][currentColumn]            .setFlagged(true);          minesToFind--; // reduce mine count          updateMineCountDisplay();         }         // case 2. set flagged to question mark         else if (!blocks[currentRow][currentColumn]           .isQuestionMarked()) {          blocks[currentRow][currentColumn]            .setBlockAsDisabled(true);          blocks[currentRow][currentColumn]            .setQuestionMarkIcon(true);          blocks[currentRow][currentColumn]            .setFlagged(false);          blocks[currentRow][currentColumn]            .setQuestionMarked(true);          minesToFind++; // increase mine count          updateMineCountDisplay();         }         // case 3. change to blank square         else {          blocks[currentRow][currentColumn]            .setBlockAsDisabled(true);          blocks[currentRow][currentColumn]            .clearAllIcons();          blocks[currentRow][currentColumn]            .setQuestionMarked(false);          // if it is flagged then increment mine          // count          if (blocks[currentRow][currentColumn]            .isFlagged()) {           minesToFind++; // increase mine           // count           updateMineCountDisplay();          }          // remove flagged status          blocks[currentRow][currentColumn]            .setFlagged(false);         }         updateMineCountDisplay();          // update mine         // display        }        return true;       }      });   }  } } private void showMineField() {  for (int row = 1; row < numberOfRowsInMineField + 1; row++) {   TableRow tableRow = new TableRow(this);   tableRow.setLayoutParams(new LayoutParams(     (blockDimension + 2 * blockPadding)       * numberOfColumnsInMineField, blockDimension + 2       * blockPadding));   for (int column = 1; column < numberOfColumnsInMineField + 1; column++) {    blocks[row][column].setLayoutParams(new LayoutParams(      blockDimension + 2 * blockPadding, blockDimension + 2        * blockPadding));    blocks[row][column].setPadding(blockPadding, blockPadding,      blockPadding, blockPadding);    tableRow.addView(blocks[row][column]);   }   mineField.addView(tableRow, new TableLayout.LayoutParams(     (blockDimension + 2 * blockPadding)       * numberOfColumnsInMineField, blockDimension + 2       * blockPadding));  } } private void endExistingGame() {  stopTimer(); // stop if timer is running  txtTimer.setText("000"); // revert all text  txtMineCount.setText("000"); // revert mines count  btnSmile.setBackgroundResource(R.drawable.smile);  // remove all rows from mineField TableLayout  mineField.removeAllViews();  // set all variables to support end of game  isTimerStarted = false;  areMinesSet = false;  isGameOver = false;  minesToFind = 0; } private boolean checkGameWin() {  for (int row = 1; row < numberOfRowsInMineField + 1; row++) {   for (int column = 1; column < numberOfColumnsInMineField + 1; column++) {    if (!blocks[row][column].hasMine()      && blocks[row][column].isCovered()) {     return false;    }   }  }  return true; } private void updateMineCountDisplay() {  if (minesToFind < 0) {   txtMineCount.setText(Integer.toString(minesToFind));  } else if (minesToFind < 10) {   txtMineCount.setText("00" + Integer.toString(minesToFind));  } else if (minesToFind < 100) {   txtMineCount.setText("0" + Integer.toString(minesToFind));  } else {   txtMineCount.setText(Integer.toString(minesToFind));  } } private void winGame() {  stopTimer();  isTimerStarted = false;  isGameOver = true;  minesToFind = 0; // set mine count to 0  // set icon to cool dude  btnSmile.setBackgroundResource(R.drawable.cool);  updateMineCountDisplay(); // update mine count  // disable all buttons  // set flagged all un-flagged blocks  for (int row = 1; row < numberOfRowsInMineField + 1; row++) {   for (int column = 1; column < numberOfColumnsInMineField + 1; column++) {    blocks[row][column].setClickable(false);    if (blocks[row][column].hasMine()) {     blocks[row][column].setBlockAsDisabled(false);     blocks[row][column].setFlagIcon(true);    }   }  }  // show message  showDialog("You won in " + Integer.toString(secondsPassed)    + " seconds!", 1000, false, true); } private void finishGame(int currentRow, int currentColumn) {  isGameOver = true; // mark game as over  stopTimer(); // stop timer  isTimerStarted = false;  btnSmile.setBackgroundResource(R.drawable.sad);  // show all mines  // disable all blocks  for (int row = 1; row < numberOfRowsInMineField + 1; row++) {   for (int column = 1; column < numberOfColumnsInMineField + 1; column++) {    // disable block    blocks[row][column].setBlockAsDisabled(false);    // block has mine and is not flagged    if (blocks[row][column].hasMine()      && !blocks[row][column].isFlagged()) {     // set mine icon     blocks[row][column].setMineIcon(false);    }    // block is flagged and doesn't not have mine    if (!blocks[row][column].hasMine()      && blocks[row][column].isFlagged()) {     // set flag icon     blocks[row][column].setFlagIcon(false);    }    // block is flagged    if (blocks[row][column].isFlagged()) {     // disable the block     blocks[row][column].setClickable(false);    }   }  }  // trigger mine  blocks[currentRow][currentColumn].triggerMine();  // show message  showDialog("You tried for " + Integer.toString(secondsPassed)    + " seconds!", 1000, false, false); } private void setMines(int currentRow, int currentColumn) {  // set mines excluding the location where user clicked  Random rand = new Random();  int mineRow, mineColumn;  for (int row = 0; row < totalNumberOfMines; row++) {   mineRow = rand.nextInt(numberOfColumnsInMineField);   mineColumn = rand.nextInt(numberOfRowsInMineField);   if ((mineRow + 1 != currentColumn)     || (mineColumn + 1 != currentRow)) {    if (blocks[mineColumn + 1][mineRow + 1].hasMine()) {     row--; // mine is already there, don't repeat for same block    }    // plant mine at this location    blocks[mineColumn + 1][mineRow + 1].plantMine();   }   // exclude the user clicked location   else {    row--;   }  }  int nearByMineCount;  for (int row = 0; row < numberOfRowsInMineField + 2; row++) {   for (int column = 0; column < numberOfColumnsInMineField + 2; column++) {    // for each block find nearby mine count    nearByMineCount = 0;    if ((row != 0) && (row != (numberOfRowsInMineField + 1))      && (column != 0)      && (column != (numberOfColumnsInMineField + 1))) {     // check in all nearby blocks     for (int previousRow = -1; previousRow < 2; previousRow++) {      for (int previousColumn = -1; previousColumn < 2; previousColumn++) {       if (blocks[row + previousRow][column         + previousColumn].hasMine()) {        // a mine was found so increment the counter        nearByMineCount++;       }      }     }     blocks[row][column]       .setNumberOfMinesInSurrounding(nearByMineCount);    }    // for side rows (0th and last row/column)    // set count as 9 and mark it as opened    else {     blocks[row][column].setNumberOfMinesInSurrounding(9);     blocks[row][column].OpenBlock();    }   }  } } private void rippleUncover(int rowClicked, int columnClicked) {  // don't open flagged or mined rows  if (blocks[rowClicked][columnClicked].hasMine()    || blocks[rowClicked][columnClicked].isFlagged()) {   return;  }  // open clicked block  blocks[rowClicked][columnClicked].OpenBlock();  // if clicked block have nearby mines then don't open further  if (blocks[rowClicked][columnClicked].getNumberOfMinesInSorrounding() != 0) {   return;  }  // open next 3 rows and 3 columns recursively  for (int row = 0; row < 3; row++) {   for (int column = 0; column < 3; column++) {    // check all the above checked conditions    // if met then open subsequent blocks    if (blocks[rowClicked + row - 1][columnClicked + column - 1]      .isCovered()      && (rowClicked + row - 1 > 0)      && (columnClicked + column - 1 > 0)      && (rowClicked + row - 1 < numberOfRowsInMineField + 1)      && (columnClicked + column - 1 < numberOfColumnsInMineField + 1)) {     rippleUncover(rowClicked + row - 1, columnClicked + column       - 1);    }   }  }  return; } public void startTimer() {  if (secondsPassed == 0) {   timer.removeCallbacks(updateTimeElasped);   // tell timer to run call back after 1 second   timer.postDelayed(updateTimeElasped, 1000);   Log.i("tag",String.valueOf((timer.postDelayed(updateTimeElasped, 1000))) );  } } public void stopTimer() {  // disable call backs  timer.removeCallbacks(updateTimeElasped); } // timer call back when timer is ticked private Runnable updateTimeElasped = new Runnable() {  public void run() {   long currentMilliseconds = System.currentTimeMillis();   ++secondsPassed;   txtTimer.setText(Integer.toString(secondsPassed));   // add notification   timer.postAtTime(this, currentMilliseconds);   // notify to call back after 1 seconds   // basically to remain in the timer loop   timer.postDelayed(updateTimeElasped, 1000);  } }; private void showDialog(String message, int milliseconds,   boolean useSmileImage, boolean useCoolImage) {  // show message  Toast dialog = Toast.makeText(getApplicationContext(), message,    Toast.LENGTH_LONG);  dialog.setGravity(Gravity.CENTER, 0, 0);  LinearLayout dialogView = (LinearLayout) dialog.getView();  ImageView coolImage = new ImageView(getApplicationContext());  if (useSmileImage) {   coolImage.setImageResource(R.drawable.smile);  } else if (useCoolImage) {   coolImage.setImageResource(R.drawable.cool);  } else {   coolImage.setImageResource(R.drawable.sad);  }  dialogView.addView(coolImage, 0);  dialog.setDuration(milliseconds);  dialog.show();  Log.i("tag", "showDialog()"); }} 

?

源码下载

  相关解决方案