Android扫雷游戏源码分析

合集下载

Android扫雷游戏源码分析

Android扫雷游戏源码分析

第1章游戏源码1.1 MinesweeperGamepackage com.VertexVerveInc.Games;import java.util.Random;import android.app.Activity;import android.graphics.Typeface;import android.os.Bundle;import android.os.Handler;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 youtParams;import android.widget.TableLayout;import android.widget.TableRow;import android.widget.TextView;import android.widget.Toast;public class MinesweeperGame extends Activity{private TextView txtMineCount;private TextView txtTimer;private ImageButton btnSmile;private TableLayout mineField; // table layout to add mines toprivate Block blocks[][]; // blocks for mine fieldprivate int blockDimension = 24; // width of each blockprivate int blockPadding = 2; // padding between blocksprivate int numberOfRowsInMineField = 9;private int numberOfColumnsInMineField = 9;private int totalNumberOfMines = 10;// timer to keep track of time elapsedprivate 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@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(yout.main);txtMineCount = (TextView) findViewById(R.id.MineCount);txtTimer = (TextView) findViewById(R.id.Timer);// set font style for timer and mine count to LCD styleTypeface lcdFont = Typeface.createFromAsset(getAssets(),"fonts/lcd2mono.ttf");txtMineCount.setTypeface(lcdFont);txtTimer.setTypeface(lcdFont);btnSmile = (ImageButton) findViewById(R.id.Smiley);btnSmile.setOnClickListener(new OnClickListener(){@Overridepublic 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(){// plant mines and do rest of the calculationscreateMineField();// display all blocks in UIshowMineField();minesToFind = totalNumberOfMines;isGameOver = false;secondsPassed = 0;}private void showMineField(){// remember we will not show 0th and last Row and Columns// they are used for calculation purposes onlyfor (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 youtParams((blockDimension + 2 * blockPadding) * numberOfColumnsInMineField, blockDimension + 2 * blockPadding));}}private void endExistingGame(){stopTimer(); // stop if timer is runningtxtTimer.setText("000"); // revert all texttxtMineCount.setText("000"); // revert mines countbtnSmile.setBackgroundResource(R.drawable.smile);// remove all rows from mineField TableLayoutmineField.removeAllViews();// set all variables to support end of gameisTimerStarted = false;areMinesSet = false;isGameOver = false;minesToFind = 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 < numberOfRowsInMineField + 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 onlyfinal int currentRow = row;final int currentColumn = column;// add Click Listener// this is treated as Left Mouse clickblocks[row][column].setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View view){// start timer on first clickif (!isTimerStarted){startTimer();isTimerStarted = true;}// set mines on first clickif (!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 minesif (!blocks[currentRow][currentColumn].isFlagged()){// open nearby blocks till we get numbered blocksrippleUncover(currentRow, currentColumn);// did we clicked a mineif (blocks[currentRow][currentColumn].hasMine()){// Oops, game overfinishGame(currentRow,currentColumn);// check if we win the gameif (checkGameWin()){// mark game as winwinGame();}}}});// add Long Click listener// this is treated as right mouse click listenerblocks[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 blocksif (!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 blocksif (nearbyFlaggedBlocks == blocks[currentRow][currentColumn].getNumberOfMinesInSorrounding()) {for (int previousRow = -1; previousRow < 2; previousRow++){for (int previousColumn = -1; previousColumn < 2; previousColumn++){// don't open flagged blocksif (!blocks[currentRow + previousRow][currentColumn + previousColumn].isFlagged()){// open blocks till we get numbered blockrippleUncover(currentRow + previousRow, currentColumn + previousColumn);// did we clicked a mineif (blocks[currentRow + previousRow][currentColumn + previousColumn].hasMine()){// oops game overfinishGame(currentRow + previousRow, currentColumn + previousColumn);}// did we win the gameif (checkGameWin()){// mark game as winwinGame();}}}}}// 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 blankreturn true;}// if clicked block is enabled, clickable or flaggedif (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 flaggedif (!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 countupdateMineCountDisplay();}// case 2. set flagged to question markelse 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 countupdateMineCountDisplay();}// case 3. change to blank squareelse{blocks[currentRow][currentColumn].setBlockAsDisabled(true);blocks[currentRow][currentColumn].clearAllIcons();blocks[currentRow][currentColumn].setQuestionMarked(false);// if it is flagged then increment mine countif (blocks[currentRow][currentColumn].isFlagged()){minesToFind++; // increase mine countupdateMineCountDisplay();}// remove flagged statusblocks[currentRow][currentColumn].setFlagged(false);}updateMineCountDisplay(); // update mine display}return true;}});}}}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 dudebtnSmile.setBackgroundResource(R.drawable.cool); updateMineCountDisplay(); // update mine count// disable all buttons// set flagged all un-flagged blocksfor (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 messageshowDialog("You won in " + Integer.toString(secondsPassed) + " seconds!", 1000, false, true);}private void finishGame(int currentRow, int currentColumn){isGameOver = true; // mark game as overstopTimer(); // stop timerisTimerStarted = false;btnSmile.setBackgroundResource(R.drawable.sad);// show all mines// disable all blocksfor (int row = 1; row < numberOfRowsInMineField + 1; row++){for (int column = 1; column < numberOfColumnsInMineField + 1; column++){// disable blockblocks[row][column].setBlockAsDisabled(false);// block has mine and is not flaggedif (blocks[row][column].hasMine() && !blocks[row][column].isFlagged()){// set mine iconblocks[row][column].setMineIcon(false);}// block is flagged and doesn't not have mineif (!blocks[row][column].hasMine() && blocks[row][column].isFlagged()){// set flag iconblocks[row][column].setFlagIcon(false);}// block is flaggedif (blocks[row][column].isFlagged()){// disable the blockblocks[row][column].setClickable(false);}}}// trigger mineblocks[currentRow][currentColumn].triggerMine();// show messageshowDialog("You tried for " + Integer.toString(secondsPassed) + " seconds!", 1000, false, false);}private void setMines(int currentRow, int currentColumn){// set mines excluding the location where user clickedRandom 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 locationblocks[mineColumn + 1][mineRow + 1].plantMine();}// exclude the user clicked locationelse{row--;}}int nearByMineCount;// count number of mines in surrounding blocksfor (int row = 0; row < numberOfRowsInMineField + 2; row++){for (int column = 0; column < numberOfColumnsInMineField + 2; column++){// for each block find nearby mine countnearByMineCount = 0;if ((row != 0) && (row != (numberOfRowsInMineField + 1)) && (column != 0) && (column != (numberOfColumnsInMineField + 1))){// check in all nearby blocksfor (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 counternearByMineCount++;}}}blocks[row][column].setNumberOfMinesInSurrounding(nearByMineCount);}// for side rows (0th and last row/column)// set count as 9 and mark it as openedelse{blocks[row][column].setNumberOfMinesInSurrounding(9);blocks[row][column].OpenBlock();}}}}private void rippleUncover(int rowClicked, int columnClicked){// don't open flagged or mined rowsif (blocks[rowClicked][columnClicked].hasMine() || blocks[rowClicked][columnClicked].isFlagged()){return;}// open clicked blockblocks[rowClicked][columnClicked].OpenBlock();// if clicked block have nearby mines then don't open furtherif (blocks[rowClicked][columnClicked].getNumberOfMinesInSorrounding() != 0 ) {return;}// open next 3 rows and 3 columns recursivelyfor (int row = 0; row < 3; row++){for (int column = 0; column < 3; column++){// check all the above checked conditions// if met then open subsequent blocksif (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 secondtimer.postDelayed(updateTimeElasped, 1000);}}public void stopTimer(){// disable call backstimer.removeCallbacks(updateTimeElasped);}// timer call back when timer is tickedprivate Runnable updateTimeElasped = new Runnable(){public void run(){long currentMilliseconds = System.currentTimeMillis();++secondsPassed;if (secondsPassed < 10){txtTimer.setText("00" + Integer.toString(secondsPassed));}else if (secondsPassed < 100){txtTimer.setText("0" + Integer.toString(secondsPassed));}else{txtTimer.setText(Integer.toString(secondsPassed));}// add notificationtimer.postAtTime(this, currentMilliseconds);// notify to call back after 1 seconds// basically to remain in the timer looptimer.postDelayed(updateTimeElasped, 1000);}};private void showDialog(String message, int milliseconds, boolean useSmileImage, boolean useCoolImage){// show messageToast 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();}}1.2 Blockpackage com.VertexVerveInc.Games;import android.content.Context;import android.graphics.Color;import android.graphics.Typeface;import android.util.AttributeSet;import android.widget.Button;public class Block extends Button{private boolean isCovered; // is block covered yetprivate boolean isMined; // does the block has a mine underneathprivate boolean isFlagged; // is block flagged as a potential mineprivate boolean isQuestionMarked; // is block question markedprivate boolean isClickable; // can block accept click eventsprivate int numberOfMinesInSurrounding; // number of mines in nearby blocks public Block(Context context){super(context);}public Block(Context context, AttributeSet attrs){super(context, attrs);}public Block(Context context, AttributeSet attrs, int defStyle){super(context, attrs, defStyle);}// set default properties for the blockpublic void setDefaults(){isCovered = true;isMined = false;isFlagged = false;isQuestionMarked = false;isClickable = true;numberOfMinesInSurrounding = 0;this.setBackgroundResource(R.drawable.square_blue); setBoldFont();}// mark the block as disabled/opened// update the number of nearby minespublic void setNumberOfSurroundingMines(int number) {this.setBackgroundResource(R.drawable.square_grey); updateNumber(number);}// set mine icon for block// set block as disabled/opened if false is passed 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);}}// set mine as flagged// set block as disabled/opened if false is passed 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);}}// set mine as question mark// set block as disabled/opened if false is passed public void setQuestionMarkIcon(boolean enabled) {this.setText("?");if (!enabled){this.setBackgroundResource(R.drawable.square_grey); this.setTextColor(Color.RED);}else{this.setTextColor(Color.BLACK);}}// set block as disabled/opened if false is passed // else enable/close itpublic void setBlockAsDisabled(boolean enabled) {if (!enabled){this.setBackgroundResource(R.drawable.square_grey); }else{this.setBackgroundResource(R.drawable.square_blue); }}// clear all icons/textpublic void clearAllIcons(){this.setText("");}// set font as boldprivate void setBoldFont(){this.setTypeface(null, Typeface.BOLD);}// uncover this blockpublic void OpenBlock(){// cannot uncover a mine which is not coveredif (!isCovered)return;setBlockAsDisabled(false);isCovered = false;// check if it has mineif (hasMine()){setMineIcon(false);}// update with the nearby mine countelse{setNumberOfSurroundingMines(numberOfMinesInSurrounding); }}// set text as nearby mine countpublic void updateNumber(int text){if (text != 0){this.setText(Integer.toString(text));// select different color for each number// we have already skipped 0 mine countswitch (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;}}}// set block as a mine underneathpublic void plantMine(){isMined = true;}// mine was opened// change the block icon and colorpublic void triggerMine(){setMineIcon(true);this.setTextColor(Color.RED);}// is block still coveredpublic boolean isCovered(){return isCovered;}// does the block have any mine underneathpublic boolean hasMine(){return isMined;}// set number of nearby minespublic void setNumberOfMinesInSurrounding(int number) {numberOfMinesInSurrounding = number;}// get number of nearby minespublic int getNumberOfMinesInSorrounding(){return numberOfMinesInSurrounding;}// is block marked as flaggedpublic boolean isFlagged(){return isFlagged;}// mark block as flaggedpublic void setFlagged(boolean flagged){isFlagged = flagged;}// is block marked as a question markpublic boolean isQuestionMarked(){return isQuestionMarked;}// set question mark for the blockpublic void setQuestionMarked(boolean questionMarked){isQuestionMarked = questionMarked;}// can block receive click eventpublic boolean isClickable(){return isClickable;}// disable block for receive click eventspublic void setClickable(boolean clickable){isClickable = clickable;}}第2章源码详细分析2.1 基本变量设置private TextView txtMineCount;//剩余地雷数private TextView txtTimer;//计时private ImageButton btnSmile;//新游戏按钮private TableLayout mineField; //表的布局添加地雷private Block blocks[][]; //所有的块private int blockDimension = 24; //每块的宽度private int blockPadding = 2; //块之间填充private int numberOfRowsInMineField = 9;//雷区为9行private int numberOfColumnsInMineField = 9;//雷区为9列private int totalNumberOfMines = 10;//总共有10个雷//定时器的运行时间保持跟踪private Handler timer = new Handler();private int secondsPassed = 0;private boolean isTimerStarted; //检查是否已经开始或不定时private boolean areMinesSet; //检查是否已经设置地雷private boolean isGameOver;//检查是否游戏结束private int minesToFind; //有待发现的地雷数量2.2 游戏初始化游戏的初始化函数中,要设置整个界面的背景图片和游戏开始按钮的图片,还有设置一个提示信息(当点击其它地方时弹出)。

实用文库汇编之扫雷游戏代码

实用文库汇编之扫雷游戏代码

*作者:座殿角*作品编号48877446331144215458创作日期:2020年12月20日实用文库汇编之/*block.h*/#ifndef BLOCK_H_#define BLOCK_H_#include<QLabel>class QWidget;class Block:public QLabel{Q_OBJECTpublic:explicit Block(bool mine_flag,QWidget*parent=0);void set_number(int number);void turn_over();bool is_mine()const;bool is_turn_over()const;signals:void turn_over(bool is_mine);protected:void mousePressEvent(QMouseEvent*event);private:bool mine_flag_;bool mark_flag_;bool turn_over_flag_;int number_;};#endif#include"block.h"#include<QLabel>#include<QMouseEvent>#include<QPixmap>#include<QWidget>Block::Block(bool mine_flag,QWidget*parent):QLabel(parent){mine_flag_=mine_flag;mark_flag_=false;turn_over_flag_=false;number_=-1;setPixmap(QPixmap(":/images/normal.png"));}void Block::set_number(int number){number_=number;}void Block::turn_over(){if(!turn_over_flag_){turn_over_flag_=true;if(mine_flag_)setPixmap(QPixmap(":/images/mine.png"));elsesetPixmap(QPixmap(":/images/mine_"+QString("%1").arg (number_)+".png"));update();}}bool Block::is_mine()const{return mine_flag_;}bool Block::is_turn_over()const{return turn_over_flag_;}/*鼠标事件的实现*/void Block::mousePressEvent(QMouseEvent*event){if(event->button()==Qt::LeftButton){if(!turn_over_flag_&&!mark_flag_){turn_over_flag_=true;if(mine_flag_==true){setPixmap(QPixmap(":/images/mine.png"));update();emit turn_over(true);}else{setPixmap(QPixmap(":/images/mine_"+QString("%1").arg (number_)+".png"));update();emit turn_over(false);}}}else if(event->button()==Qt::RightButton){if(!turn_over_flag_){if(!mark_flag_){mark_flag_=true;setPixmap(QPixmap(":/images/flag.png"));}else{mark_flag_=false;setPixmap(QPixmap(":/images/normal.png"));}update();}作者:座殿角作品编号48877446331144215458创作日期:2020年12月20日}QLabel::mousePressEvent(event);}#ifndef BLOCK_AREA_H_#define BLOCK_AREA_H_#include"block.h"#include<QWidget>class QEvent;class QGridLayout;class QObject;class BlockArea:public QWidget{Q_OBJECTpublic:BlockArea(int row,int column,intmine_number,QWidget*parent=0);void set_block_area(int row,int column,intmine_number,int init_flag=false);signals:void game_over(bool is_win);protected:bool eventFilter(QObject*watched,QEvent*event);private slots:void slot_turn_over(bool is_mine);private:int calculate_mines(int x,int y)const;//璁$畻浠,y涓轰腑蹇幂殑涔濆镙煎唴镄勯浄鏁voidtry_to_turn_over_more_blocks(int x,int y);private:QGridLayout*mainLayout;int row_;int column_;int total_block_number_;int total_mine_number_;int turn_over_block_number_;bool game_over_flag_;};#endif/*block_area.h*/#include"block_area.h"#include<algorithm>#include<QEvent>#include<QGridLayout>#include<QLayout>#include<QMouseEvent>#include<QObject>#include<QQueue>#include<QTime>#include<QWidget>/*雷的随机布置*/ptrdiff_t random(ptrdiff_t i){return qrand()%i;}ptrdiff_t(*p_random)(ptrdiff_t)=random; BlockArea::BlockArea(int row,int column,intmine_number,QWidget*parent):QWidget(parent){set_block_area(row,column,mine_number,true); }void BlockArea::set_block_area(int row,int column,int mine_number,int init_flag){if(!init_flag){for(int i=0;i<row_;i++)for(int j=0;j<column_;j++)deletestatic_cast<Block*>(mainLayout->itemAtPosition(i,j)->widget());delete mainLayout;}row_=row;column_=column;total_block_number_=row_*column_;total_mine_number_=mine_number;turn_over_block_number_=0;game_over_flag_=false;bool mine_flag[total_block_number_];for(int i=0;i<total_mine_number_;i++)mine_flag[i]=true;for(inti=total_mine_number_;i<total_block_number_;i++)mine_flag[i]=false;QTime time;time=QTime::currentTime();qsrand(time.msec()+time.second()*1000);std::random_shuffle(mine_flag,mine_flag+total_block_ number_,p_random);mainLayout=new QGridLayout(this);for(int i=0;i<row_;i++)for(int j=0;j<column_;j++)mainLayout->addWidget(newBlock(mine_flag[i*column_+j]),i,j);for(int i=0;i<row_;i++){for(int j=0;j<column_;j++){Block*current_block=static_cast<Block*>(mainLayout->itemAtPosition(i,j)->widget());current_block->set_number(calculate_mines(i,j));connect(current_block,SIGNAL(turn_over(bool)),this,S LOT(slot_turn_over(bool)));current_block->installEventFilter(this);作者:座殿角作品编号48877446331144215458创作日期:2020年12月20日}}}bool BlockArea::eventFilter(QObject*watched,QEvent* event){if(game_over_flag_)if(event->type()==QEvent::MouseButtonPress)return true;return QWidget::eventFilter(watched,event);}void BlockArea::slot_turn_over(bool is_mine){if(is_mine){game_over_flag_=true;emit game_over(false);}else{++turn_over_block_number_;if(turn_over_block_number_==total_block_number_-total_mine_number_){game_over_flag_=true;emit game_over(true);}else{for(int i=0;i<row_;i++)for(int j=0;j<column_;j++)if(sender()==static_cast<Block*>(mainLayout->itemAtPosition(i,j)->widget()))try_to_turn_over_more_blocks(i,j);}}}int BlockArea::calculate_mines(int x,int y)const{int number=0;for(int i=0;i<3;i++)for(int j=0;j<3;j++)if((x-1+i>=0)&&(x-1+i<row_)&&(y-1+j>=0)&&(y-1+j<column_))if(static_cast<Block*>(mainLayout->itemAtPosition(x-1+i,y-1+j)->widget())->is_mine())++number;return number;}void BlockArea::try_to_turn_over_more_blocks(int x,int y) {QQueue<QPair<int,int>>queue;QPair<int,int>pair;queue.enqueue(qMakePair(x,y));while(!queue.isEmpty()){pair=queue.head();queue.dequeue();if(calculate_mines(pair.first,pair.second)==0){for(int i=0;i<3;i++){for(int j=0;j<3;j++){if((pair.first-1+i>=0)&&(pair.first-1+i<row_)&&(pair.second-1+j>=0)&& (pair.second-1+j<column_)){if(!static_cast<Block*>(mainLayout->itemAtPosition(pair.first-1+i,pair.second-1+j)->widget())->is_turn_over()){static_cast<Block*>(mainLayout->itemAtPosition(pair.first-1+i,pair.second-1+j)->widget())->turn_over();++turn_over_block_number_;queue.enqueue(qMakePair(pair.first-1+i,pair.second-1+j));}}}}}}if(turn_over_block_number_==total_block_number_-total_mine_number_){game_over_flag_=true;emit game_over(true);}}#ifndef MAIN_WINDOW_H_#define MAIN_WINDOW_H_#include"block_area.h"#include<QMainWindow>#include<QTime>#include<QTimer>class QAction;class QActionGroup;class QCloseEvent;class QMenu;class QToolBar;class QWidget;class MainWindow:public QMainWindow{Q_OBJECTpublic:MainWindow(QWidget*parent=0);protected:void closeEvent(QCloseEvent*event);private slots:void slot_new_game();void slot_rank();void slot_show_game_toolBar(bool show);void slot_show_statusBar(bool show);void slot_standard(QAction*standard_action);void slot_about_game();void slot_game_over(bool is_win);void slot_timer();private:void read_settings();void write_settings();void create_actions();void create_menus();void create_game_toolBar();void create_statusBar();作者:座殿角作品编号48877446331144215458创作日期:2020年12月20日private:BlockArea*area_;int row_;int column_;int mine_number_;int easy_record_time_;int middle_record_time_;int hard_record_time_;QString easy_record_name_;QString middle_record_name_;QString hard_record_name_;int current_standard_;QMenu*game_menu;QMenu*setting_menu;QMenu*help_menu;QToolBar*game_toolBar;QAction*new_game_action;QAction*rank_action;QAction*exit_action;QAction*show_game_toolBar_action;QAction*show_statusBar_action;QAction*easy_standard_action;QAction*middle_standard_action;QAction*hard_standard_action;QAction*custom_standard_action;QActionGroup*standard_actionGroup;QAction*about_game_action;QAction*about_qt_action;QLabel*time_label;QTime time;QTimer timer;};#endif#include"main_window.h"#include<QAction>#include<QActionGroup>#include<QApplication>#include<QDialog>#include<QDialogButtonBox>#include<QHBoxLayout>#include<QIcon>#include<QInputDialog>#include<QLayout>#include<QMainWindow>#include<QMenu>#include<QMenuBar>#include<QMessageBox>#include<QPushButton>#include<QSettings>#include<QSpinBox>#include<QStatusBar>#include<QToolBar>#include<QVBoxLayout>#include<QWidget>/*关于游戏介绍的信息*/const QString g_software_name="Mine Sweeper";const QString g_software_version="1.2";const QString g_software_author="CHANGHUIZHEN";/*关于排行榜的信息*/const int g_no_record_time=9999;const QString g_no_record_name="";MainWindow::MainWindow(QWidget*parent):QMainWindow(parent){area_=new BlockArea(9,9,10);//一般设置connect(area_,SIGNAL(game_over(bool)),this,SLOT(slot _game_over(bool)));setCentralWidget(area_);create_actions();create_menus();create_game_toolBar();create_statusBar();QCoreApplication::setOrganizationName(g_software_aut hor);QCoreApplication::setApplicationName(g_software_name );read_settings();layout()->setSizeConstraint(QLayout::SetFixedSize);setWindowTitle(g_software_name);setWindowIcon(QIcon(":/game.png"));/*等待最长时间,到时间就会提示游戏失败*/timer.start(1000);connect(&timer,SIGNAL(timeout()),this,SLOT(slot_time r()));slot_new_game();}void MainWindow::closeEvent(QCloseEvent*){write_settings();}void MainWindow::slot_new_game(){area_->set_block_area(row_,column_,mine_number_);time_label->setText("0");time.restart();timer.start();}void MainWindow::slot_rank(){QDialog dialog;dialog.setWindowTitle(tr("rank"));QGridLayout*up_layout=new QGridLayout;up_layout->addWidget(new QLabel(tr("Standard")),0,0); 作者:座殿角作品编号48877446331144215458创作日期:2020年12月20日up_layout->addWidget(new QLabel(tr("Time")),0,1);up_layout->addWidget(new QLabel(tr("Name")),0,2);up_layout->addWidget(new QLabel(tr("Easy")),1,0);up_layout->addWidget(newQLabel(QString("%1").arg(easy_record_time_)),1,1);up_layout->addWidget(newQLabel(easy_record_name_),1,2);up_layout->addWidget(new QLabel(tr("Middle")),2,0);up_layout->addWidget(newQLabel(QString("%1").arg(middle_record_time_)),2,1);up_layout->addWidget(newQLabel(middle_record_name_),2,2);up_layout->addWidget(new QLabel(tr("Hard")),3,0);up_layout->addWidget(newQLabel(QString("%1").arg(hard_record_time_)),3,1);up_layout->addWidget(newQLabel(hard_record_name_),3,2);QPushButton*recount_button=newQPushButton(tr("recount"));QPushButton*close_button=newQPushButton(tr("close"));close_button->setDefault(true);connect(recount_button,SIGNAL(clicked()),&dialog,SLO T(accept()));connect(close_button,SIGNAL(clicked()),&dialog,SLOT( reject()));QHBoxLayout*bottom_layout=new QHBoxLayout;bottom_layout->addStretch();bottom_layout->addWidget(recount_button);bottom_layout->addWidget(close_button);QVBoxLayout*main_layout=new QVBoxLayout(&dialog);main_layout->addLayout(up_layout);main_layout->addLayout(bottom_layout);if(dialog.exec()==QDialog::Accepted){easy_record_time_=middle_record_time_=hard_record_ti me_=g_no_record_time;easy_record_name_=middle_record_name_=hard_record_na me_=g_no_record_name;}}void MainWindow::slot_show_game_toolBar(bool show){if(show)game_toolBar->show();elsegame_toolBar->hide();}void MainWindow::slot_show_statusBar(bool show){if(show)statusBar()->show();elsestatusBar()->hide();}/*游戏的设置容易、中等、困难及自定义*/void MainWindow::slot_standard(QAction*standard_action) {if(standard_action==easy_standard_action){current_standard_=0;row_=9;column_=9;mine_number_=10;}else if(standard_action==middle_standard_action){current_standard_=1;row_=16;column_=16;mine_number_=40;}else if(standard_action==hard_standard_action){current_standard_=2;row_=16;column_=30;mine_number_=99;}else if(standard_action==custom_standard_action){QDialog dialog;dialog.setWindowTitle(tr("set standard"));QSpinBox*row_spinBox=new QSpinBox;row_spinBox->setRange(5,50);row_spinBox->setValue(row_);QSpinBox*column_spinBox=new QSpinBox;column_spinBox->setRange(5,50);column_spinBox->setValue(column_);QSpinBox*mine_spinBox=new QSpinBox;mine_spinBox->setValue(mine_number_);QHBoxLayout*up_layout=new QHBoxLayout;up_layout->addWidget(row_spinBox);up_layout->addWidget(column_spinBox);up_layout->addWidget(mine_spinBox);QDialogButtonBox*dialog_buttonBox=new QDialogButtonBox;dialog_buttonBox->addButton(QDialogButtonBox::Ok);dialog_buttonBox->addButton(QDialogButtonBox::Cancel);connect(dialog_buttonBox,SIGNAL(accepted()),&dialog, SLOT(accept()));connect(dialog_buttonBox,SIGNAL(rejected()),&dialog, SLOT(reject()));QHBoxLayout*bottom_layout=new QHBoxLayout;bottom_layout->addStretch();bottom_layout->addWidget(dialog_buttonBox);QVBoxLayout*main_layout=newQVBoxLayout(&dialog);main_layout->addLayout(up_layout);main_layout->addLayout(bottom_layout);if(dialog.exec()==QDialog::Accepted)if(row_spinBox->value()*column_spinBox->value()>mine_spinBox->value()){current_standard_=3;row_=row_spinBox->value();column_=column_spinBox->value();mine_number_=mine_spinBox->value();}}slot_new_game();}/*实现帮助菜单中的关于游戏,及功能*/void MainWindow::slot_about_game(){QString introduction("<h2>"+tr("About Mine Sweepr")+"</h2>"+"<p>"+tr("This game is played by revealing squares of the grid,typically by clicking them with a mouse.If a square containing a mine is revealed,the player loses the game.Otherwise,a digit is revealed in the square,indicating the number of adjacent squares(out of the possible eight)that contain mines.if this number is zero then the square appears blank,and the surrounding squares are automatically also revealed.By using logic, the player can in many instances use this information to deduce that certain other squares are mine-free,in which case they may be safely revealed,or mine-filled,in which they can be marked as such(which is effected by right-clicking the square and indicated by a flaggraphic).")+"</p>"作者:座殿角作品编号48877446331144215458创作日期:2020年12月20日+"<p>"+tr("This program is free software; you can redistribute it and/or modify.it under the terms of the GNU General Public License as published by the Software Foundation;either version3of the License,or(at your option)any later version.")+"</p>"+"<p>"+tr("Please see")+"<ahref=></a>"+tr("for an overview of GPLv3licensing")+"</p>"+"<br>"+tr("Version:")+g_software_version+"</br>"+"<br>"+tr("Author:")+g_software_author+"</br>");QMessageBoxmessageBox(QMessageBox::Information,tr("About Mine Sweeper"),introduction,QMessageBox::Ok);messageBox.exec();}/*游戏的判断,及所给出的提示做出判断*/void MainWindow::slot_game_over(bool is_win){timer.stop();QString name;if(is_win){switch(current_standard_){case0:if(time_label->text().toInt()<easy_record_time_){name=QInputDialog::getText(this,tr("Please enter your name"),tr("You create a record.Please enter your name"));if(!name.isEmpty()){ easy_record_time_=time_label->text().toInt();easy_record_name_=name;}}elseQMessageBox::information(this,tr("Result"),tr("You win"));break;case1:if(time_label->text().toInt()<middle_record_time_){name=QInputDialog::getText(this,tr("Please enter your name"),tr("You create a record.Please enter your name"));if(!name.isEmpty()){ middle_record_time_=time_label->text().toInt();middle_record_name_=name;}}elseQMessageBox::information(this,tr("Result"),tr("You win"));break;case2:if(time_label->text().toInt()<hard_record_time_){name=QInputDialog::getText(this,tr("Please enter your name"),tr("You create a record.Please enter your name"));if(!name.isEmpty()){ hard_record_time_=time_label->text().toInt();hard_record_name_=name;}}elseQMessageBox::information(this,tr("Result"),tr("You win"));break;default:QMessageBox::information(this,tr("Result"),t r("You win"));}}else{QMessageBox::information(this,tr("Result"),tr("You lose"));}}/*定时器的设置*/void MainWindow::slot_timer(){time_label->setText(QString("%1").arg(time.elapsed()/1000));}/*关于菜单栏的设置是否显示游戏工具栏和状态栏*/void MainWindow::read_settings(){QSettings settings;settings.beginGroup("MainWindow");resize(settings.value("size").toSize());move(settings.value("pos").toPoint());boolshow_game_toolBar=settings.value("showGameToolBar").toBool( );show_game_toolBar_action->setChecked(show_game_toolBar);slot_show_game_toolBar(show_game_toolBar);boolshow_statusBar=settings.value("showStatusBar").toBool();show_statusBar_action->setChecked(show_statusBar);slot_show_statusBar(show_statusBar);settings.endGroup();settings.beginGroup("GameSetting");current_standard_=settings.value("current_standard") .toInt();switch(current_standard_){case0:easy_standard_action->setChecked(true);break;case1:middle_standard_action->setChecked(true);break;case2:hard_standard_action->setChecked(true);break;case3:custom_standard_action->setChecked(true);break;default:;}row_=settings.value("row").toInt()==0?9:settings.val ue("row").toInt();column_=settings.value("column").toInt()==0?9:settin gs.value("column").toInt();mine_number_=settings.value("mine_number").toInt()== 0?10:settings.value("mine_number").toInt();settings.endGroup();settings.beginGroup("Rank");easy_record_time_=settings.value("easy_record_time") .toInt()==0?g_no_record_time:settings.value("easy_record_ti me").toInt();middle_record_time_=settings.value("middle_record_ti me").toInt()==0?g_no_record_time:settings.value("middle_rec ord_time").toInt();hard_record_time_=settings.value("hard_record_time") .toInt()==0?g_no_record_time:settings.value("hard_record_ti me").toInt();easy_record_name_=settings.value("easy_record_name") .toString()==""?g_no_record_name:settings.value("easy_recor d_name").toString();middle_record_name_=settings.value("middle_record_na me").toString()==""?g_no_record_name:settings.value("middle _record_name").toString();hard_record_name_=settings.value("hard_record_name") .toString()==""?g_no_record_name:settings.value("hard_recor d_name").toString();settings.endGroup();}void MainWindow::write_settings(){QSettings settings;settings.beginGroup("MainWindow");settings.setValue("size",size());settings.setValue("pos",pos());settings.setValue("showGameToolBar",show_game_toolBa r_action->isChecked());settings.setValue("showStatusBar",show_statusBar_act ion->isChecked());settings.endGroup();settings.beginGroup("GameSetting");settings.setValue("current_standard",current_standar d_);settings.setValue("row",row_);settings.setValue("column",column_);settings.setValue("mine_number",mine_number_);settings.endGroup();settings.beginGroup("Rank");settings.setValue("easy_record_time",easy_record_tim e_);settings.setValue("middle_record_time",middle_record _time_);作者:座殿角作品编号48877446331144215458创作日期:2020年12月20日settings.setValue("hard_record_time",hard_record_tim e_);settings.setValue("easy_record_name",easy_record_nam e_);settings.setValue("middle_record_name",middle_record _name_);settings.setValue("hard_record_name",hard_record_nam e_);settings.endGroup();}/*菜单栏里图片的显示*/void MainWindow::create_actions(){new_game_action=newQAction(QIcon(":/images/new_game.png"),tr("New Game"),this);new_game_action->setShortcut(QKeySequence::New);connect(new_game_action,SIGNAL(triggered()),this,SLO T(slot_new_game()));rank_action=newQAction(QIcon(":/images/rank.png"),tr("Rank"),this);connect(rank_action,SIGNAL(triggered()),this,SLOT(sl ot_rank()));exit_action=newQAction(QIcon(":/images/exit.png"),tr("Exit"),this);exit_action->setShortcut(QKeySequence::Quit);connect(exit_action,SIGNAL(triggered()),this,SLOT(cl ose()));show_game_toolBar_action=new QAction(tr("Show Game Tool Bar"),this);show_game_toolBar_action->setCheckable(true);connect(show_game_toolBar_action,SIGNAL(toggled(bool )),this,SLOT(slot_show_game_toolBar(bool)));show_statusBar_action=new QAction(tr("Show Status Bar"),this);show_statusBar_action->setCheckable(true);connect(show_statusBar_action,SIGNAL(toggled(bool)), this,SLOT(slot_show_statusBar(bool)));easy_standard_action=newQAction(QIcon(":/images/easy_standard.png"),tr("Easy"),this );easy_standard_action->setCheckable(true);middle_standard_action=newQAction(QIcon(":/images/middle_standard.png"),tr("Middle"), this);middle_standard_action->setCheckable(true);hard_standard_action=newQAction(QIcon(":/images/hard_standard.png"),tr("Hard"),this );hard_standard_action->setCheckable(true);custom_standard_action=newQAction(QIcon(":/images/custom_standard.png"),tr("Custom"), this);custom_standard_action->setCheckable(true);standard_actionGroup=new QActionGroup(this);standard_actionGroup->addAction(easy_standard_action);standard_actionGroup->addAction(middle_standard_action);standard_actionGroup->addAction(hard_standard_action);standard_actionGroup->addAction(custom_standard_action);connect(standard_actionGroup,SIGNAL(triggered(QActio n*)),this,SLOT(slot_standard(QAction*)));about_game_action=newQAction(QIcon(":/images/game.png"),tr("About Game"),this);connect(about_game_action,SIGNAL(triggered()),this,S LOT(slot_about_game()));about_qt_action=newQAction(QIcon(":/images/qt.png"),tr("About Qt"),this);connect(about_qt_action,SIGNAL(triggered()),qApp,SLO T(aboutQt()));}/*菜单栏的创建*/void MainWindow::create_menus(){game_menu=menuBar()->addMenu(tr("Game"));game_menu->addAction(new_game_action);game_menu->addSeparator();game_menu->addAction(rank_action);game_menu->addSeparator();game_menu->addAction(exit_action);setting_menu=menuBar()->addMenu(tr("Setting"));setting_menu->addAction(show_game_toolBar_action);setting_menu->addAction(show_statusBar_action);setting_menu->addSeparator();setting_menu->addAction(easy_standard_action);setting_menu->addAction(middle_standard_action);setting_menu->addAction(hard_standard_action);setting_menu->addAction(custom_standard_action);help_menu=menuBar()->addMenu(tr("Help"));help_menu->addAction(about_game_action);help_menu->addAction(about_qt_action);}void MainWindow::create_game_toolBar(){game_toolBar=addToolBar(tr("Game Tool Bar"));game_toolBar->setFloatable(false);game_toolBar->setMovable(false);game_toolBar->addAction(new_game_action);game_toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); }void MainWindow::create_statusBar(){time_label=new QLabel;statusBar()->addPermanentWidget(time_label);statusBar()->addPermanentWidget(newQLabel(tr("second")));}#include"main_window.h"#include<QApplication>#include<QTranslator>int main(int argc,char*argv[]){QApplication app(argc,argv);QTranslator translator;translator.load(":/mine_sweeper_zh.qm");app.installTranslator(&translator);MainWindow window;window.show();return app.exec();}作者:座殿角作品编号48877446331144215458创作日期:2020年12月20日。

扫雷游戏源代码

扫雷游戏源代码

import javax.swing.ImageIcon;public class Block {String name; //名字,比如"雷"或数字int aroundMineNumber; //周围雷的数目 ImageIcon mineIcon; //雷的图标boolean isMine=false; //是否是雷boolean isMark=false; //是否被标记boolean isOpen=false; //是否被挖开public void setName(String name) {=name;}public void setAroundMineNumber(int n) { aroundMineNumber=n;}public int getAroundMineNumber() {return aroundMineNumber;}public String getName() {return name;}public boolean isMine() {return isMine;}public void setIsMine(boolean b) {isMine=b;}public void setMineIcon(ImageIcon icon){ mineIcon=icon;}public ImageIcon getMineicon(){return mineIcon;}public boolean getIsOpen() {return isOpen;}public void setIsOpen(boolean p) {isOpen=p;}public boolean getIsMark() {return isMark;}public void setIsMark(boolean m) {isMark=m;}}import java.awt.BorderLayout;import java.awt.Container;import java.awt.Font;import java.awt.GridLayout;import java.awt.Insets;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JPanel;import javax.swing.Timer;public class ScanLei1 extends JFrame implements ActionListener{ private static final long serialVersionUID = 1L;private Container contentPane;private JButton btn;private JButton[] btns;private JLabel b1;private JLabel b2;private JLabel b3;private Timer timer;private int row=9;private int col=9;private int bon=10;private int[][] a;private int b;private int[] a1;private JPanel p,p1,p2,p3;public ScanLei1(String title){super(title);contentPane=getContentPane();setSize(297,377);this.setBounds(400, 100, 400, 500);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);timer =new Timer(1000,(ActionListener) this);a = new int[row+2][col+2];initGUI();}public void initGUI(){p3=new JPanel();b=bon;JMenuBar menuBar=new JMenuBar();JMenu menu1=new JMenu("游戏");JMenu menu2=new JMenu("帮助");JMenuItem mi1=new JMenuItem("初级");JMenuItem mi2 = new JMenuItem("中级");JMenuItem mi3 =new JMenuItem("高级");mi1.addActionListener(this);menu1.add(mi1);mi2.addActionListener(this);menu1.add(mi2);mi3.addActionListener(this);menu1.add(mi3);menuBar.add(menu1);menuBar.add(menu2);p3.add(menuBar);b1=new JLabel(bon+"");a1=new int[bon];btn =new JButton("开始");btn.addActionListener(this);b2=new JLabel("0");b3=new JLabel("");btns=new JButton[row*col];p=new JPanel();p.setLayout(new BorderLayout());contentPane.add(p);p.add(p3,BorderLayout.NORTH);//combo=new JComboBox(new Object[]{"初级","中级","高级"} );//加监听/*combo.addItemListener(new ItemListener(){}});*/p1=new JPanel();//在那个位置//(( FlowLayout)p1.getLayout()).setAlignment( FlowLayout.RIGHT);p1.add(b1);p1.add(btn);p1.add(b2);p1.add(b3);p.add(p3,BorderLayout.NORTH);p.add(p1,BorderLayout.CENTER);p2=new JPanel();p2.setLayout(new GridLayout(row,col,0,0));for(int i=0;i<row*col;i++){btns[i]=new JButton("");btns[i].setMargin(new Insets(0,0,0,0));btns[i].setFont(new Font(null,Font.BOLD,25));btns[i].addActionListener(this);btns[i].addMouseListener(new NormoreMouseEvent());p2.add(btns[i]);}contentPane.add(p,BorderLayout.NORTH);contentPane.add(p2,BorderLayout.CENTER);}public void go(){setVisible(true);}public static void main(String[] args){new ScanLei1("扫雷").go();}public void out(int[][] a,JButton[] btns,ActionEvent e,int i,int x,int y){int p=1;if(a[x][y]==0){a[x][y]=10;btns[i].setEnabled(false); //33for(int l=y-1;l<=y+1;l++){int m=x-1-1;int n=l-1;p=1;System.out.println(a[1][2]);if(n>-1&&n<col&&m>-1&&m<row){for(int q=0;q<row&&p==1;q++){//col-->row;if(((n+col*q)>=(m*col))&&((n+col*q)<(m+1)*col)){if(a[x-1][l]!=0&&a[x-1][l]!=10){btns[n+col*q].setText(a[x-1][l]+"");a[x-1][l]=10;btns[n+col*q].setEnabled(false);}else if(a[x-1][l]==0){//a[x-1][l]=10;btns[n+col*q].setEnabled(false);out(a,btns,e,n+col*q,x-1,l);////55////a[x-1][l]=10;btns[n+col*q].setEnabled(false);}p=0;}}}p=1;m=x;if(n>-1&&n<col&&m>-1&&m<col){for(int q=0;q<row&&p==1;q++){if(((n+col*q)>=(m*col))&&((n+col*q)<(m+1)*col)){if(a[x+1][l]!=0&&a[x+1][l]!=10){btns[n+col*q].setText(a[x+1][l]+"");a[x+1][l]=10;btns[n+col*q].setEnabled(false);}else if(a[x+1][l]==0){out(a,btns,e,n+col*q,x+1,l);///55////a[x+1][l]=10;btns[n+col*q].setEnabled(false);}p=0;}}}}int m=x-1;int n=y-1-1;p=1;if(n>-1&&n<col&&m>-1&&m<col){for(int q=0;q<row&&p==1;q++){if(((n+col*q)>=(m*col))&&((n+col*q)<(m+1)*col)){if(a[x][y-1]!=0&&a[x][y-1]!=10){btns[n+col*q].setText(a[x][y-1]+"");a[x][y-1]=10;btns[n+col*q].setEnabled(false);}else if(a[x][y-1]==0){out(a,btns,e,n+col*q,x,y-1);a[x][y-1]=10;btns[n+col*q].setEnabled(false);}p=0;}}}p=1;m=x-1;n=y+1-1;if(n>-1&&n<col&&m>-1&&m<col){for(int q=0;q<row&&p==1;q++){if(((n+col*q)>=(m*col))&&((n+col*q)<(m+1)*col)){if(a[x][y+1]!=0&&a[x][y+1]!=10){btns[n+col*q].setText(a[x][y+1]+"");a[x][y+1]=10;btns[n+col*q].setEnabled(false);}else if(a[x][y+1]==0){out(a,btns,e,n+col*q,x,y+1);a[x][y+1]=10;btns[n+col*q].setEnabled(false);}p=0;}}}}}public void actionPerformed(ActionEvent e) {if(e.getActionCommand()=="初级"){row=9;col=9;bon=10;a1=new int[bon];b=bon;//setSize(297,377);a = new int[row+2][col+2];this.remove(p2);timer.stop();b1.setText("10");b2.setText("0");b3.setText("");btns=new JButton[row*col];p2=new JPanel();p2.setLayout(new GridLayout(row,col,0,0));for(int i=0;i<row*col;i++){btns[i]=new JButton(" ");btns[i].setMargin(new Insets(0,0,0,0));btns[i].setFont(new Font(null,Font.BOLD,25));btns[i].addActionListener(this);btns[i].addMouseListener(new NormoreMouseEvent());p2.add(btns[i]);}contentPane.add(p2,BorderLayout.CENTER);//setSize(297,377);this.pack();for(int i=0;i<row*col;i++){btns[i].setText(" ");btns[i].setEnabled(true);}for(int i=0;i<row+2;i++){for(int j=0;j<col+2;j++){a[i][j]=0;}}}else if(e.getActionCommand()=="中级"){row=16;col=16;bon=40;//setSize(33*col,33*row+80);a1=new int[bon];a = new int[row+2][col+2];b=bon;this.remove(p2);timer.stop();b1.setText("40");b2.setText("0");b3.setText("");btns=new JButton[row*col];p2=new JPanel();p2.setLayout(new GridLayout(row,col,0,0));for(int i=0;i<row*col;i++){btns[i]=new JButton(" ");btns[i].setMargin(new Insets(0,0,0,0));btns[i].setFont(new Font(null,Font.BOLD,25));btns[i].addActionListener(this);btns[i].addMouseListener(new NormoreMouseEvent());p2.add(btns[i]);}contentPane.add(p2,BorderLayout.CENTER);this.pack();//setSize(33*col,33*row+80);for(int i=0;i<row*col;i++){btns[i].setText("");btns[i].setEnabled(true);}for(int i=0;i<row+2;i++){for(int j=0;j<col+2;j++){a[i][j]=0;}}}else if(e.getActionCommand()=="高级"){row=16;col=32;bon=99;setSize(33*col,33*row+80);a1=new int[bon];a = new int[row+2][col+2];b=bon;this.remove(p2);timer.stop();b1.setText("99");b2.setText("0");b3.setText("");btns=new JButton[row*col];p2=new JPanel();p2.setLayout(new GridLayout(row,col,0,0));for(int i=0;i<row*col;i++){btns[i]=new JButton(" ");btns[i].setMargin(new Insets(0,0,0,0));btns[i].setFont(new Font(null,Font.BOLD,25));btns[i].addActionListener(this);btns[i].addMouseListener(new NormoreMouseEvent());p2.add(btns[i]);}contentPane.add(p2,BorderLayout.CENTER);//setSize(33*col,33*row+80);this.pack();for(int i=0;i<row*col;i++){btns[i].setText("");btns[i].setEnabled(true);}for(int i=0;i<row+2;i++){for(int j=0;j<col+2;j++){a[i][j]=0;}}}if(e.getSource()==btn){timer.start();b=bon;b3.setText("");//System.out.println(bon);//清空for(int i=0;i<row*col;i++){btns[i].setText("");btns[i].setEnabled(true);}for(int i=0;i<row+2;i++){for(int j=0;j<col+2;j++){a[i][j]=0;}}//产生随机数for(int i=0;i<bon;i++){ int p=1;int m=(int)(Math.random()*row*col);while(p==1){int l=1;int j;for( j=0;j<i&&l==1;j++){if(a1[j]==m){m=(int)(Math.random()*row*col);l=0;}}if(j==i){a1[i]=m;p=0;}}}b1.setText(bon+"");b2.setText("0");//布雷for(int i=0;i<bon;i++){int x=(a1[i]/col+1);int y=(a1[i]%col+1);a[x][y]=100;}for(int i=0;i<row+2;i++){for(int j=0;j<col+2;j++){if(i==0||j==0||i==row+1||j==col+1){a[i][j]=0;}}}for(int i=1;i<=row;i++){for(int j=1;j<=col;j++){if(a[i][j]!=100){for(int l=j-1;l<=j+1;l++){if(a[i-1][l]==100){a[i][j]++;}if(a[i+1][l]==100){a[i][j]++;}}if(a[i][j-1]==100){a[i][j]++;}if(a[i][j+1]==100){a[i][j]++;}}}}}if(e.getSource()==timer){String time=b2.getText().trim();int t=Integer.parseInt(time);//System.out.println(t);if(t>=600){timer.stop();}else{t++;b2.setText(t+"");}}for(int i=0;i<col*row;i++){if(btns[i].getText()!="★"){int x=i/col+1;int y=i%col+1;if(e.getSource()==btns[i]&&a[x][y]==100){ btns[i].setText("★");btns[i].setEnabled(false);a[x][y]=10;for(int k=0;k<col*row;k++){int m1=k/col+1;int n1=k%col+1;if(a[m1][n1]!=10&&btns[k].getText()=="★"){btns[k].setText("*o*");}}for(int j=0;j<col*row;j++){int m=j/col+1;int n=j%col+1;if(a[m][n]==100){btns[j].setText("★");btns[j].setEnabled(false);b3.setText("你输了!!");}btns[j].setEnabled(false);a[m][n]=10;}timer.stop();}else if(e.getSource()==btns[i]){if(a[x][y]==0){out(a,btns,e,i,x,y);a[x][y]=10;btns[i].setEnabled(false);}if(a[x][y]!=0&&a[x][y]!=10){btns[i].setText(a[x][y]+"");btns[i].setEnabled(false);a[x][y]=10;}}}else if(btns[i].getText()=="★"){}}}class NormoreMouseEvent extends MouseAdapter{ public void mouseClicked(MouseEvent e) {System.out.println(b);for(int i=0;i<col*row;i++){int x1=i/col+1;int y1=i%col+1;if(e.getSource()==btns[i]&&btns[i].getText()!="★"&&a[x1][y1]!=10){if(e.getButton()==MouseEvent.BUTTON3){btns[i].setText("★");b--;if(b==0){int flag=0;for(int j=0;j<col*row;j++){int x=j/col+1;int y=j%col+1;if(a[x][y]==100&&btns[j].getText()=="★"){flag++;}}if(flag==bon){timer.stop();b3.setText("你赢了!");}}b1.setText(b+"");}}else if(e.getSource()==btns[i]&&btns[i].getText()=="★"&&a[x1][y1]!=-1){if(e.getButton()==MouseEvent.BUTTON3){btns[i].setText("");b++;if(b>bon){b1.setText(bon+"");}else{b1.setText(b+"");}btns[i].setEnabled(true);}}}}}}import java.awt.BorderLayout;import java.awt.Container;import java.awt.Font;import java.awt.GridLayout;import java.awt.Insets;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JPanel;import javax.swing.Timer;public class ScanLei1 extends JFrame implements ActionListener{ private static final long serialVersionUID = 1L;private Container contentPane;private JButton btn;private JButton[] btns;private JLabel b1;private JLabel b2;private JLabel b3;private Timer timer;private int row=9;private int col=9;private int bon=10;private int[][] a;private int b;private int[] a1;private JPanel p,p1,p2,p3;public ScanLei1(String title){super(title);contentPane=getContentPane();setSize(297,377);this.setBounds(400, 100, 400, 500);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);timer =new Timer(1000,(ActionListener) this);a = new int[row+2][col+2];initGUI();}public void initGUI(){p3=new JPanel();b=bon;JMenuBar menuBar=new JMenuBar();JMenu menu1=new JMenu("游戏");JMenu menu2=new JMenu("帮助");JMenuItem mi1=new JMenuItem("初级");JMenuItem mi2 = new JMenuItem("中级");JMenuItem mi3 =new JMenuItem("高级");mi1.addActionListener(this);menu1.add(mi1);mi2.addActionListener(this);menu1.add(mi2);mi3.addActionListener(this);menu1.add(mi3);menuBar.add(menu1);menuBar.add(menu2);p3.add(menuBar);b1=new JLabel(bon+"");a1=new int[bon];btn =new JButton("开始");btn.addActionListener(this);b2=new JLabel("0");b3=new JLabel("");btns=new JButton[row*col];p=new JPanel();p.setLayout(new BorderLayout());contentPane.add(p);p.add(p3,BorderLayout.NORTH);//combo=new JComboBox(new Object[]{"初级","中级","高级"} );//加监听/*combo.addItemListener(new ItemListener(){}});*/p1=new JPanel();//在那个位置//(( FlowLayout)p1.getLayout()).setAlignment( FlowLayout.RIGHT);p1.add(b1);p1.add(btn);p1.add(b2);p1.add(b3);p.add(p3,BorderLayout.NORTH);p.add(p1,BorderLayout.CENTER);p2=new JPanel();p2.setLayout(new GridLayout(row,col,0,0));for(int i=0;i<row*col;i++){btns[i]=new JButton("");btns[i].setMargin(new Insets(0,0,0,0));btns[i].setFont(new Font(null,Font.BOLD,25));btns[i].addActionListener(this);btns[i].addMouseListener(new NormoreMouseEvent());p2.add(btns[i]);}contentPane.add(p,BorderLayout.NORTH);contentPane.add(p2,BorderLayout.CENTER);}public void go(){setVisible(true);}public static void main(String[] args){new ScanLei1("扫雷").go();}public void out(int[][] a,JButton[] btns,ActionEvent e,int i,int x,int y){ int p=1;if(a[x][y]==0){a[x][y]=10;btns[i].setEnabled(false); //33for(int l=y-1;l<=y+1;l++){int m=x-1-1;int n=l-1;p=1;System.out.println(a[1][2]);if(n>-1&&n<col&&m>-1&&m<row){for(int q=0;q<row&&p==1;q++){//col-->row;if(((n+col*q)>=(m*col))&&((n+col*q)<(m+1)*col)){if(a[x-1][l]!=0&&a[x-1][l]!=10){btns[n+col*q].setText(a[x-1][l]+"");a[x-1][l]=10;btns[n+col*q].setEnabled(false);}else if(a[x-1][l]==0){//a[x-1][l]=10;btns[n+col*q].setEnabled(false);out(a,btns,e,n+col*q,x-1,l); ////55////a[x-1][l]=10;btns[n+col*q].setEnabled(false);}p=0;}}}p=1;m=x;if(n>-1&&n<col&&m>-1&&m<col){for(int q=0;q<row&&p==1;q++){if(((n+col*q)>=(m*col))&&((n+col*q)<(m+1)*col)){if(a[x+1][l]!=0&&a[x+1][l]!=10){btns[n+col*q].setText(a[x+1][l]+"");a[x+1][l]=10;btns[n+col*q].setEnabled(false);}else if(a[x+1][l]==0){out(a,btns,e,n+col*q,x+1,l);///55////a[x+1][l]=10;btns[n+col*q].setEnabled(false);}p=0;}}}}int m=x-1;int n=y-1-1;p=1;if(n>-1&&n<col&&m>-1&&m<col){for(int q=0;q<row&&p==1;q++){if(((n+col*q)>=(m*col))&&((n+col*q)<(m+1)*col)){if(a[x][y-1]!=0&&a[x][y-1]!=10){btns[n+col*q].setText(a[x][y-1]+"");a[x][y-1]=10;btns[n+col*q].setEnabled(false);}else if(a[x][y-1]==0){out(a,btns,e,n+col*q,x,y-1);a[x][y-1]=10;btns[n+col*q].setEnabled(false);}p=0;}}}p=1;m=x-1;n=y+1-1;if(n>-1&&n<col&&m>-1&&m<col){for(int q=0;q<row&&p==1;q++){if(((n+col*q)>=(m*col))&&((n+col*q)<(m+1)*col)){if(a[x][y+1]!=0&&a[x][y+1]!=10){btns[n+col*q].setText(a[x][y+1]+"");a[x][y+1]=10;btns[n+col*q].setEnabled(false);}else if(a[x][y+1]==0){out(a,btns,e,n+col*q,x,y+1);a[x][y+1]=10;btns[n+col*q].setEnabled(false);}p=0;}}}}}public void actionPerformed(ActionEvent e) {if(e.getActionCommand()=="初级"){row=9;col=9;bon=10;a1=new int[bon];b=bon;//setSize(297,377);a = new int[row+2][col+2];this.remove(p2);timer.stop();b1.setText("10");b2.setText("0");b3.setText("");btns=new JButton[row*col];p2=new JPanel();p2.setLayout(new GridLayout(row,col,0,0));for(int i=0;i<row*col;i++){btns[i]=new JButton(" ");btns[i].setMargin(new Insets(0,0,0,0));btns[i].setFont(new Font(null,Font.BOLD,25));btns[i].addActionListener(this);btns[i].addMouseListener(new NormoreMouseEvent());p2.add(btns[i]);}contentPane.add(p2,BorderLayout.CENTER);//setSize(297,377);this.pack();for(int i=0;i<row*col;i++){btns[i].setText(" ");btns[i].setEnabled(true);}for(int i=0;i<row+2;i++){for(int j=0;j<col+2;j++){a[i][j]=0;}}}else if(e.getActionCommand()=="中级"){row=16;col=16;bon=40;//setSize(33*col,33*row+80);a1=new int[bon];a = new int[row+2][col+2];b=bon;this.remove(p2);timer.stop();b1.setText("40");b2.setText("0");b3.setText("");btns=new JButton[row*col];p2=new JPanel();p2.setLayout(new GridLayout(row,col,0,0));for(int i=0;i<row*col;i++){btns[i]=new JButton(" ");btns[i].setMargin(new Insets(0,0,0,0));btns[i].setFont(new Font(null,Font.BOLD,25));btns[i].addActionListener(this);btns[i].addMouseListener(new NormoreMouseEvent());p2.add(btns[i]);}contentPane.add(p2,BorderLayout.CENTER);this.pack();//setSize(33*col,33*row+80);for(int i=0;i<row*col;i++){btns[i].setText("");btns[i].setEnabled(true);}for(int i=0;i<row+2;i++){for(int j=0;j<col+2;j++){a[i][j]=0;}}}else if(e.getActionCommand()=="高级"){row=16;col=32;bon=99;setSize(33*col,33*row+80);a1=new int[bon];a = new int[row+2][col+2];b=bon;this.remove(p2);timer.stop();b1.setText("99");b2.setText("0");b3.setText("");btns=new JButton[row*col];p2=new JPanel();p2.setLayout(new GridLayout(row,col,0,0));for(int i=0;i<row*col;i++){btns[i]=new JButton(" ");btns[i].setMargin(new Insets(0,0,0,0));btns[i].setFont(new Font(null,Font.BOLD,25));btns[i].addActionListener(this);btns[i].addMouseListener(new NormoreMouseEvent());p2.add(btns[i]);}contentPane.add(p2,BorderLayout.CENTER);//setSize(33*col,33*row+80);this.pack();for(int i=0;i<row*col;i++){btns[i].setText("");btns[i].setEnabled(true);}for(int i=0;i<row+2;i++){for(int j=0;j<col+2;j++){a[i][j]=0;}}}if(e.getSource()==btn){timer.start();b=bon;b3.setText("");//System.out.println(bon);//清空for(int i=0;i<row*col;i++){btns[i].setText("");btns[i].setEnabled(true);}for(int i=0;i<row+2;i++){for(int j=0;j<col+2;j++){a[i][j]=0;}}//产生随机数for(int i=0;i<bon;i++){ int p=1;int m=(int)(Math.random()*row*col);while(p==1){int l=1;int j;for( j=0;j<i&&l==1;j++){if(a1[j]==m){m=(int)(Math.random()*row*col);l=0;}}if(j==i){a1[i]=m;p=0;}}}b1.setText(bon+"");b2.setText("0");//布雷for(int i=0;i<bon;i++){int x=(a1[i]/col+1);int y=(a1[i]%col+1);a[x][y]=100;}for(int i=0;i<row+2;i++){for(int j=0;j<col+2;j++){if(i==0||j==0||i==row+1||j==col+1){a[i][j]=0;}}}for(int i=1;i<=row;i++){for(int j=1;j<=col;j++){if(a[i][j]!=100){for(int l=j-1;l<=j+1;l++){if(a[i-1][l]==100){a[i][j]++;}if(a[i+1][l]==100){a[i][j]++;}}if(a[i][j-1]==100){a[i][j]++;}if(a[i][j+1]==100){a[i][j]++;}}}}}if(e.getSource()==timer){String time=b2.getText().trim();int t=Integer.parseInt(time);//System.out.println(t);if(t>=600){timer.stop();}else{t++;b2.setText(t+"");}}for(int i=0;i<col*row;i++){if(btns[i].getText()!="★"){int x=i/col+1;int y=i%col+1;if(e.getSource()==btns[i]&&a[x][y]==100){btns[i].setText("★");btns[i].setEnabled(false);a[x][y]=10;for(int k=0;k<col*row;k++){int m1=k/col+1;int n1=k%col+1;if(a[m1][n1]!=10&&btns[k].getText()=="★"){btns[k].setText("*o*");}}for(int j=0;j<col*row;j++){int m=j/col+1;int n=j%col+1;if(a[m][n]==100){btns[j].setText("★");btns[j].setEnabled(false);b3.setText("你输了!!");}btns[j].setEnabled(false);a[m][n]=10;}timer.stop();}else if(e.getSource()==btns[i]){if(a[x][y]==0){out(a,btns,e,i,x,y);a[x][y]=10;btns[i].setEnabled(false);}if(a[x][y]!=0&&a[x][y]!=10){btns[i].setText(a[x][y]+"");btns[i].setEnabled(false);a[x][y]=10;}}}else if(btns[i].getText()=="★"){}}}class NormoreMouseEvent extends MouseAdapter{public void mouseClicked(MouseEvent e) {System.out.println(b);for(int i=0;i<col*row;i++){int x1=i/col+1;int y1=i%col+1;if(e.getSource()==btns[i]&&btns[i].getText()!="★"&&a[x1][y1]!=10){if(e.getButton()==MouseEvent.BUTTON3){btns[i].setText("★");b--;if(b==0){int flag=0;for(int j=0;j<col*row;j++){int x=j/col+1;int y=j%col+1;if(a[x][y]==100&&btns[j].getText()=="★"){flag++;}}if(flag==bon){timer.stop();b3.setText("你赢了!");}}b1.setText(b+"");}}else if(e.getSource()==btns[i]&&btns[i].getText()=="★"&&a[x1][y1]!=-1){ if(e.getButton()==MouseEvent.BUTTON3){btns[i].setText("");b++;if(b>bon){b1.setText(bon+"");}else{b1.setText(b+"");}btns[i].setEnabled(true);}}}}}}。

基于Android平台的扫雷游戏设计与实现

基于Android平台的扫雷游戏设计与实现

基于Android平台的扫雷游戏设计与实现作者:肖洪兰来源:《商情》2020年第36期【摘要】本文开发了益智类扫雷手机游戏,分析了该游戏所需用到的API,探讨了游戏的数据结构及每个方格不同状态的不同编码,最后给出核心算法。

游戏基于Android2.2.3平台开发实现,可以运行于任意主流的Android手机中。

【关键词】扫雷 ;Android ;View一、Android平台简介Android是一个开放的手机操作系统平台,为移动设备提供了一个包含操作系统、中间件及应用程序的软件叠层架构。

Android SDK为开发人员使用Java语言编写Android平台下的应用程序提供了必要的工具和API。

Android和iPhone相比,其的优点有:真正开放、应用程序相互平等、应用程序沟通无界限。

二、扫雷游戏的简介在扫雷游戏中,有N行M列个方格,每个方格包含三种状态:关闭、标记为雷和打开,初始化时每个方格都是关闭的,你可以标记某个方格是雷,预测该方格有雷(并不表示真的一定有雷);也可以打开某个方格,一个打开的方格也会包含两种状态:一个数字和一个雷。

如果你打开的是一个雷,那么就是失败;否则就会打开一个数字,该数字是位于0到8之间的一个整数,该数字表示其所有邻居方格的所包含的雷数。

一个已打开的方格不能再关闭,标记为雷可以取消标记,当一个方格标记为雷后该方格不能打开一个方格。

所有标记为雷的方格真的是雷则游戏胜利。

三、扫雷游戏的设计及实现(一)主要的类及方法方法介绍android.view.View为所有可视化控件的基类,主要提供绘制和事件处理的方法,boolean onTouchEvent(MotionEvent event)方法处理点击屏幕的事件, onDraw(Canvas canvas)方法处理绘制画面,postInvalidate()方法会通知UI线程更新界面,UI线程会调用onDraw (Canvas canvas)重新绘制界面。

C语言编写的扫雷游戏源代码

C语言编写的扫雷游戏源代码

C语言编写的扫雷嬉戏源代码/* 源程序*/#include <graphics.h>#include <stdlib.h>#include <dos.h>#define LE 0xff01#define LEFTCLICK 0xff10#define LEFTDRAG 0xff19#define MOUSEMOVE 0xff08struct{int num;/*格子当前处于什么状态,1有雷,0已经显示过数字或者空白格子*/ int roundnum;/*统计格子四周有多少雷*/int flag;/*右键按下显示红旗的标记,0没有红旗标记,1有红旗标记*/}Mine[10][10];int gameAGAIN=0;/*是否重来的变量*/int gamePLAY=0;/*是否是第一次玩嬉戏的标记*/int mineNUM;/*统计处理过的格子数*/char randmineNUM[3];/*显示数字的字符串*/int Keystate;int MouseExist;int MouseButton;int MouseX;int MouseY;void Init(void);/*图形驱动*/void MouseOn(void);/*鼠标光标显示*/void MouseOff(void);/*鼠标光标隐藏*/void MouseSetXY(int,int);/*设置当前位置*/int Le(void);/*左键按下*/int RightPress(void);/*鼠标右键按下*/void MouseGetXY(void);/*得到当前位置*/void Control(void);/*嬉戏开场,重新,关闭*/void GameBegain(void);/*嬉戏开场画面*/void DrawSmile(void);/*画笑脸*/void DrawRedflag(int,int);/*显示红旗*/void DrawEmpty(int,int,int,int);/*两种空格子的显示*/void GameOver(void);/*嬉戏完毕*/void GameWin(void);/*显示成功*/int MineStatistics(int,int);/*统计每个格子四周的雷数*/int ShowWhite(int,int);/*显示无雷区的空白局部*/void GamePlay(void);/*嬉戏过程*/void Close(void);/*图形关闭*/void main(void)Init();Control();Close();}void Init(void)/*图形开场*/{int gd=DETECT,gm;initgraph(&gd,&gm,"c:\\tc");}void Close(void)/*图形关闭*/{closegraph();}void MouseOn(void)/*鼠标光标显示*/{_AX=0x01;geninterrupt(0x33);}void MouseOff(void)/*鼠标光标隐藏*/{_AX=0x02;geninterrupt(0x33);}void MouseSetXY(int x,int y)/*设置当前位置*/ {_CX=x;_DX=y;_AX=0x04;geninterrupt(0x33);}int Le(void)/*鼠标左键按下*/{_AX=0x03;geninterrupt(0x33);return(_BX&1);}int RightPress(void)/*鼠标右键按下*/{_AX=0x03;geninterrupt(0x33);return(_BX&2);}void MouseGetXY(void)/*得到当前位置*/_AX=0x03;geninterrupt(0x33);MouseX=_CX;MouseY=_DX;}void Control(void)/*嬉戏开场,重新,关闭*/{int gameFLAG=1;/*嬉戏失败后推断是否重新开场的标记*/while(1){if(gameFLAG)/*嬉戏失败后没推断出重新开场或者退出嬉戏的话就接着推断*/ {GameBegain(); /*嬉戏初始画面*/GamePlay();/*详细嬉戏*/if(gameAGAIN==1)/*嬉戏中重新开场*/{gameAGAIN=0;continue;}}MouseOn();gameFLAG=0;if(Le())/*推断是否重新开场*/{MouseGetXY();if(MouseX>280&&MouseX<300&&MouseY>65&&MouseY<85){gameFLAG=1;continue;}}if(kbhit())/*推断是否按键退出*/break;}MouseOff();}void DrawSmile(void)/*画笑脸*/{setfillstyle(SOLID_FILL,YELLOW);fillellipse(290,75,10,10);setcolor(YELLOW);setfillstyle(SOLID_FILL,BLACK);/*眼睛*/fillellipse(285,75,2,2);setcolor(BLACK);/*嘴巴*/bar(287,80,293,81);}void DrawRedflag(int i,int j)/*显示红旗*/{setcolor(7);setfillstyle(SOLID_FILL,RED);bar(198+j*20,95+i*20,198+j*20+5,95+i*20+5);setcolor(BLACK);line(198+j*20,95+i*20,198+j*20,95+i*20+10);}void DrawEmpty(int i,int j,int mode,int color)/*两种空格子的显示*/ {setcolor(color);setfillstyle(SOLID_FILL,color);if(mode==0)/*没有单击过的大格子*/bar(200+j*20-8,100+i*20-8,200+j*20+8,100+i*20+8);elseif(mode==1)/*单击过后显示空白的小格子*/bar(200+j*20-7,100+i*20-7,200+j*20+7,100+i*20+7);}void GameBegain(void)/*嬉戏开场画面*/{int i,j;cleardevice();if(gamePLAY!=1){MouseSetXY(290,70); /*鼠标一开场的位置,并作为它的初始坐标*/ MouseX=290;MouseY=70;}gamePLAY=1;/*下次按重新开场的话鼠标不重新初始化*/mineNUM=0;setfillstyle(SOLID_FILL,7);bar(190,60,390,290);for(i=0;i<10;i++)/*画格子*/for(j=0;j<10;j++)DrawEmpty(i,j,0,8);setcolor(7);DrawSmile();/*画脸*/randomize();for(i=0;i<10;i++)/*100个格子随机赋值有没有地雷*/for(j=0;j<10;j++)Mine[i][j].num=random(8);/*假如随机数的结果是1表示这个格子有地雷*/if(Mine[i][j].num==1)mineNUM++;/*现有雷数加1*/elseMine[i][j].num=2;Mine[i][j].flag=0;/*表示没红旗标记*/}sprintf(randmineNUM,"%d",mineNUM); /*显示这次总共有多少雷数*/setcolor(1);settextstyle(0,0,2);outtextxy(210,70,randmineNUM);mineNUM=100-mineNUM;/*变量取空白格数量*/MouseOn();}void GameOver(void)/*嬉戏完毕画面*/{int i,j;setcolor(0);for(i=0;i<10;i++)for(j=0;j<10;j++)if(Mine[i][j].num==1)/*显示全部的地雷*/{DrawEmpty(i,j,0,RED);setfillstyle(SOLID_FILL,BLACK);fillellipse(200+j*20,100+i*20,7,7);}}void GameWin(void)/*显示成功*/{setcolor(11);settextstyle(0,0,2);outtextxy(230,30,"YOU WIN!");}int MineStatistics(int i,int j)/*统计每个格子四周的雷数*/{int nNUM=0;if(i==0&&j==0)/*左上角格子的统计*/{if(Mine[0][1].num==1)nNUM++;if(Mine[1][0].num==1)nNUM++;if(Mine[1][1].num==1)}elseif(i==0&&j==9)/*右上角格子的统计*/{if(Mine[0][8].num==1)nNUM++;if(Mine[1][9].num==1)nNUM++;if(Mine[1][8].num==1)nNUM++;}elseif(i==9&&j==0)/*左下角格子的统计*/{if(Mine[8][0].num==1)nNUM++;if(Mine[9][1].num==1)nNUM++;if(Mine[8][1].num==1)nNUM++;}elseif(i==9&&j==9)/*右下角格子的统计*/{if(Mine[9][8].num==1)nNUM++;if(Mine[8][9].num==1)nNUM++;if(Mine[8][8].num==1)nNUM++;}else if(j==0)/*左边第一列格子的统计*/{if(Mine[i][j+1].num==1)nNUM++;if(Mine[i+1][j].num==1)nNUM++;if(Mine[i-1][j].num==1)nNUM++;if(Mine[i-1][j+1].num==1)nNUM++;if(Mine[i+1][j+1].num==1)nNUM++;else if(j==9)/*右边第一列格子的统计*/ {if(Mine[i][j-1].num==1)nNUM++;if(Mine[i+1][j].num==1)nNUM++;if(Mine[i-1][j].num==1)nNUM++;if(Mine[i-1][j-1].num==1)nNUM++;if(Mine[i+1][j-1].num==1)nNUM++;}else if(i==0)/*第一行格子的统计*/{if(Mine[i+1][j].num==1)nNUM++;if(Mine[i][j-1].num==1)nNUM++;if(Mine[i][j+1].num==1)nNUM++;if(Mine[i+1][j-1].num==1)nNUM++;if(Mine[i+1][j+1].num==1)nNUM++;}else if(i==9)/*最终一行格子的统计*/ {if(Mine[i-1][j].num==1)nNUM++;if(Mine[i][j-1].num==1)nNUM++;if(Mine[i][j+1].num==1)nNUM++;if(Mine[i-1][j-1].num==1)nNUM++;if(Mine[i-1][j+1].num==1)nNUM++;}else/*一般格子的统计*/{if(Mine[i-1][j].num==1)nNUM++;nNUM++;if(Mine[i][j+1].num==1)nNUM++;if(Mine[i+1][j+1].num==1)nNUM++;if(Mine[i+1][j].num==1)nNUM++;if(Mine[i+1][j-1].num==1)nNUM++;if(Mine[i][j-1].num==1)nNUM++;if(Mine[i-1][j-1].num==1)nNUM++;}return(nNUM);/*把格子四周一共有多少雷数的统计结果返回*/}int ShowWhite(int i,int j)/*显示无雷区的空白局部*/{if(Mine[i][j].flag==1||Mine[i][j].num==0)/*假如有红旗或该格处理过就不对该格进展任何推断*/return;mineNUM--;/*显示过数字或者空格的格子就表示多处理了一个格子,当全部格子都处理过了表示成功*/if(Mine[i][j].roundnum==0&&Mine[i][j].num!=1)/*显示空格*/{DrawEmpty(i,j,1,7);Mine[i][j].num=0;}elseif(Mine[i][j].roundnum!=0)/*输出雷数*/{DrawEmpty(i,j,0,8);sprintf(randmineNUM,"%d",Mine[i][j].roundnum);setcolor(RED);outtextxy(195+j*20,95+i*20,randmineNUM);Mine[i][j].num=0;/*已经输出雷数的格子用0表示已经用过这个格子*/return ;}/*8个方向递归显示全部的空白格子*/if(i!=0&&Mine[i-1][j].num!=1)ShowWhite(i-1,j);if(i!=0&&j!=9&&Mine[i-1][j+1].num!=1)ShowWhite(i-1,j+1);ShowWhite(i,j+1);if(j!=9&&i!=9&&Mine[i+1][j+1].num!=1)ShowWhite(i+1,j+1);if(i!=9&&Mine[i+1][j].num!=1)ShowWhite(i+1,j);if(i!=9&&j!=0&&Mine[i+1][j-1].num!=1)ShowWhite(i+1,j-1);if(j!=0&&Mine[i][j-1].num!=1)ShowWhite(i,j-1);if(i!=0&&j!=0&&Mine[i-1][j-1].num!=1)ShowWhite(i-1,j-1);}void GamePlay(void)/*嬉戏过程*/{int i,j,Num;/*Num用来接收统计函数返回一个格子四周有多少地雷*/for(i=0;i<10;i++)for(j=0;j<10;j++)Mine[i][j].roundnum=MineStatistics(i,j);/*统计每个格子四周有多少地雷*/while(!kbhit()){if(Le())/*鼠标左键盘按下*/{MouseGetXY();if(MouseX>280&&MouseX<300&&MouseY>65&&MouseY<85)/*重新来*/{MouseOff();gameAGAIN=1;break;}if(MouseX>190&&MouseX<390&&MouseY>90&&MouseY<290)/*当前鼠标位置在格子范围内*/{j=(MouseX-190)/20;/*x坐标*/i=(MouseY-90)/20;/*y坐标*/if(Mine[i][j].flag==1)/*假如格子有红旗那么左键无效*/continue;if(Mine[i][j].num!=0)/*假如格子没有处理过*/{if(Mine[i][j].num==1)/*鼠标按下的格子是地雷*/{MouseOff();GameOver();/*嬉戏失败*/}else/*鼠标按下的格子不是地雷*/{MouseOff();Num=MineStatistics(i,j);if(Num==0)/*四周没地雷就用递归算法来显示空白格子*/ShowWhite(i,j);else/*按下格子四周有地雷*/{sprintf(randmineNUM,"%d",Num);/*输出当前格子四周的雷数*/setcolor(RED);outtextxy(195+j*20,95+i*20,randmineNUM);mineNUM--;}MouseOn();Mine[i][j].num=0;/*点过的格子四周雷数的数字变为0表示这个格子已经用过*/if(mineNUM<1)/*成功了*/{GameWin();break;}}}}}if(RightPress())/*鼠标右键键盘按下*/{MouseGetXY();if(MouseX>190&&MouseX<390&&MouseY>90&&MouseY<290)/*当前鼠标位置在格子范围内*/{j=(MouseX-190)/20;/*x坐标*/i=(MouseY-90)/20;/*y坐标*/MouseOff();if(Mine[i][j].flag==0&&Mine[i][j].num!=0)/*原来没红旗现在显示红旗*/{DrawRedflag(i,j);Mine[i][j].flag=1;}elseif(Mine[i][j].flag==1)/*有红旗标记再按右键就红旗消逝*/DrawEmpty(i,j,0,8);Mine[i][j].flag=0;}}MouseOn();sleep(1);}}}。

Android的扫雷游戏源代码

Android的扫雷游戏源代码
(blockDimension + 2 * blockPadding)* numberOfColumnsInMineField,blockDimension + 2 * blockPadding));
}
}
私人无效endExistingGame()
{
stopTimer(); / /停止,如果计时器正在运行
{
/ /我们为每方一列额外的行
/ /整体两个额外的两个额外的行和列
/ /第一个和最后一个行/列用于计算仅
/ / x |的xxxxxxxxxxxxxx | x
/ / ------------------
/ / X的| | x
/ / X的| | x
/ / ------------------
块[行] [列] setPadding(blockPadding,blockPadding,blockPadding,blockPadding)。
tableRow.addView(块[行] [列]);
}
mineField.addView(TableRow的,新的youtParams(
txtTimer.setText(“000”); / /恢复所有文本
txtMineCount.setText(“000”); / /恢复矿山数量
btnSmile.setBackgroundResource(R.drawable.smile);
/ /删除所有行雷区TableL是处理LongClick
/ /如果块没有再发现标记附近区
/ /直到我们得到编号地雷
如果(!块[currentRow] [currentColumn]。isFlagged())

扫雷游戏代码

}
}
/*计算方块周围雷数 */
public void CountRoundBomb()
{
for (int i = 0; i < (int)Math.sqrt(BlockNum); i++) {
for (int j = 0; j < (int)Math.sqrt(BlockNum); j++) {
}
/*重新开始*/
public void replay()
{
nowBomb.setText("当前雷数"+" "+BombNum+"");
for(int i = 0 ; i < (int)Math.sqrt(BlockNum) ; i++)
for(int j = 0 ; j < (int)Math.sqrt(BlockNum) ; j++)
bombButton=new Bomb[ (int)Math.sqrt(BlockNum) ][];
for(int i = 0 ; i < (int)Math.sqrt(BlockNum) ; i++)
{
bombButton[ i ]=new Bomb[ (int)Math.sqrt(BlockNum) ];
int y =(int)(Math.random()*(int)(Math.sqrt(BlockNum)-1));
if(bombButton[ x ][ y ].isBomb==true)
i--;
else
bombButton[ x ][ y ].isBomb=true ;

扫雷游戏源代码

int boo[maxcell][maxcell];
int x,y,z,cc;
bool lei=false;
now_time = time(NULL);
h=now_time;
cc=c;
//初始化数组
for(int i=0;i<maxcell;i++)
for(int y=0;y<maxcell;y++)
void cell(int a,int b,int c)
{
//
time_t now_time;
time_t h;
srand( (unsigned)time( NULL ) );
initgraph((a+2)*cel,(b+5)*cel);
MOUSEMSG m;
int mimi[maxcell][maxcell];
case WM_RBUTTONDOWN:
x=m.x/cel-1;
y=m.y/cel-1;
if(mimi[x][y]==0)
{
mimi[x][y]=2;
cc--;
}
else if(mimi[x][y]==2)
{
/////////////////////////
//@挚爱
//vc6.0 EasyX库
///////////////////////////
#include<graphics.h>
#include <conio.h>
#include<time.h>
#include <stdio.h>

扫雷游戏开发代码

return isMark;
}
public void setIsMark(boolean m) {
isMark=m;
}
}
/*(2)雷区显示*/
import javax.swing.*;
import java.awt.*;
}
else {
int n=block.getAroundMineNumber();
setBackground(new Color(0,0,122));
if(n>=1)
{
isMine=b;
}
public void setMineIcon(ImageIcon icon){
mineIcon=icon;
}
public ImageIcon getMineicon(){
return mineIcon;
if(n==2)////
blockNameOrIcon.setForeground(new Color(0,0,255));////////
if(n==3)
blockNameOrIcon.setForeground(new Color(0,255,0));///
}
}
block[i][j].setIsOpen(false);
block[i][j].setIsMark(false);
block[i][j].setName(""+mineNumber);
blockNameOrIcon.setVerticalTextPosition(AbstractButton.CENTER);
blockCover=new JButton();

扫雷4Android(附源码)

扫雷4Android(附源码) 最近由于项⽬需要学习了⼀下Android ,感觉汗不错。

做了⼀个Android版的扫雷游戏。

游戏简介 在此游戏中,我们使⽤⼀个块的⽹格,其中有⼀些随机的地雷下⾯是效果图⼀、应⽤程序布局使⽤TableLayout布局控件。

设置3⾏。

⼆、地雷块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 youtParams((blockDimension + 2 * blockPadding) * numberOfColumnsInMineField, blockDimension + 2 * blockPadding)); }}2.定时器Handlerprivate 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 secondtimer.postDelayed(updateTimeElasped, 1000);}}public void stopTimer(){// disable call backstimer.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 notificationtimer.postAtTime(this, currentMilliseconds);// notify to call back after 1 seconds// basically to remain in the timer looptimer.postDelayed(updateTimeElasped, 1000);}};3.第⼀次点击private boolean isTimerStarted; // check if timer already started or notblocks[row][column].setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View view){// start timer on first clickif (!isTimerStarted){startTimer();isTimerStarted = true;}...}});4.第⼀次点击⽆雷private boolean areMinesSet; // check if mines are planted in blocksblocks[row][column].setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View view){...// set mines on first clickif (!areMinesSet){areMinesSet = true;setMines(currentRow, currentColumn);}}});private void setMines(int currentRow, int currentColumn){// set mines excluding the location where user clickedRandom 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 locationblocks[mineColumn + 1][mineRow + 1].plantMine();}// exclude the user clicked locationelse{row--;}}int nearByMineCount;// count number of mines in surrounding blocks...}5.点击雷块的效果private void rippleUncover(int rowClicked, int columnClicked){// don't open flagged or mined rowsif (blocks[rowClicked][columnClicked].hasMine() || blocks[rowClicked][columnClicked].isFlagged()) {return;}// open clicked blockblocks[rowClicked][columnClicked].OpenBlock();// if clicked block have nearby mines then don't open furtherif (blocks[rowClicked][columnClicked].getNumberOfMinesInSorrounding() != 0 ){return;}// open next 3 rows and 3 columns recursivelyfor (int row = 0; row < 3; row++){for (int column = 0; column < 3; column++){// check all the above checked conditions// if met then open subsequent blocksif (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 flaggedif (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 flaggedif (!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 countupdateMineCountDisplay();}// case 2. set flagged to question markelse 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 countupdateMineCountDisplay();}// case 3. change to blank squareelse{blocks[currentRow][currentColumn].setBlockAsDisabled(true);blocks[currentRow][currentColumn].clearAllIcons();blocks[currentRow][currentColumn].setQuestionMarked(false);// if it is flagged then increment mine countif (blocks[currentRow][currentColumn].isFlagged()){minesToFind++; // increase mine countupdateMineCountDisplay();}// remove flagged statusblocks[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 overfinishGame(currentRow + previousRow, currentColumn + previousColumn);}// did we win the gameif (checkGameWin()){// mark game as winwinGame();}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 youtParams;public class MinesweeperGame extends Activity {private TextView txtMineCount;private TextView txtTimer;private ImageButton btnSmile;private TableLayout mineField;private Block blocks[][]; // blocks for mine fieldprivate int blockDimension = 24; // width of each blockprivate int blockPadding = 2; // padding between blocksprivate int numberOfRowsInMineField = 9;private int numberOfColumnsInMineField = 9;private int totalNumberOfMines = 10;// timer to keep track of time elapsedprivate 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. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.test);txtMineCount = (TextView) findViewById(R.id.minecount);txtTimer = (TextView) findViewById(R.id.timer);btnSmile = (ImageButton) findViewById(R.id.smiley);btnSmile.setOnClickListener(new OnClickListener(){@Overridepublic 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 UIshowMineField();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 minesblocks = 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 onlyfinal int currentRow = row;final int currentColumn = column;blocks[row][column].setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// start timer on first clickif (!isTimerStarted) {startTimer();isTimerStarted = true;}// set mines on first clickif (!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 minesif (!blocks[currentRow][currentColumn].isFlagged()) {// open nearby blocks till we get numbered blocksrippleUncover(currentRow, currentColumn);// did we clicked a mineif (blocks[currentRow][currentColumn].hasMine()) {// Oops, game overfinishGame(currentRow, currentColumn);}// check if we win the gameif (checkGameWin()) {// mark game as winwinGame();}}}});// add Long Click listener// this is treated as right mouse click listenerblocks[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.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 blocksif (nearbyFlaggedBlocks == blocks[currentRow][currentColumn].getNumberOfMinesInSorrounding()) {for (int previousRow = -1; previousRow < 2; previousRow++) {for (int previousColumn = -1; previousColumn < 2; previousColumn++) { // don't open flagged blocksif (!blocks[currentRow+ previousRow][currentColumn+ previousColumn].isFlagged()) {// open blocks till we get// numbered blockrippleUncover(currentRow+ previousRow,currentColumn+ previousColumn);// did we clicked a mineif (blocks[currentRow+ previousRow][currentColumn+ previousColumn].hasMine()) {// oops game overfinishGame(currentRow+ previousRow,currentColumn+ previousColumn);}// did we win the gameif (checkGameWin()) {// mark game as winwinGame();}}}}}// 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 blankreturn true;}// if clicked block is enabled, clickable or// flaggedif (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 flaggedif (!blocks[currentRow][currentColumn].isFlagged().isQuestionMarked()) {blocks[currentRow][currentColumn].setBlockAsDisabled(false);blocks[currentRow][currentColumn].setFlagIcon(true);blocks[currentRow][currentColumn].setFlagged(true);minesToFind--; // reduce mine countupdateMineCountDisplay();}// case 2. set flagged to question markelse 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 countupdateMineCountDisplay();}// case 3. change to blank squareelse {blocks[currentRow][currentColumn].setBlockAsDisabled(true);blocks[currentRow][currentColumn].clearAllIcons();blocks[currentRow][currentColumn].setQuestionMarked(false);// if it is flagged then increment mine// countif (blocks[currentRow][currentColumn].isFlagged()) {minesToFind++; // increase mine// countupdateMineCountDisplay();}// remove flagged statusblocks[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 youtParams((blockDimension + 2 * blockPadding)* numberOfColumnsInMineField, blockDimension + 2* blockPadding));}}private void endExistingGame() {stopTimer(); // stop if timer is runningtxtTimer.setText("000"); // revert all texttxtMineCount.setText("000"); // revert mines countbtnSmile.setBackgroundResource(R.drawable.smile);// remove all rows from mineField TableLayoutmineField.removeAllViews();// set all variables to support end of gameisTimerStarted = 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 dudebtnSmile.setBackgroundResource(R.drawable.cool);updateMineCountDisplay(); // update mine count// disable all buttons// set flagged all un-flagged blocksfor (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 messageshowDialog("You won in " + Integer.toString(secondsPassed)+ " seconds!", 1000, false, true);}private void finishGame(int currentRow, int currentColumn) {isGameOver = true; // mark game as overstopTimer(); // stop timerisTimerStarted = false;btnSmile.setBackgroundResource(R.drawable.sad);// show all mines// disable all blocksfor (int row = 1; row < numberOfRowsInMineField + 1; row++) {for (int column = 1; column < numberOfColumnsInMineField + 1; column++) { // disable blockblocks[row][column].setBlockAsDisabled(false);// block has mine and is not flaggedif (blocks[row][column].hasMine()&& !blocks[row][column].isFlagged()) {// set mine iconblocks[row][column].setMineIcon(false);}// block is flagged and doesn't not have mineif (!blocks[row][column].hasMine()&& blocks[row][column].isFlagged()) {// set flag iconblocks[row][column].setFlagIcon(false);}// block is flaggedif (blocks[row][column].isFlagged()) {// disable the blockblocks[row][column].setClickable(false);}}}// trigger mineblocks[currentRow][currentColumn].triggerMine();// show messageshowDialog("You tried for " + Integer.toString(secondsPassed)+ " seconds!", 1000, false, false);}private void setMines(int currentRow, int currentColumn) {// set mines excluding the location where user clickedRandom 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 locationblocks[mineColumn + 1][mineRow + 1].plantMine();}// exclude the user clicked locationelse {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 countnearByMineCount = 0;if ((row != 0) && (row != (numberOfRowsInMineField + 1))&& (column != 0)&& (column != (numberOfColumnsInMineField + 1))) {// check in all nearby blocksfor (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 counternearByMineCount++;}}}blocks[row][column].setNumberOfMinesInSurrounding(nearByMineCount);}// for side rows (0th and last row/column)// set count as 9 and mark it as openedelse {blocks[row][column].setNumberOfMinesInSurrounding(9);blocks[row][column].OpenBlock();}}}}private void rippleUncover(int rowClicked, int columnClicked) {// don't open flagged or mined rowsif (blocks[rowClicked][columnClicked].hasMine()|| blocks[rowClicked][columnClicked].isFlagged()) {return;}// open clicked blockblocks[rowClicked][columnClicked].OpenBlock();// if clicked block have nearby mines then don't open furtherif (blocks[rowClicked][columnClicked].getNumberOfMinesInSorrounding() != 0) { return;}// open next 3 rows and 3 columns recursivelyfor (int row = 0; row < 3; row++) {for (int column = 0; column < 3; column++) {// check all the above checked conditions// if met then open subsequent blocksif (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 secondtimer.postDelayed(updateTimeElasped, 1000);Log.i("tag",String.valueOf((timer.postDelayed(updateTimeElasped, 1000))) ); }}public void stopTimer() {// disable call backstimer.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 notificationtimer.postAtTime(this, currentMilliseconds);// notify to call back after 1 seconds// basically to remain in the timer looptimer.postDelayed(updateTimeElasped, 1000);}};private void showDialog(String message, int milliseconds,boolean useSmileImage, boolean useCoolImage) {// show messageToast 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()");}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第1章游戏源码1.1 MinesweeperGamepackage com.VertexVerveInc.Games;import java.util.Random;import android.app.Activity;import android.graphics.Typeface;import android.os.Bundle;import android.os.Handler;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 youtParams;import android.widget.TableLayout;import android.widget.TableRow;import android.widget.TextView;import android.widget.Toast;public class MinesweeperGame extends Activity{private TextView txtMineCount;private TextView txtTimer;private ImageButton btnSmile;private TableLayout mineField; // table layout to add mines toprivate Block blocks[][]; // blocks for mine fieldprivate int blockDimension = 24; // width of each blockprivate int blockPadding = 2; // padding between blocksprivate int numberOfRowsInMineField = 9;private int numberOfColumnsInMineField = 9;private int totalNumberOfMines = 10;// timer to keep track of time elapsedprivate 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@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(yout.main);txtMineCount = (TextView) findViewById(R.id.MineCount);txtTimer = (TextView) findViewById(R.id.Timer);// set font style for timer and mine count to LCD styleTypeface lcdFont = Typeface.createFromAsset(getAssets(),"fonts/lcd2mono.ttf");txtMineCount.setTypeface(lcdFont);txtTimer.setTypeface(lcdFont);btnSmile = (ImageButton) findViewById(R.id.Smiley);btnSmile.setOnClickListener(new OnClickListener(){@Overridepublic 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(){// plant mines and do rest of the calculationscreateMineField();// display all blocks in UIshowMineField();minesToFind = totalNumberOfMines;isGameOver = false;secondsPassed = 0;}private void showMineField(){// remember we will not show 0th and last Row and Columns// they are used for calculation purposes onlyfor (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 youtParams((blockDimension + 2 * blockPadding) * numberOfColumnsInMineField, blockDimension + 2 * blockPadding));}}private void endExistingGame(){stopTimer(); // stop if timer is runningtxtTimer.setText("000"); // revert all texttxtMineCount.setText("000"); // revert mines countbtnSmile.setBackgroundResource(R.drawable.smile);// remove all rows from mineField TableLayoutmineField.removeAllViews();// set all variables to support end of gameisTimerStarted = false;areMinesSet = false;isGameOver = false;minesToFind = 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 < numberOfRowsInMineField + 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 onlyfinal int currentRow = row;final int currentColumn = column;// add Click Listener// this is treated as Left Mouse clickblocks[row][column].setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View view){// start timer on first clickif (!isTimerStarted){startTimer();isTimerStarted = true;}// set mines on first clickif (!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 minesif (!blocks[currentRow][currentColumn].isFlagged()){// open nearby blocks till we get numbered blocksrippleUncover(currentRow, currentColumn);// did we clicked a mineif (blocks[currentRow][currentColumn].hasMine()){// Oops, game overfinishGame(currentRow,currentColumn);// check if we win the gameif (checkGameWin()){// mark game as winwinGame();}}}});// add Long Click listener// this is treated as right mouse click listenerblocks[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 blocksif (!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 blocksif (nearbyFlaggedBlocks == blocks[currentRow][currentColumn].getNumberOfMinesInSorrounding()) {for (int previousRow = -1; previousRow < 2; previousRow++){for (int previousColumn = -1; previousColumn < 2; previousColumn++){// don't open flagged blocksif (!blocks[currentRow + previousRow][currentColumn + previousColumn].isFlagged()){// open blocks till we get numbered blockrippleUncover(currentRow + previousRow, currentColumn + previousColumn);// did we clicked a mineif (blocks[currentRow + previousRow][currentColumn + previousColumn].hasMine()){// oops game overfinishGame(currentRow + previousRow, currentColumn + previousColumn);}// did we win the gameif (checkGameWin()){// mark game as winwinGame();}}}}}// 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 blankreturn true;}// if clicked block is enabled, clickable or flaggedif (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 flaggedif (!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 countupdateMineCountDisplay();}// case 2. set flagged to question markelse 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 countupdateMineCountDisplay();}// case 3. change to blank squareelse{blocks[currentRow][currentColumn].setBlockAsDisabled(true);blocks[currentRow][currentColumn].clearAllIcons();blocks[currentRow][currentColumn].setQuestionMarked(false);// if it is flagged then increment mine countif (blocks[currentRow][currentColumn].isFlagged()){minesToFind++; // increase mine countupdateMineCountDisplay();}// remove flagged statusblocks[currentRow][currentColumn].setFlagged(false);}updateMineCountDisplay(); // update mine display}return true;}});}}}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 dudebtnSmile.setBackgroundResource(R.drawable.cool); updateMineCountDisplay(); // update mine count// disable all buttons// set flagged all un-flagged blocksfor (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 messageshowDialog("You won in " + Integer.toString(secondsPassed) + " seconds!", 1000, false, true);}private void finishGame(int currentRow, int currentColumn){isGameOver = true; // mark game as overstopTimer(); // stop timerisTimerStarted = false;btnSmile.setBackgroundResource(R.drawable.sad);// show all mines// disable all blocksfor (int row = 1; row < numberOfRowsInMineField + 1; row++){for (int column = 1; column < numberOfColumnsInMineField + 1; column++){// disable blockblocks[row][column].setBlockAsDisabled(false);// block has mine and is not flaggedif (blocks[row][column].hasMine() && !blocks[row][column].isFlagged()){// set mine iconblocks[row][column].setMineIcon(false);}// block is flagged and doesn't not have mineif (!blocks[row][column].hasMine() && blocks[row][column].isFlagged()){// set flag iconblocks[row][column].setFlagIcon(false);}// block is flaggedif (blocks[row][column].isFlagged()){// disable the blockblocks[row][column].setClickable(false);}}}// trigger mineblocks[currentRow][currentColumn].triggerMine();// show messageshowDialog("You tried for " + Integer.toString(secondsPassed) + " seconds!", 1000, false, false);}private void setMines(int currentRow, int currentColumn){// set mines excluding the location where user clickedRandom 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 locationblocks[mineColumn + 1][mineRow + 1].plantMine();}// exclude the user clicked locationelse{row--;}}int nearByMineCount;// count number of mines in surrounding blocksfor (int row = 0; row < numberOfRowsInMineField + 2; row++){for (int column = 0; column < numberOfColumnsInMineField + 2; column++){// for each block find nearby mine countnearByMineCount = 0;if ((row != 0) && (row != (numberOfRowsInMineField + 1)) && (column != 0) && (column != (numberOfColumnsInMineField + 1))){// check in all nearby blocksfor (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 counternearByMineCount++;}}}blocks[row][column].setNumberOfMinesInSurrounding(nearByMineCount);}// for side rows (0th and last row/column)// set count as 9 and mark it as openedelse{blocks[row][column].setNumberOfMinesInSurrounding(9);blocks[row][column].OpenBlock();}}}}private void rippleUncover(int rowClicked, int columnClicked){// don't open flagged or mined rowsif (blocks[rowClicked][columnClicked].hasMine() || blocks[rowClicked][columnClicked].isFlagged()){return;}// open clicked blockblocks[rowClicked][columnClicked].OpenBlock();// if clicked block have nearby mines then don't open furtherif (blocks[rowClicked][columnClicked].getNumberOfMinesInSorrounding() != 0 ) {return;}// open next 3 rows and 3 columns recursivelyfor (int row = 0; row < 3; row++){for (int column = 0; column < 3; column++){// check all the above checked conditions// if met then open subsequent blocksif (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 secondtimer.postDelayed(updateTimeElasped, 1000);}}public void stopTimer(){// disable call backstimer.removeCallbacks(updateTimeElasped);}// timer call back when timer is tickedprivate Runnable updateTimeElasped = new Runnable(){public void run(){long currentMilliseconds = System.currentTimeMillis();++secondsPassed;if (secondsPassed < 10){txtTimer.setText("00" + Integer.toString(secondsPassed));}else if (secondsPassed < 100){txtTimer.setText("0" + Integer.toString(secondsPassed));}else{txtTimer.setText(Integer.toString(secondsPassed));}// add notificationtimer.postAtTime(this, currentMilliseconds);// notify to call back after 1 seconds// basically to remain in the timer looptimer.postDelayed(updateTimeElasped, 1000);}};private void showDialog(String message, int milliseconds, boolean useSmileImage, boolean useCoolImage){// show messageToast 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();}}1.2 Blockpackage com.VertexVerveInc.Games;import android.content.Context;import android.graphics.Color;import android.graphics.Typeface;import android.util.AttributeSet;import android.widget.Button;public class Block extends Button{private boolean isCovered; // is block covered yetprivate boolean isMined; // does the block has a mine underneathprivate boolean isFlagged; // is block flagged as a potential mineprivate boolean isQuestionMarked; // is block question markedprivate boolean isClickable; // can block accept click eventsprivate int numberOfMinesInSurrounding; // number of mines in nearby blocks public Block(Context context){super(context);}public Block(Context context, AttributeSet attrs){super(context, attrs);}public Block(Context context, AttributeSet attrs, int defStyle){super(context, attrs, defStyle);}// set default properties for the blockpublic void setDefaults(){isCovered = true;isMined = false;isFlagged = false;isQuestionMarked = false;isClickable = true;numberOfMinesInSurrounding = 0;this.setBackgroundResource(R.drawable.square_blue); setBoldFont();}// mark the block as disabled/opened// update the number of nearby minespublic void setNumberOfSurroundingMines(int number) {this.setBackgroundResource(R.drawable.square_grey); updateNumber(number);}// set mine icon for block// set block as disabled/opened if false is passed 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);}}// set mine as flagged// set block as disabled/opened if false is passed 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);}}// set mine as question mark// set block as disabled/opened if false is passed public void setQuestionMarkIcon(boolean enabled) {this.setText("?");if (!enabled){this.setBackgroundResource(R.drawable.square_grey); this.setTextColor(Color.RED);}else{this.setTextColor(Color.BLACK);}}// set block as disabled/opened if false is passed // else enable/close itpublic void setBlockAsDisabled(boolean enabled) {if (!enabled){this.setBackgroundResource(R.drawable.square_grey); }else{this.setBackgroundResource(R.drawable.square_blue); }}// clear all icons/textpublic void clearAllIcons(){this.setText("");}// set font as boldprivate void setBoldFont(){this.setTypeface(null, Typeface.BOLD);}// uncover this blockpublic void OpenBlock(){// cannot uncover a mine which is not coveredif (!isCovered)return;setBlockAsDisabled(false);isCovered = false;// check if it has mineif (hasMine()){setMineIcon(false);}// update with the nearby mine countelse{setNumberOfSurroundingMines(numberOfMinesInSurrounding); }}// set text as nearby mine countpublic void updateNumber(int text){if (text != 0){this.setText(Integer.toString(text));// select different color for each number// we have already skipped 0 mine countswitch (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;}}}// set block as a mine underneathpublic void plantMine(){isMined = true;}// mine was opened// change the block icon and colorpublic void triggerMine(){setMineIcon(true);this.setTextColor(Color.RED);}// is block still coveredpublic boolean isCovered(){return isCovered;}// does the block have any mine underneathpublic boolean hasMine(){return isMined;}// set number of nearby minespublic void setNumberOfMinesInSurrounding(int number) {numberOfMinesInSurrounding = number;}// get number of nearby minespublic int getNumberOfMinesInSorrounding(){return numberOfMinesInSurrounding;}// is block marked as flaggedpublic boolean isFlagged(){return isFlagged;}// mark block as flaggedpublic void setFlagged(boolean flagged){isFlagged = flagged;}// is block marked as a question markpublic boolean isQuestionMarked(){return isQuestionMarked;}// set question mark for the blockpublic void setQuestionMarked(boolean questionMarked){isQuestionMarked = questionMarked;}// can block receive click eventpublic boolean isClickable(){return isClickable;}// disable block for receive click eventspublic void setClickable(boolean clickable){isClickable = clickable;}}第2章源码详细分析2.1 基本变量设置private TextView txtMineCount;//剩余地雷数private TextView txtTimer;//计时private ImageButton btnSmile;//新游戏按钮private TableLayout mineField; //表的布局添加地雷private Block blocks[][]; //所有的块private int blockDimension = 24; //每块的宽度private int blockPadding = 2; //块之间填充private int numberOfRowsInMineField = 9;//雷区为9行private int numberOfColumnsInMineField = 9;//雷区为9列private int totalNumberOfMines = 10;//总共有10个雷//定时器的运行时间保持跟踪private Handler timer = new Handler();private int secondsPassed = 0;private boolean isTimerStarted; //检查是否已经开始或不定时private boolean areMinesSet; //检查是否已经设置地雷private boolean isGameOver;//检查是否游戏结束private int minesToFind; //有待发现的地雷数量2.2 游戏初始化游戏的初始化函数中,要设置整个界面的背景图片和游戏开始按钮的图片,还有设置一个提示信息(当点击其它地方时弹出)。

相关文档
最新文档