Minesweeper game blocks around the mines - java

Hi so I'm building a program to create the classical minesweeper game in Java, and have almost everything down but I cant figure out how to check the sqaures around a mine and to write in the numbers (i.e. if there are one, two, three mines next to it). I only included the method it's under, but I can post the rest of the program if necessary. What should my approach be? Thanks!
private void countAdjacentMines()
{
for (int i = 0; i < mineField.length; i++)
{
for (int j = 0; j < mineField.length; j++)
{
if (!(mineField[i][j].getIsMine()))
{
mineField[i-1][j-1];
mineField[i-1][j];
mineField[i-1][j+1];
mineField[i][j-1];
mineField[i][j+1];
mineField[i+1][j-1];
mineField[i+1][j];
mineField[i+1][j+1];
mineField[i][j].setAdjacentMines(0);
}
} // end for loop rows
} // end for loop columns
} // end countAdjacentMines

Something like this:
private void countAdjacentMines()
{
for (int i = 0; i < mineField.length; i++)
{
for (int j = 0; j < mineField.length; j++)
{
if (!(mineField[i][j].getIsMine()))
{
int count = 0;
for (int p = i - 1; p <= i + 1; p++)
{
for (int q = j - 1; q <= j + 1; q++)
{
if (0 <= p && p < mineField.length && 0 <= q && q < mineField.length)
{
if (mineField[p][q].getIsMine())
++count;
}
}
}
mineField[i][j].setAdjacentMines(count);
}
} // end for loop rows
} // end for loop columns
} // end countAdjacentMines

For each item in that "list", do something like:
if ((i-1) >= 0 && (j-1) >= 0 && mineField[i-1][j-1].getIsMine()) {
numAdjacentMines++;
}
It's probably worth writing a helper function to do all of this, and then you just need to call it 8 times.

You're on the right track. You should be keeping a counter, that represents the count of adjacent mines that return true for .getIsMine().
if (!(mineField[i][j].getIsMine()))
{
counter = 0;
if (i-1 >= 0)
{
if (j-1 >=0 && mineField[i-1][j-1].getIsMine()) counter++;
if (mineField[i-1][j].getIsMine()) counter++;
if (j+1 < mineField.length && mineField[i-1][j+1].getIsMine()) counter++;
}
if (j-1 >=0 && mineField[i][j-1].getIsMine()) counter++;
if (j+1 < mineField.length && mineField[i][j+1].getIsMine()) counter++;
if (i+1 < mineField.length)
{
if (j-1 >=0 && mineField[i+1][j-1].getIsMine()) counter++;
if (mineField[i+1][j].getIsMine()) counter++;
if (j+1 < mineField.length && mineField[i+1][j+1].getIsMine()) counter++;
}
mineField[i][j].setAdjacentMines(counter);
}
You also need to be checking that all of those values (i-1, j-1, i+1, j+1) don't go outside the bounds of your array (i - 1 > -1, etc)
EDIT:: I think I covered all of the checks.

I'm not sure what you're trying to do. This statement, mineField[i-1][j-1]; and the ones like it just access data and do nothing with it.
I'm assuming that the array stores something that includes a boolean that tells you whether or not there's a mine in that space. If that's true, just make a counter and change those statements to something like if(mineField[i-1][j-1].hasMine()) counter++;. And then change the last statement to mineField[i][j].setAdjacentMines(counter);.

int sum = 0;
sum += mineField[i-1][j-1].getIsMine() ? 1 : 0;
sum += mineField[i-1][j].getIsMine() ? 1 : 0;
sum += mineField[i-1][j+1].getIsMine() ? 1 : 0;
sum += mineField[i][j-1].getIsMine() ? 1 : 0;
sum += mineField[i][j+1].getIsMine() ? 1 : 0;
sum += mineField[i+1][j-1].getIsMine() ? 1 : 0;
sum += mineField[i+1][j].getIsMine() ? 1 : 0;
sum += mineField[i+1][j+1].getIsMine() ? 1 : 0;
mineField[i][j].setAdjacentMines(sum);
This is count up how many are mines and use it properly. It may be more clean to create a loop to perform this calculation, since it is the same thing for each adjacent field.

Try something like:
private static int countAdjacentMines(int x, int y) {
int adjacentMines = 0;
for(int i = -1; i <= 1; i++) {
if((x + i < 0) || (x + i >= width)) {
continue;
}
for(int j = -1; j <= 1; j++) {
if((y + j < 0) || (y + j >= height)) {
continue;
}
if(mineField[x + i][y + j].getIsMine()) {
adjacentMines++;
}
}
}
return adjacentMines;
}
This should count the number of mines neighbouring a block at (x, y).

Related

Avoid going below index -1 with a for loop

How do I avoid going below 0 with this for loop ? When this loop executes, it checks if both the vehicle and the garage are in the same space. If not, it decrements the vehicle loop by --i to get the next available vehicle. when it reaches to index 0, it is going below index -1 causing the program to crash.
for (int i = vehicles.size() - 1; i >= 0;) {
for (int j = 0; j < garage.size();) {
if (this.garage.get(j).getSpace() == this.vehicles.get(i).getSpace()) {
if (this.garage.get(j).garageRequest(vehicles.get(i).getvehiclesType())
&& this.garage.get(j).getLimit() > 0) {
this.garage.get(j).addvehicles(vehicles.get(i));
this.vehicles.remove(i);
i--;
break;
} else {
j++;
}
} else {
i--;
j = 0;
}
}
i tried the following at the end
else if(i != 0) {
i--;
j = 0;
}
Add a second condition to your inner loop. That is, change
for (int j = 0; j < garage.size();) {
to
for (int j = 0; j < garage.size() && i >= 0;) {

Printing only NON-BOUNDARY and CORNER elements of an (n*n) array

I am to write a program that prints ONLY the NON-BOUNDARY AND CORNER elements of an (n*n) array, for my assignment, and this is the main part of the code:
The output I am getting is this:
As you can see, the non-boundary elements (6,7,10,11) are not in their correct positions, which I believe, is because of incorrect printing of tab spaces within the loop. (My code is totally a mess) I would like some help or suggestions to fix this. Thanks!
I generally find that flattening things (the if-conditions in particular), and putting conditions into boolean-returning methods helps. Try something like
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++ {
if (isCorner(i,j,n) || !isEdge(i,j,n)) {
//...
} else {
//...
}
}
System.out.println();
}
where isCorner(i,j,n) and isEdge(i,j,n) are defined something like
public boolean isCorner(int row, int column, int gridSize) {
//...
}
A you got a solution, just missing spaces, I'll add some smart things:
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
boolean visible = (i % (n - 1) == 0) == (j % (n - 1) == 0);
if (visible) {
System.out.printf(" %4d", a[i][j]);
} else {
System.out.print(" ");
}
}
System.out.println();
}
No longer any problems with tabs "\t", though I used spaces here.
Keep it simple, too many cases just cause problems - as you experienced.
The trick here is to consider whether to print or not. Hence I started with
a variable visible.
The border condition
i == 0 || i == n - 1
could also be written with modulo as
i % (n - 1) == 0
If this is "too smart", hard to grasp reading:
boolean iOnBorder = i % (n - 1) == 0;
boolean jOnBorder = j % (n - 1) == 0;
boolean visible = iOnBorder == jOnBorder;
The "X" pattern checks the _equivalence of i-on-border and j-on-border.
For the rest: formatted printf allows padding of a number.
Try this i have optimized your if condition
No need to again check for i == 0 or i == n-1
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i==0 || i==n-1){
if(j==0 || j==n-1){
System.out.print(a[i][j]);
}
}else{
if(j != 0 && j!= n-1){
System.out.print(a[i][j]);
}
}
System.out.print("\t");
}
System.out.println();
}
Just gave a try in case you might find it helpful.
public static void main(String[] args) throws ParseException {
int[][] ar = new int[4][4];
int[] input = new int[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
int pointer=0;
int imin=0,jmin=0,imax=3,jmax=3;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
ar[i][j]=input[pointer];
pointer++;
}
}
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(!((i==imax && j==jmin)||(i==imin && j==jmax)||i==j) && //For skipping the corners
(i == imin || j == jmin || i == imax || j == jmax)){// Not to print the borders
continue;
}
else {
System.out.println(ar[i][j]);
}
}
}
}

Checking for out of bounds in a 2D array

I'm trying to check the neighboring values of each element in a 2D array but am getting an IndexOutOfBoundsException when I reach the sides of the array or a corner. For example if my array is:
|2|4|2|7|8|
|8|1|0|5|6|
|0|3|1|5|2|
|1|9|7|2|0|
I know that all the neighbors of 8 are 7,5 and 6, but my if statements don't check the bounds properly. The code I have for this is:
int numOfRows = imageArray.length;
int numOfColumns = imageArray[0].length;
for(int i = 0; i < numOfRows; i++)
for(int j = 0; j < numOfColumns; j++)
if((j+1) < numOfColumns-1)
if((i+1) < numOfRows-1)
if((j-1) > 0 )
if((i-1) > 0 )
if((i+1) < numOfColumns-1 && (j+1) < numOfRows-1)
if((i-1) >= 0 && (j-1) >= 0)
if((i+1) < numOfColumns-1 && (j-1) >= 0)
if((i-1) >= 0 && (j+1) < numOfRows-1)
I've been working on this for a while and have gone through many different techniques to solve this. Any help would be great. Thanks.
If you're trying to get all the neighbor cells and do something with them, for example add them, then you need to do some sort of bounds checking, for example something modified from this could work:
for (int i = 0; i < numOfRows; i++) {
for (int j = 0; j < numOfCols; j++) {
// check all bounds out of range:
int iMin = Math.max(0, i - 1);
int iMax = Math.min(numOfRows - 1, i + 1);
int jMin = Math.max(0, j - 1);
int jMax = Math.min(numOfCols - 1, j + 1);
// loop through the above numbers safely
for (int innerI = iMin; innerI <= iMax; innerI++) {
for (int innerJ = jMin; innerJ <= jMax; innerJ++) {
if (i != innerI && j != innerJ) {
// do what needs to be done
}
}
}
}
}
Caveat: code has not been compiled nor tested and is mainly to show you the idea of what can be done rather than a copy-paste solution

JAVA Numberline errors

I am trying to make the following number line is Java
2,3,5,7,11,13,17 (Prime Numbers)
I tried this code
for(int i =0; i <= 100; i++) {
if(i < 2) {
continue;
}
for(int j = 2; j < 1; j++) {
if(i % j == 0) {
break;
} else {
System.out.print(i + ",");
}
}
}
But it doesn't work
Anyone help please?
Your code is quite poor, but the minimal amount of changes needed to make it work yields this code:
outerLoop:
for(int i = 0; i <= 100; i++) {
if(i < 2) {
continue;
}
for(int j = 2; j < i; j++) {
if(i % j == 0) {
continue outerLoop;
}
}
System.out.print(i + ",");
}
But a further improvement would be to start the first loop at 2 right away:
outerLoop:
for(int i = 2; i <= 100; i++) {
for(int j = 2; j < i; j++) {
// and so on...
EDITED
There are a lot of errors in that code, first of all that second loop is a infinite loop and second one that the System.out.println line should not be in second loop it should be at end of first loop! If you place it in second it will print numbers hundreds of time.
This is the correct code :
for(int i = 2; i <= 100; i++)//begin loop from 2 instead of 0
{
boolean flag = true;
for(int j = 2; j < i; j++)
{
if(i % j == 0)
{
flag = false;
break;
}
}
if(flag)System.out.print(i + ",");
}
You need to set a flag to check if a factor was found outside the loop.

how to write a conditional telling java that the array index is invalid

(this is a 2d array filled with objects) So the places marked "//Out of Grid" is where I don't know how to tell java that the index its looking for is not in the grid and to move on.
A basic over view of what im trying to accomplish is go thru each cell starting[0][0] and check all of its adjacent neighbors, as for the first check its neighbors would be [0][1],[1][0], and [1][1]. and then if the age of the object in the index is 0, do something..
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
int neighbor_x = x + i;
int neighbor_y = y + j;
if (neighbor_x < 0 || neighbor_x >= board.length) {
// Out of Grid
}
if (neighbor_y < 0 || neighbor_y >= board[neighbor_x].length) {
// Out of Grid
}
if (board[neighbor_x][neighbor_y].age == 0) {
nCount++;
if (board[x + i][y + j].getPreviousValue() == 0)
hCount++;
}
}
}
Unless you want to perform some operations, you can simply leave them out.
Out of bound exception can occur in the case where neighbor_x < 0 and neighbor_y >=0, when the second statement is being ran, the first condition is verified and the second throws an exception. You can simply use the only condition that matters
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
int neighbor_x = x + i;
int neighbor_y = y + j;
if ((neighbor_x >=0 && neighbor_x < board.length) &&
(neighbor_y >= 0 && neighbor_y < board[neighbor_x].length) &&
board[neighbor_x][neighbor_y].age == 0 ) {
nCount++;
if (board[x + i][y + j].getPreviousValue() == 0)
hCount++;
}
}
}
If this ever throws an exception, then just separate the conditions comme suite
if ( neighbor_x >=0 && neighbor_x < board.length )
if(neighbor_y >= 0 && neighbor_y < board[neighbor_x].length)
if(board[neighbor_x][neighbor_y].age == 0 )

Categories

Resources