Skip to main content
Code Review

Return to Question

Tweeted twitter.com/#!/StackCodeReview/status/580536839754371072
deleted 59 characters in body
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238
  • Very minimal implementation (Wellwell, I did what was required...)
  • No separation of logic, entire game crammed into Game ActivityGameActivity (not sure what they want)
  • Game logic isn't separated from view classes (not sure what they want)
  • Flood-fill when you click on an empty square doesn't quite work right
  • Doesn't make the best use of Android features (e.g. GridViewGridView) [seems(seems debatable that it is the 'best' to me since I used TableLayoutTableLayout for the rows instead of GridView]GridView)

My code is at https://github.com/John61590/minesweeperhere .

The recruiter said that they had no Android Engineersengineers currently but they had some people that "knew it" who reviewed my code. It seems kind of sketchy. The company would not consider any other samples I had on my resume either except their coding challenge.... (Yesyes, one of those companies...).

  • Very minimal implementation (Well, I did what was required...)
  • No separation of logic, entire game crammed into Game Activity (not sure what they want)
  • Game logic isn't separated from view classes (not sure what they want)
  • Flood-fill when you click on an empty square doesn't quite work right
  • Doesn't make the best use of Android features (e.g. GridView) [seems debatable that it is the 'best' to me since I used TableLayout for the rows instead of GridView]

My code is at https://github.com/John61590/minesweeper

The recruiter said that they had no Android Engineers currently but they had some people that "knew it" who reviewed my code. It seems kind of sketchy. The company would not consider any other samples I had on my resume either except their coding challenge.... (Yes, one of those companies...)

  • Very minimal implementation (well, I did what was required...)
  • No separation of logic, entire game crammed into GameActivity (not sure what they want)
  • Game logic isn't separated from view classes (not sure what they want)
  • Flood-fill when you click on an empty square doesn't quite work right
  • Doesn't make the best use of Android features (e.g. GridView) (seems debatable that it is the 'best' to me since I used TableLayout for the rows instead of GridView)

My code is at here .

The recruiter said that they had no Android engineers currently but they had some people that "knew it" who reviewed my code. It seems kind of sketchy. The company would not consider any other samples I had on my resume either except their coding challenge (yes, one of those companies).

Linked to current GitHub commit
Source Link
200_success
  • 145.5k
  • 22
  • 190
  • 479
  • ☺︎ Game works
  • ☺︎ Concise code

My code is at https://github.com/John61590/minesweeper https://github.com/John61590/minesweeper

  • Game works
  • Concise code

My code is at https://github.com/John61590/minesweeper

  • ☺︎ Game works
  • ☺︎ Concise code

My code is at https://github.com/John61590/minesweeper

added 10 characters in body
Source Link
John61590
  • 213
  • 2
  • 8
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.*;
import java.util.Random;
public class GameActivity extends Activity {
private TableLayout mTableLayout;
private ImageButton mValidateButton;
private static final int mineCount = 10;
private final Tile[][] mData = new Tile[8][8]; //8x8 grid
public class Tile extends Button
{
 private boolean isMine;
 private boolean isFlag;
 private boolean isCovered;
 private int noSurroundingMines;
 public Tile(Context context)
 {
 super(context);
 }
 public Tile(Context context, AttributeSet attrs)
 {
 super(context, attrs);
 }
 public Tile(Context context, AttributeSet attrs, int defStyle)
 {
 super(context, attrs, defStyle);
 }
 public void setDefaults()
 {
 isMine = false;
 isFlag = false;
 isCovered = true;
 noSurroundingMines = 0;
 this.setBackgroundResource(R.drawable.tile);
 }
 public void setMine(boolean mine)
 {
 this.isMine = mine;
 if (isMine && !isCovered) //only show mine if isn't
 {
 this.setBackgroundResource(R.drawable.mine);
 }
 }
 public void setFlag(boolean flag)
 {
 this.isFlag = flag;
 if (flag)
 {
 this.setBackgroundResource(R.drawable.flag);
 }
 }
 public void setUncovered()
 {
 this.isCovered = false;
 if (isMine())
 {
 this.setBackgroundResource(R.drawable.mine);
 } else if (noSurroundingMines > -1) {
 switch (noSurroundingMines)
 {
 case 0:
 this.setBackgroundResource(R.drawable.sq0);
 break;
 case 1:
 this.setBackgroundResource(R.drawable.sq1);
 break;
 case 2:
 this.setBackgroundResource(R.drawable.sq2);
 break;
 case 3:
 this.setBackgroundResource(R.drawable.sq3);
 break;
 case 4:
 this.setBackgroundResource(R.drawable.sq4);
 break;
 case 5:
 this.setBackgroundResource(R.drawable.sq5);
 break;
 case 6:
 this.setBackgroundResource(R.drawable.sq6);
 break;
 case 7:
 this.setBackgroundResource(R.drawable.sq7);
 break;
 case 8:
 this.setBackgroundResource(R.drawable.sq8);
 break;
 }
 }
}
public void updateSurroundingNumber() {
 this.noSurroundingMines++;
}
public void setSurroundingNumber(int number)
{
 this.noSurroundingMines = number;
}
public boolean isMine()
{
 return this.isMine;
}
public boolean isFlag()
{
 return this.isFlag;
}
public int getNoSurroundingMines()
{
 return noSurroundingMines;
}
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle bundle) {
 super.onCreate(bundle);
 setContentView(R.layout.lib_game);
 mValidateButton = (ImageButton) findViewById(R.id.validate);
 mValidateButton.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 //check if win. if not, reset game
 if (!checkGameFinished()) {
 //reset game
 mValidateButton.setBackgroundResource(R.drawable.normal_smiley);
 initTiles();
 mTableLayout.removeAllViews();
 initTable();
 initMineField(mineCount);
 } else {
 v.setBackgroundResource(R.drawable.win_smiley);
 setUncoveredMinesToFlags();
 setWinState();
 }
 }
});
 mValidateButton.setBackgroundResource(R.drawable.normal_smiley);
 mTableLayout = (TableLayout) findViewById(R.id.game_view);
 mTableLayout.setShrinkAllColumns(true);
 initTiles();
 initTable();
 initMineField(mineCount);
}
private void initTiles()
{
 for (int i = 0; i < mData.length; i++) {
 for (int j = 0; j < mData[0].length; j++) {
 Tile tile = new Tile(this);
 tile.setDefaults();
 mData[i][j] = tile;
 }
 }
}
private void initTable()
{
 //setting up rows for tablelayout
 for (int i = 0; i < mData.length; i++)
 {
 TableRow row = new TableRow(this);
 for (int button = 0; button < mData[0].length; button++) {
 // and you have to add them to the TableRow
 mData[i][button].setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 //check if you won before anything incl. setting adjacent elements
 if (v.getTag(R.id.mine) != null)
 {
 Object tag = v.getTag(R.id.mine);
 if ((Boolean)tag)
 {
 //you clicked on a mine, so you lost
 v.setBackgroundColor(Color.RED);
 v.setBackgroundResource(R.drawable.mine);
 mValidateButton.setBackgroundResource(R.drawable.lose_smiley);
 //display all other mines
 uncoverAllMines();
 }
 }
rippleUncover((Integer)v.getTag(R.id.x), (Integer)v.getTag(R.id.y));
checkGameFinished();
}
});
mData[i][button].setTag(R.id.x, i);
mData[i][button].setTag(R.id.y, button);
row.addView(mData[i][button]);
}
// a new row has been constructed -> add to table
mTableLayout.addView(row);
}
}
private void rippleUncover(int rowClicked, int columnClicked)
{
// don't open mined rows
if (mData[rowClicked][columnClicked].isMine())
{
return;
}
// open clicked block
mData[rowClicked][columnClicked].setUncovered();
// if clicked block have nearby mines then don't open further
if (mData[rowClicked][columnClicked].getNoSurroundingMines() != 0 )
{
return;
}
// open next 3 rows and 3 columns recursively
for (int row = 0; row < 3; row++)
{
for (int column = 0; column < 3; column++)
{
// check all the above checked conditions
// if met then open subsequent blocks
if ((rowClicked + row - 1 >= 0) && (rowClicked + row - 1 < 8) && (columnClicked + column - 1 >= 0) &&
columnClicked + column - 1 < 8) {
if (mData[rowClicked + row - 1][columnClicked + column - 1].isCovered
&& (rowClicked + row - 1 > 0) && (columnClicked + column - 1 > 0)
&& (rowClicked + row - 1 < 9) && (columnClicked + column - 1 < 9)) {
rippleUncover(rowClicked + row - 1, columnClicked + column - 1);
}
}
}
}
}
public void uncoverAllMines()
{
 for (int i = 0; i < mData.length; i++)
 {
 for (int j = 0; j < mData[0].length; j++)
 {
 if (mData[i][j].isMine())
 {
 mData[i][j].setBackgroundResource(R.drawable.mine);
 mData[i][j].setUncovered();
 }
 }
 }
}
public void initMineField(int mines)
{
Random rnd = new Random();
for (int i = 0; i < mines; i++)
{
int randomRow = rnd.nextInt(mData.length);
int randomCol = rnd.nextInt(mData[0].length);
//if randomRow/Col happens to already have a mine,
//continue looking for another spot to fill
if (!mData[randomRow][randomCol].isMine())
{
mData[randomRow][randomCol].setMine(true);
mData[randomRow][randomCol].setTag(R.id.mine, true);
} else { //if it is already a mine, do random until you find an empty spot
while (mData[randomRow][randomCol].isMine())
{
randomRow = rnd.nextInt(mData.length);
randomCol = rnd.nextInt(mData[0].length);
}
//set mine
mData[randomRow][randomCol].setMine(true);
mData[randomRow][randomCol].setTag(R.id.mine, true);
}
}
// count number of mines in surrounding blocks
for (int row = 0; row < 8; row++) {
for (int column = 0; column < 8; column++) {
// check in all nearby blocks
for (int ii = row - 1; ii <= row + 1; ii++)
{
 for (int jj = column - 1; jj <= column + 1; jj++)
 {
 if (ii >= 0 && ii < 8 && jj >= 0 && jj <8) {
 if (mData[ii][jj].isMine()) mData[row][column].updateSurroundingNumber();
 }
 }
 }
 }
 }
}
public void setUncoveredMinesToFlags()
{
 for (int i = 0; i < mData.length; i++)
 {
 for (int j = 0; j < mData[0].length; j++) {
 if (mData[i][j].isMine()) {
 mData[i][j].setFlag(true);
 mData[i][j].setBackgroundResource(R.drawable.flag);
 }
 }
 }
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
 MenuInflater inflater = getMenuInflater();
 inflater.inflate(R.menu.game_activity_options, menu);
 return true;
}
@Override
protected void onResume() {
 super.onResume();
}
/*
Returns void and reveals/uncovers all mines, while not ending the game.
*/
public void revealMines()
{
 for (int i = 0; i < mData.length; i++)
 {
 for (int j = 0; j < mData[0].length; j++)
 {
 if (mData[i][j].isMine())
 {
 mData[i][j].setBackgroundResource(R.drawable.mine);
 mData[i][j].setUncovered();
 }
 }
 }
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
 // Handle item selection
 switch (item.getItemId()) {
 case R.id.action_cheat:
 revealMines();
 return true;
 default:
 return super.onOptionsItemSelected(item);
 }
}
public boolean checkGameFinished() {
 // check grid and see if all squares are uncovered
 for (int i = 0; i < mData.length; i++) {
 for (int j = 0; j < mData[0].length; j++ ) {
 if (mData[i][j].isCovered)
 {
 return false;
 }
 }
 }
setWinState();
return true;
}
private void setWinState() {
 AlertDialog.Builder builder = new AlertDialog.Builder(this);
 builder.setMessage(R.string.player1_win)
 .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//go back to main activity
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog, so do nothing
}
});
// Create the AlertDialog object and show it
builder.create().show();
}
}
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.*;
import java.util.Random;
public class GameActivity extends Activity {
private TableLayout mTableLayout;
private ImageButton mValidateButton;
private static final int mineCount = 10;
private final Tile[][] mData = new Tile[8][8]; //8x8 grid
public class Tile extends Button
{
 private boolean isMine;
 private boolean isFlag;
 private boolean isCovered;
 private int noSurroundingMines;
 public Tile(Context context)
 {
 super(context);
 }
 public Tile(Context context, AttributeSet attrs)
 {
 super(context, attrs);
 }
 public Tile(Context context, AttributeSet attrs, int defStyle)
 {
 super(context, attrs, defStyle);
 }
 public void setDefaults()
 {
 isMine = false;
 isFlag = false;
 isCovered = true;
 noSurroundingMines = 0;
 this.setBackgroundResource(R.drawable.tile);
 }
 public void setMine(boolean mine)
 {
 this.isMine = mine;
 if (isMine && !isCovered) //only show mine if isn't
 {
 this.setBackgroundResource(R.drawable.mine);
 }
 }
 public void setFlag(boolean flag)
 {
 this.isFlag = flag;
 if (flag)
 {
 this.setBackgroundResource(R.drawable.flag);
 }
 }
 public void setUncovered()
 {
 this.isCovered = false;
 if (isMine())
 {
 this.setBackgroundResource(R.drawable.mine);
 } else if (noSurroundingMines > -1) {
 switch (noSurroundingMines)
 {
 case 0:
 this.setBackgroundResource(R.drawable.sq0);
 break;
 case 1:
 this.setBackgroundResource(R.drawable.sq1);
 break;
 case 2:
 this.setBackgroundResource(R.drawable.sq2);
 break;
 case 3:
 this.setBackgroundResource(R.drawable.sq3);
 break;
 case 4:
 this.setBackgroundResource(R.drawable.sq4);
 break;
 case 5:
 this.setBackgroundResource(R.drawable.sq5);
 break;
 case 6:
 this.setBackgroundResource(R.drawable.sq6);
 break;
 case 7:
 this.setBackgroundResource(R.drawable.sq7);
 break;
 case 8:
 this.setBackgroundResource(R.drawable.sq8);
 break;
 }
 }
}
public void updateSurroundingNumber() {
 this.noSurroundingMines++;
}
public void setSurroundingNumber(int number)
{
 this.noSurroundingMines = number;
}
public boolean isMine()
{
 return this.isMine;
}
public boolean isFlag()
{
 return this.isFlag;
}
public int getNoSurroundingMines()
{
 return noSurroundingMines;
}
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle bundle) {
 super.onCreate(bundle);
 setContentView(R.layout.lib_game);
 mValidateButton = (ImageButton) findViewById(R.id.validate);
 mValidateButton.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 //check if win. if not, reset game
 if (!checkGameFinished()) {
 //reset game
 mValidateButton.setBackgroundResource(R.drawable.normal_smiley);
 initTiles();
 mTableLayout.removeAllViews();
 initTable();
 initMineField(mineCount);
 } else {
 v.setBackgroundResource(R.drawable.win_smiley);
 setUncoveredMinesToFlags();
 setWinState();
 }
 }
});
 mValidateButton.setBackgroundResource(R.drawable.normal_smiley);
 mTableLayout = (TableLayout) findViewById(R.id.game_view);
 mTableLayout.setShrinkAllColumns(true);
 initTiles();
 initTable();
 initMineField(mineCount);
}
private void initTiles()
{
 for (int i = 0; i < mData.length; i++) {
 for (int j = 0; j < mData[0].length; j++) {
 Tile tile = new Tile(this);
 tile.setDefaults();
 mData[i][j] = tile;
 }
 }
}
private void initTable()
{
 //setting up rows for tablelayout
 for (int i = 0; i < mData.length; i++)
 {
 TableRow row = new TableRow(this);
 for (int button = 0; button < mData[0].length; button++) {
 // and you have to add them to the TableRow
 mData[i][button].setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 //check if you won before anything incl. setting adjacent elements
 if (v.getTag(R.id.mine) != null)
 {
 Object tag = v.getTag(R.id.mine);
 if ((Boolean)tag)
 {
 //you clicked on a mine, so you lost
 v.setBackgroundColor(Color.RED);
 v.setBackgroundResource(R.drawable.mine);
 mValidateButton.setBackgroundResource(R.drawable.lose_smiley);
 //display all other mines
 uncoverAllMines();
 }
 }
rippleUncover((Integer)v.getTag(R.id.x), (Integer)v.getTag(R.id.y));
checkGameFinished();
}
});
mData[i][button].setTag(R.id.x, i);
mData[i][button].setTag(R.id.y, button);
row.addView(mData[i][button]);
}
// a new row has been constructed -> add to table
mTableLayout.addView(row);
}
}
private void rippleUncover(int rowClicked, int columnClicked)
{
// don't open mined rows
if (mData[rowClicked][columnClicked].isMine())
{
return;
}
// open clicked block
mData[rowClicked][columnClicked].setUncovered();
// if clicked block have nearby mines then don't open further
if (mData[rowClicked][columnClicked].getNoSurroundingMines() != 0 )
{
return;
}
// open next 3 rows and 3 columns recursively
for (int row = 0; row < 3; row++)
{
for (int column = 0; column < 3; column++)
{
// check all the above checked conditions
// if met then open subsequent blocks
if ((rowClicked + row - 1 >= 0) && (rowClicked + row - 1 < 8) && (columnClicked + column - 1 >= 0) &&
columnClicked + column - 1 < 8) {
if (mData[rowClicked + row - 1][columnClicked + column - 1].isCovered
&& (rowClicked + row - 1 > 0) && (columnClicked + column - 1 > 0)
&& (rowClicked + row - 1 < 9) && (columnClicked + column - 1 < 9)) {
rippleUncover(rowClicked + row - 1, columnClicked + column - 1);
}
}
}
}
}
public void uncoverAllMines()
{
 for (int i = 0; i < mData.length; i++)
 {
 for (int j = 0; j < mData[0].length; j++)
 {
 if (mData[i][j].isMine())
 {
 mData[i][j].setBackgroundResource(R.drawable.mine);
 mData[i][j].setUncovered();
 }
 }
 }
}
public void initMineField(int mines)
{
Random rnd = new Random();
for (int i = 0; i < mines; i++)
{
int randomRow = rnd.nextInt(mData.length);
int randomCol = rnd.nextInt(mData[0].length);
//if randomRow/Col happens to already have a mine,
//continue looking for another spot to fill
if (!mData[randomRow][randomCol].isMine())
{
mData[randomRow][randomCol].setMine(true);
mData[randomRow][randomCol].setTag(R.id.mine, true);
} else { //if it is already a mine, do random until you find an empty spot
while (mData[randomRow][randomCol].isMine())
{
randomRow = rnd.nextInt(mData.length);
randomCol = rnd.nextInt(mData[0].length);
}
//set mine
mData[randomRow][randomCol].setMine(true);
mData[randomRow][randomCol].setTag(R.id.mine, true);
}
}
// count number of mines in surrounding blocks
for (int row = 0; row < 8; row++) {
for (int column = 0; column < 8; column++) {
// check in all nearby blocks
for (int ii = row - 1; ii <= row + 1; ii++)
{
 for (int jj = column - 1; jj <= column + 1; jj++)
 {
 if (ii >= 0 && ii < 8 && jj >= 0 && jj <8) {
 if (mData[ii][jj].isMine()) mData[row][column].updateSurroundingNumber();
 }
 }
 }
 }
 }
}
public void setUncoveredMinesToFlags()
{
 for (int i = 0; i < mData.length; i++)
 {
 for (int j = 0; j < mData[0].length; j++) {
 if (mData[i][j].isMine()) {
 mData[i][j].setFlag(true);
 mData[i][j].setBackgroundResource(R.drawable.flag);
 }
 }
 }
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
 MenuInflater inflater = getMenuInflater();
 inflater.inflate(R.menu.game_activity_options, menu);
 return true;
}
@Override
protected void onResume() {
 super.onResume();
}
/*
Returns void and reveals/uncovers all mines, while not ending the game.
*/
public void revealMines()
{
 for (int i = 0; i < mData.length; i++)
 {
 for (int j = 0; j < mData[0].length; j++)
 {
 if (mData[i][j].isMine())
 {
 mData[i][j].setBackgroundResource(R.drawable.mine);
 mData[i][j].setUncovered();
 }
 }
 }
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
 // Handle item selection
 switch (item.getItemId()) {
 case R.id.action_cheat:
 revealMines();
 return true;
 default:
 return super.onOptionsItemSelected(item);
 }
}
public boolean checkGameFinished() {
 // check grid and see if all squares are uncovered
 for (int i = 0; i < mData.length; i++) {
 for (int j = 0; j < mData[0].length; j++ ) {
 if (mData[i][j].isCovered)
 {
 return false;
 }
 }
 }
setWinState();
return true;
}
private void setWinState() {
 AlertDialog.Builder builder = new AlertDialog.Builder(this);
 builder.setMessage(R.string.player1_win)
 .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//go back to main activity
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog, so do nothing
}
});
// Create the AlertDialog object and show it
builder.create().show();
}
}
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.*;
import java.util.Random;
public class GameActivity extends Activity {
private TableLayout mTableLayout;
private ImageButton mValidateButton;
private static final int mineCount = 10;
private final Tile[][] mData = new Tile[8][8]; //8x8 grid
public class Tile extends Button
{
 private boolean isMine;
 private boolean isFlag;
 private boolean isCovered;
 private int noSurroundingMines;
 public Tile(Context context)
 {
 super(context);
 }
 public Tile(Context context, AttributeSet attrs)
 {
 super(context, attrs);
 }
 public Tile(Context context, AttributeSet attrs, int defStyle)
 {
 super(context, attrs, defStyle);
 }
 public void setDefaults()
 {
 isMine = false;
 isFlag = false;
 isCovered = true;
 noSurroundingMines = 0;
 this.setBackgroundResource(R.drawable.tile);
 }
 public void setMine(boolean mine)
 {
 this.isMine = mine;
 if (isMine && !isCovered) //only show mine if isn't
 {
 this.setBackgroundResource(R.drawable.mine);
 }
 }
 public void setFlag(boolean flag)
 {
 this.isFlag = flag;
 if (flag)
 {
 this.setBackgroundResource(R.drawable.flag);
 }
 }
 public void setUncovered()
 {
 this.isCovered = false;
 if (isMine())
 {
 this.setBackgroundResource(R.drawable.mine);
 } else if (noSurroundingMines > -1) {
 switch (noSurroundingMines)
 {
 case 0:
 this.setBackgroundResource(R.drawable.sq0);
 break;
 case 1:
 this.setBackgroundResource(R.drawable.sq1);
 break;
 case 2:
 this.setBackgroundResource(R.drawable.sq2);
 break;
 case 3:
 this.setBackgroundResource(R.drawable.sq3);
 break;
 case 4:
 this.setBackgroundResource(R.drawable.sq4);
 break;
 case 5:
 this.setBackgroundResource(R.drawable.sq5);
 break;
 case 6:
 this.setBackgroundResource(R.drawable.sq6);
 break;
 case 7:
 this.setBackgroundResource(R.drawable.sq7);
 break;
 case 8:
 this.setBackgroundResource(R.drawable.sq8);
 break;
 }
 }
}
public void updateSurroundingNumber() {
 this.noSurroundingMines++;
}
public void setSurroundingNumber(int number)
{
 this.noSurroundingMines = number;
}
public boolean isMine()
{
 return this.isMine;
}
public boolean isFlag()
{
 return this.isFlag;
}
public int getNoSurroundingMines()
{
 return noSurroundingMines;
}
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle bundle) {
 super.onCreate(bundle);
 setContentView(R.layout.lib_game);
 mValidateButton = (ImageButton) findViewById(R.id.validate);
 mValidateButton.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 //check if win. if not, reset game
 if (!checkGameFinished()) {
 //reset game
 mValidateButton.setBackgroundResource(R.drawable.normal_smiley);
 initTiles();
 mTableLayout.removeAllViews();
 initTable();
 initMineField(mineCount);
 } else {
 v.setBackgroundResource(R.drawable.win_smiley);
 setUncoveredMinesToFlags();
 setWinState();
 }
 }
});
 mValidateButton.setBackgroundResource(R.drawable.normal_smiley);
 mTableLayout = (TableLayout) findViewById(R.id.game_view);
 mTableLayout.setShrinkAllColumns(true);
 initTiles();
 initTable();
 initMineField(mineCount);
}
private void initTiles()
{
 for (int i = 0; i < mData.length; i++) {
 for (int j = 0; j < mData[0].length; j++) {
 Tile tile = new Tile(this);
 tile.setDefaults();
 mData[i][j] = tile;
 }
 }
}
private void initTable()
{
 //setting up rows for tablelayout
 for (int i = 0; i < mData.length; i++)
 {
 TableRow row = new TableRow(this);
 for (int button = 0; button < mData[0].length; button++) {
 // and you have to add them to the TableRow
 mData[i][button].setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 //check if you won before anything incl. setting adjacent elements
 if (v.getTag(R.id.mine) != null)
 {
 Object tag = v.getTag(R.id.mine);
 if ((Boolean)tag)
 {
 //you clicked on a mine, so you lost
 v.setBackgroundColor(Color.RED);
 v.setBackgroundResource(R.drawable.mine);
 mValidateButton.setBackgroundResource(R.drawable.lose_smiley);
 //display all other mines
 uncoverAllMines();
 }
 }
rippleUncover((Integer)v.getTag(R.id.x), (Integer)v.getTag(R.id.y));
checkGameFinished();
}
});
mData[i][button].setTag(R.id.x, i);
mData[i][button].setTag(R.id.y, button);
row.addView(mData[i][button]);
}
// a new row has been constructed -> add to table
mTableLayout.addView(row);
}
}
private void rippleUncover(int rowClicked, int columnClicked)
{
// don't open mined rows
if (mData[rowClicked][columnClicked].isMine())
{
return;
}
// open clicked block
mData[rowClicked][columnClicked].setUncovered();
// if clicked block have nearby mines then don't open further
if (mData[rowClicked][columnClicked].getNoSurroundingMines() != 0 )
{
return;
}
// open next 3 rows and 3 columns recursively
for (int row = 0; row < 3; row++)
{
for (int column = 0; column < 3; column++)
{
// check all the above checked conditions
// if met then open subsequent blocks
if ((rowClicked + row - 1 >= 0) && (rowClicked + row - 1 < 8) && (columnClicked + column - 1 >= 0) &&
columnClicked + column - 1 < 8) {
if (mData[rowClicked + row - 1][columnClicked + column - 1].isCovered
&& (rowClicked + row - 1 > 0) && (columnClicked + column - 1 > 0)
&& (rowClicked + row - 1 < 9) && (columnClicked + column - 1 < 9)) {
rippleUncover(rowClicked + row - 1, columnClicked + column - 1);
}
}
}
}
}
public void uncoverAllMines()
{
 for (int i = 0; i < mData.length; i++)
 {
 for (int j = 0; j < mData[0].length; j++)
 {
 if (mData[i][j].isMine())
 {
 mData[i][j].setBackgroundResource(R.drawable.mine);
 mData[i][j].setUncovered();
 }
 }
 }
}
public void initMineField(int mines)
{
Random rnd = new Random();
for (int i = 0; i < mines; i++)
{
int randomRow = rnd.nextInt(mData.length);
int randomCol = rnd.nextInt(mData[0].length);
//if randomRow/Col happens to already have a mine,
//continue looking for another spot to fill
if (!mData[randomRow][randomCol].isMine())
{
mData[randomRow][randomCol].setMine(true);
mData[randomRow][randomCol].setTag(R.id.mine, true);
} else { //if it is already a mine, do random until you find an empty spot
while (mData[randomRow][randomCol].isMine())
{
randomRow = rnd.nextInt(mData.length);
randomCol = rnd.nextInt(mData[0].length);
}
//set mine
mData[randomRow][randomCol].setMine(true);
mData[randomRow][randomCol].setTag(R.id.mine, true);
}
}
// count number of mines in surrounding blocks
for (int row = 0; row < 8; row++) {
for (int column = 0; column < 8; column++) {
// check in all nearby blocks
for (int ii = row - 1; ii <= row + 1; ii++)
{
 for (int jj = column - 1; jj <= column + 1; jj++)
 {
 if (ii >= 0 && ii < 8 && jj >= 0 && jj <8) {
 if (mData[ii][jj].isMine()) mData[row][column].updateSurroundingNumber();
 }
 }
 }
 }
 }
}
public void setUncoveredMinesToFlags()
{
 for (int i = 0; i < mData.length; i++)
 {
 for (int j = 0; j < mData[0].length; j++) {
 if (mData[i][j].isMine()) {
 mData[i][j].setFlag(true);
 mData[i][j].setBackgroundResource(R.drawable.flag);
 }
 }
 }
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
 MenuInflater inflater = getMenuInflater();
 inflater.inflate(R.menu.game_activity_options, menu);
 return true;
}
@Override
protected void onResume() {
 super.onResume();
}
/*
Returns void and reveals/uncovers all mines, while not ending the game.
*/
public void revealMines()
{
 for (int i = 0; i < mData.length; i++)
 {
 for (int j = 0; j < mData[0].length; j++)
 {
 if (mData[i][j].isMine())
 {
 mData[i][j].setBackgroundResource(R.drawable.mine);
 mData[i][j].setUncovered();
 }
 }
 }
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
 // Handle item selection
 switch (item.getItemId()) {
 case R.id.action_cheat:
 revealMines();
 return true;
 default:
 return super.onOptionsItemSelected(item);
 }
}
public boolean checkGameFinished() {
 // check grid and see if all squares are uncovered
 for (int i = 0; i < mData.length; i++) {
 for (int j = 0; j < mData[0].length; j++ ) {
 if (mData[i][j].isCovered)
 {
 return false;
 }
 }
 }
setWinState();
return true;
}
private void setWinState() {
 AlertDialog.Builder builder = new AlertDialog.Builder(this);
 builder.setMessage(R.string.player1_win)
 .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//go back to main activity
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog, so do nothing
}
});
// Create the AlertDialog object and show it
builder.create().show();
}
}
Post Reopened by Simon Forsberg, SirPython, TheCoffeeCup, rolfl
indents argh
Source Link
John61590
  • 213
  • 2
  • 8
Loading
edited title
Source Link
John61590
  • 213
  • 2
  • 8
Loading
added 58 characters in body
Source Link
John61590
  • 213
  • 2
  • 8
Loading
added 58 characters in body
Source Link
John61590
  • 213
  • 2
  • 8
Loading
edited tags
Link
Simon Forsberg
  • 59.7k
  • 9
  • 157
  • 311
Loading
added gameactivity code
Source Link
John61590
  • 213
  • 2
  • 8
Loading
Post Closed as "Not suitable for this site" by 200_success
Source Link
John61590
  • 213
  • 2
  • 8
Loading
lang-java

AltStyle によって変換されたページ (->オリジナル) /