My problem is when i change the first parameter into over 300 in line 133, i get a java.lang.StackOverflowError in line 37.This line is a recursion. How can i solve this?
public class PathFindingOnSquaredGrid {
// given an N-by-N matrix of open cells, return an N-by-N matrix
// of cells reachable from the top
public static boolean[][] flow(boolean[][] open) {
int N = open.length;
boolean[][] full = new boolean[N][N];
for (int j = 0; j < N; j++) {
flow(open, full, 0, j);
}
return full;
}
// determine set of open/blocked cells using depth first search
public static void flow(boolean[][] open, boolean[][] full, int i, int j) {
int N = open.length;
// base cases
if (i < 0 || i >= N) return; // invalid row
if (j < 0 || j >= N) return; // invalid column
if (!open[i][j]) return; // not an open cell
if (full[i][j]) return; // already marked as open
full[i][j] = true;
flow(open, full, i+1, j); // down line 37
flow(open, full, i, j+1); // right line 38
flow(open, full, i, j-1); // left line 39
flow(open, full, i-1, j); // up line 40
}
// does the system percolate?
public static boolean percolates(boolean[][] open) {
int N = open.length;
boolean[][] full = flow(open);
for (int j = 0; j < N; j++) {
if (full[N-1][j]) return true;
}
return false;
}
//does the system percolate vertically in a direct way?
public static boolean percolatesDirect(boolean[][] open) {
int N = open.length;
boolean[][] full = flow(open);
int directPerc = 0;
for (int j = 0; j < N; j++) {
if (full[N-1][j]) {
// StdOut.println("Hello");
directPerc = 1;
int rowabove = N-2;
for (int i = rowabove; i >= 0; i--) {
if (full[i][j]) {
//StdOut.println("i: " + i + " j: " + j + " " + full[i][j]);
directPerc++;
}
else break;
}
}
}
// StdOut.println("Direct Percolation is: " + directPerc);
if (directPerc == N) return true;
else return false;
}
// draw the N-by-N boolean matrix to standard draw
public static void show(boolean[][] a, boolean which) {
int N = a.length;
StdDraw.setXscale(-1, N);;
StdDraw.setYscale(-1, N);
StdDraw.setPenColor(StdDraw.BLACK);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
if (a[i][j] == which)
StdDraw.square(j, N-i-1, .5);
else StdDraw.filledSquare(j, N-i-1, .5);
}
// draw the N-by-N boolean matrix to standard draw, including the points A (x1, y1) and B (x2,y2) to be marked by a circle
public static void show(boolean[][] a, boolean which, int x1, int y1, int x2, int y2) {
int N = a.length;
StdDraw.setXscale(-1, N);;
StdDraw.setYscale(-1, N);
StdDraw.setPenColor(StdDraw.BLACK);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
if (a[i][j] == which)
if ((i == x1 && j == y1) ||(i == x2 && j == y2)) {
StdDraw.circle(j, N-i-1, .5);
}
else StdDraw.square(j, N-i-1, .5);
else StdDraw.filledSquare(j, N-i-1, .5);
}
// return a random N-by-N boolean matrix, where each entry is
// true with probability p
public static boolean[][] random(int N, double p) {
boolean[][] a = new boolean[N][N];
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
a[i][j] = StdRandom.bernoulli(p);
return a;
}
// test client
public static void main(String[] args) {
ArrayList<Node> path=null;
Stopwatch timer;
// The following will generate a 10x10 squared grid with relatively few
obstacles in it
//The lower the second parameter, the more obstacles (black cells) are
generated
In here I was changing gird values to get test cases.
boolean[][] randomlyGenMatrix = random(350, 0.8); //line133
StdArrayIO.print(randomlyGenMatrix);
show(randomlyGenMatrix, true);
System.out.println();
//System.out.println("The system percolates: " + percolates(randomlyGenMatrix));
System.out.println();
//System.out.println("The system percolates directly: " + percolatesDirect(randomlyGenMatrix));
System.out.println();
Stopwatch timerFlow = new Stopwatch();
Scanner in = new Scanner(System.in);
System.out.println("Enter i for A > ");
int Ai = in.nextInt();
System.out.println("Enter j for A > ");
int Aj = in.nextInt();
System.out.println("Enter i for B > ");
int Bi = in.nextInt();
System.out.println("Enter j for B > ");
int Bj = in.nextInt();
// THIS IS AN EXAMPLE ONLY ON HOW TO USE THE JAVA INTERNAL WATCH
// Stop the clock ticking in order to capture the time being spent on inputting the coordinates
// You should position this command accordingly in order to perform the algorithmic analysis
StdOut.println("Elapsed time = " + timerFlow.elapsedTime());
//StdDraw.point(Ai, Bj);
// System.out.println("Coordinates for A: [" + Ai + "," + Aj + "]");
// System.out.println("Coordinates for B: [" + Bi + "," + Bj + "]");
show(randomlyGenMatrix, true, Ai, Aj, Bi, Bj);
String dis="";
while(!dis.equalsIgnoreCase("X")){
//Selecting the path
System.out.println("Enter Distance: (M)Manhattan|(E)Euclidean|(C)Chebyshev|(X)Exit");
dis=in.next();
timer=new Stopwatch();
path = new DijkstraAlgorithm(dis).distance(randomlyGenMatrix, Ai, Aj, Bi, Bj);
System.out.println("Elapsed time: "+timer.elapsedTime());
//Draw the path in the grid
for (Node node : path) {
StdDraw.filledCircle(node.y, 10 - node.x -1, .2);
}
}
System.exit(0);
}
}
The only thing you are using recursion for is to keep track of the locations that need to be checked. So you could instead have a queue of those locations, and keep processing the one popped off the head of the queue until the queue is empty. The body of the loop would look like the body of your flow method (except the initial tests would continue the loop instead of returning), but you would initialize the queue with the initial (i,j) location, and replace the recursive calls with enqueues of those locations.
Related
The contents of the matrix starts from 1 to the product of rows and columns. The method "scan" should print out as per following:
If the row is entered 4 and column is entered 7, the contents of the matrix should look like the image provided here:
the correct matrix
So far I have tried absolutely noting because I just don't know how to make this possible. I can print in zigzag, spiral but I just have no idea about this one. Please have mercy on me and grant me an insight.
This code currently prints out in a spiral pattern.
How should I modify this "scan" method so it satisfies the aforementioned condition?
import java.util.Scanner;
import java.util.Random;
public class that {
public static void main(String[] args) {
int range;
range = 100;
Scanner scn = new Scanner(System.in);
while(true) {
int m, n;
System.out.println("Enter the number of row: ");
m = scn.nextInt();
System.out.println("Enter the number of column: ");
n = scn.nextInt();
if(m <= 0||n <= 0) break;
int[][] tab = new int[m][n];
generate(tab, range);
scan(tab);
}
scn.close();
}
static int len(int x) { return (""+x).length(); }
static void generate(int[][] tab, int range) {
// Random generation
Random rg = new Random();
for(int i=0; i<tab.length; ++i)
for(int j=0; j<tab[0].length; ++j)
tab[i][j] = rg.nextInt(2*range) - range;
}
static void scan(int[][] tab) {
int m = tab.length;
int n = tab[0].length;
int totalWidth = 0;
int num = 1;
int rowStart = m - 1, rowEnd = 0, colStart = 0, colEnd = n - 1;
// Compute column widths
int[] colw = new int[n];
for(int j=0; j<n; ++j) { // For every column look down
colw[j] = len(j); // (""+j).length();
for(int i=0; i<m; ++i) {
int w = len(tab[i][j]); //("" + tab[i][j]).length();
if(w > colw[j]) colw[j] = w;
}
totalWidth += colw[j];
}
// Printing
int ris = len(m-1); // row index size
System.out.printf("%"+ris+"s ", " ");
for(int j=0; j<n; ++j)
System.out.printf("%" + colw[j] +"d ", j);
System.out.println();
System.out.printf("%"+ris+"s+"," ");
for(int j=0; j<totalWidth+n-1; ++j)
System.out.printf("-");
System.out.println();
while (rowStart >= rowEnd && colStart <= colEnd) {
// Print leftmost column from bottom to top
if (colStart <= colEnd) {
for (int i = rowStart; i >= rowEnd; i--) {
tab[i][colStart] = num++;
}
colStart++;
}
// Print top row from right to left
if (rowStart >= rowEnd) {
for (int i = colStart; i <= colEnd; i++) {
tab[rowEnd][i] = num++;
}
rowEnd++;
}
// Print rightmost column from top to bottom
if (colStart <= colEnd) {
for (int i = rowEnd; i <= rowStart; i++) {
tab[i][colEnd] = num++;
}
colEnd--;
}
// Print bottom row from left to right
if (rowStart >= rowEnd) {
for (int i = colEnd; i >= colStart; i--) {
tab[rowStart][i] = num++;
}
rowStart--;
}
}
// Prints the matrix
for(int i=0; i<m; ++i) {
System.out.printf("%"+ris+"d|", i);
for(int j=0; j<n; ++j)
System.out.printf("%" + colw[j] +"d ", tab[i][j]);
System.out.println();
}
System.out.println();
}
}
I have trouble saving each step of sorting quickstep. I wrote this but its not printing anything...
I want to make javafx application with feature that i can push next button and it makes one step and back button which goes step back. So i will run the whole quicksort and save all the iterations to matrix and later i will be showing each column of the matrix bz clicking next and back. So i wanted to strat from beginning but im stuck in saving the steps.
Edit:
P.S. I know should print the matrix each step and i dont want that, i will add some condition later.
public class QS {
public static void main(String[] args) {
int[] x = { 9, 2, 4, 7, 3, 7, 10 };
System.out.println(Arrays.toString(x));
final int [] [] test = {
{1,2,3},
{4,5,6},
{7,8,9}
};
//for (int p = 0; p < test.length; p++){
// for (int k = 0; k < test[p].length; k++){
// System.out.print(test[p][k] + " ");
// }
// System.out.println();
//}
int low = 0;
int high = x.length - 1;
quickSort(x, low, high);
System.out.println(Arrays.toString(x));
int [] [] save = new int [9] [x.length];
}
public static void quickSort(int[] arr, int low, int high) {
if (arr == null || arr.length == 0)
return;
if (low >= high)
return;
// pick the pivot
int middle = low + (high - low) / 2;
int pivot = arr[middle];
// make left < pivot and right > pivot
int i = low, j = high;
while (i <= j) {
while (arr[i] < pivot)
i++;
while (arr[j] > pivot)
j--;
if (i <= j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
}
int[][] save = new int[9][arr.length];
int index = 0;
// recursively sort two sub parts
if (low < j)
quickSort(arr, low, j);
for (int h=0; h>arr.length+1; h++){
save [index] [h] = arr [h];
index++;
for (int e = 0; e < save.length; e++) {
for (int f = 0; f < save[e].length; f++) {
System.out.print(save[e][f] + " ");
}
System.out.println();
}
}
if (high > i)
quickSort(arr, i, high);
for (int h=0; h>arr.length+1; h++){
save [index] [h] = arr [h];
index++;
for (int e = 0; e < save.length; e++) {
for (int f = 0; f < save[e].length; f++) {
System.out.print(save[e][f] + " ");
}
System.out.println();
}
}
}
}
In the for loops like this one:
for (int h=0; h>arr.length+1; h++){/*code*/}
Presumably, it should be a smaller-than sign:
for (int h=0; h<arr.length+1; h++){/*code*/}
Otherwise h is always bigger than arr.length+1, making the condition false and and the loop just stops there.
I have run my code to get shorted distance from two point which we giving.my grid & everything working suddenly there got issue with jave PriorityQueue error n another error in my code i cant figure out what is it.help me to sort out this.
I have two classes called pathfinding & algo code separately.I'm passing 4 values to methord,start point n ending point ,grid size & blocked areas.
public class PathFindingOnSquaredGrid {
// given an N-by-N matrix of open cells, return an N-by-N matrix
// of cells reachable from the top
public static boolean[][] flow(boolean[][] open) {
int N = open.length;
boolean[][] full = new boolean[N][N];
for (int j = 0; j < N; j++) {
flow(open, full, 0, j);
}
return full;
}
// determine set of open/blocked cells using depth first search
public static void flow(boolean[][] open, boolean[][] full, int i, int j) {
int N = open.length;
// base cases
if (i < 0 || i >= N) return; // invalid row
if (j < 0 || j >= N) return; // invalid column
if (!open[i][j]) return; // not an open cell
if (full[i][j]) return; // already marked as open
full[i][j] = true;
flow(open, full, i+1, j); // down
flow(open, full, i, j+1); // right
flow(open, full, i, j-1); // left
flow(open, full, i-1, j); // up
}
// does the system percolate?
public static boolean percolates(boolean[][] open) {
int N = open.length;
boolean[][] full = flow(open);
for (int j = 0; j < N; j++) {
if (full[N-1][j]) return true;
}
return false;
}
// does the system percolate vertically in a direct way?
public static boolean percolatesDirect(boolean[][] open) {
int N = open.length;
boolean[][] full = flow(open);
int directPerc = 0;
for (int j = 0; j < N; j++) {
if (full[N-1][j]) {
// StdOut.println("Hello");
directPerc = 1;
int rowabove = N-2;
for (int i = rowabove; i >= 0; i--) {
if (full[i][j]) {
// StdOut.println("i: " + i + " j: " + j + " " + full[i][j]);
directPerc++;
}
else break;
}
}
}
// StdOut.println("Direct Percolation is: " + directPerc);
if (directPerc == N) return true;
else return false;
}
// draw the N-by-N boolean matrix to standard draw
public static void show(boolean[][] a, boolean which) {
int N = a.length;
StdDraw.setXscale(-1, N);;
StdDraw.setYscale(-1, N);
StdDraw.setPenColor(StdDraw.BLACK);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
if (a[i][j] == which)
StdDraw.square(j, N-i-1, .5);
else StdDraw.filledSquare(j, N-i-1, .5);
}
// draw the N-by-N boolean matrix to standard draw, including the points A (x1, y1) and B (x2,y2) to be marked by a circle
public static void show(boolean[][] a, boolean which, int x1, int y1, int x2, int y2) {
int N = a.length;
StdDraw.setXscale(-1, N);;
StdDraw.setYscale(-1, N);
StdDraw.setPenColor(StdDraw.BLACK);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
if (a[i][j] == which)
if ((i == x1 && j == y1) ||(i == x2 && j == y2)) {
StdDraw.circle(j, N-i-1, .5);
}
else StdDraw.square(j, N-i-1, .5);
else StdDraw.filledSquare(j, N-i-1, .5);
}
// return a random N-by-N boolean matrix, where each entry is
// true with probability p
public static boolean[][] random(int N, double p) {
boolean[][] a = new boolean[N][N];
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
a[i][j] = StdRandom.bernoulli(p);
return a;
}
// test client
public static void main(String[] args) {
// boolean[][] open = StdArrayIO.readBoolean2D();
// The following will generate a 10x10 squared grid with relatively few obstacles in it
// The lower the second parameter, the more obstacles (black cells) are generated
boolean[][] randomlyGenMatrix = random(10, 0.8);
StdArrayIO.print(randomlyGenMatrix);
show(randomlyGenMatrix, true);
System.out.println();
System.out.println("The system percolates: " + percolates(randomlyGenMatrix));
System.out.println();
System.out.println("The system percolates directly: " + percolatesDirect(randomlyGenMatrix));
System.out.println();
// Reading the coordinates for points A and B on the input squared grid.
// THIS IS AN EXAMPLE ONLY ON HOW TO USE THE JAVA INTERNAL WATCH
// Start the clock ticking in order to capture the time being spent on inputting the coordinates
// You should position this command accordingly in order to perform the algorithmic analysis
Stopwatch timerFlow = new Stopwatch();
Scanner in = new Scanner(System.in);
System.out.println("Enter i for A > ");
int Ai = in.nextInt();
System.out.println("Enter j for A > ");
int Aj = in.nextInt();
System.out.println("Enter i for B > ");
int Bi = in.nextInt();
System.out.println("Enter j for B > ");
int Bj = in.nextInt();
// THIS IS AN EXAMPLE ONLY ON HOW TO USE THE JAVA INTERNAL WATCH
// Stop the clock ticking in order to capture the time being spent on inputting the coordinates
// You should position this command accordingly in order to perform the algorithmic analysis
StdOut.println("Elapsed time = " + timerFlow.elapsedTime());
// System.out.println("Coordinates for A: [" + Ai + "," + Aj + "]");
// System.out.println("Coordinates for B: [" + Bi + "," + Bj + "]");
ArrayList<int[]> blockList=new ArrayList<>();
for (int i = 0; i < randomlyGenMatrix.length; i++) {
for (int j = 0; j < randomlyGenMatrix[i].length; j++) {
if(randomlyGenMatrix[i][j]){
blockList.add(new int[]{i,j});
}
}
}
int[][] blockArray=new int[blockList.size()][2];
for (int i = 0; i < blockList.size(); i++) {
blockArray[i] = blockList.get(i);
System.out.println("############"+blockList.get(i));
// blockArray[j] = blockList.get(j);
}
//show(randomlyGenMatrix, true, Ai, Aj, Bi, Bj,);
show(randomlyGenMatrix, true, Ai, Aj, Bi, Bj);
AStarCopied.test(10,10, Ai, Aj, Bi, Bj, blockArray);
}
}
I've been working on a Game of Life assignment and am nearing the stage of completion, but am struggling to figure out what I've messed up on such that the GOL rules (and Fredkin rules that the assignment requires us to implement as well) are not generating the proper result.
As I have little experience working with graphics I decided to output everything in the interactions window (using Dr.Java). (It's used to set up menu options like the scale, coordinates (you manually enter), generations, and output the final generation of whichever rule you choose to run (GOL or Fredkin).
The program nextGeneration takes a Boolean array map from the main method (where people input coordinates), and should change it to correspond to the next generation of the Game of Life. This happens by creating an entirely new 2D array, map2, which gets values loaded into it based on the number of neighbors which are turned on for each point. At the end of the program, map gets loaded into map2.(Note: this isn't original, this is required by the assignment)
The program living merely checks if a point in the map array is on or off. countNeighbors takes the 8 neighbors of a particular square, passes them each through the living method, and returns the number of neighbors which are currently on. Since countNeighbors sometimes demands either a negative number, or a number greater than the scale of the map, we implemented conditions in living to create that wraparound universe.
I think the problem(s) most likely arise in nextGeneration. I am somewhat tense about using the operand "or" (written as || ), and I think this may be where I screwed up. If you could just look through the code, and see if what I have said is true is written as true, that would be absolutely wonderful.
Below is the code for the program. It also utilizes a Keyboard.class file which I'm happy to post (however one would do that) if that helps (it's required to compile).
public class GameOfLife {
public static void main(String[] args) {
int r = 0; //rules set. Either 0 or 1, 0 for life game, 1 for Fredkin game
int i = 0; // looping variable
int j = 0; // looping variable
int b = 0; // used to read integer inputs from keyboard
int x = 0; // used during the stage where the player manually changes the board. Represents x coordinate.
int y = 0; // used during the stage where the player manually changes the board. Represents x coordinate.
int gen = 0; //number of generations to be skipped before printing out new map
int scale = 0;
boolean[][] map = new boolean[0][0];
System.out.println("Start game? y/n");
String a = Keyboard.readString();
if (a.equals("n")) {
return;
} else {
System.out.println("Do you wish to know the rules? y/n");
a = Keyboard.readString();
if (a.equals("y")) {
System.out.println("Each coordinate in the printed graph is represented by a 0 or a .");
System.out.println("0 represents a live cell, . represents a dead one.");
System.out.println("Each cell has 8 neighboring cells.");
System.out.println("There are two ways in which the game can be played.");
System.out.println("In the Life model, if a cell has 3 neighbors, if dead, it turns on.");
System.out.println("If it has 2 neighbors, it keeps its current condition.");
System.out.println("Else, it dies. Brutal.");
System.out.println("In the Fredkin Model, only non-diagnol neighbors count.");
System.out.println("If a cell has 1 or 3 neighbors, it is alive.");
System.out.println("If it has 0, 2 or 4, it dies. WAY more Brutal.");
}
System.out.println("Do you want to play by Fredkin or Life Rules? 0 for life, 1 for Fredkin");
while (i == 0) {
b = Keyboard.readInt();
if (b == 1) {
r = 1;
i = 1;
}
if (b == 0) {
r = 0;
i = 1;
}
}
while (j == 0) {
System.out.println("What scale would you like to use? Please enter an integer larger than 4");
b = Keyboard.readInt();
if (b >= 5) {
map = new boolean[b][b];
scale = b;
j = 1;
} else {
System.out.println("Come on, buddy, read the rules");
}
}
j = 0;
while (j == 0) {
System.out.println("Do you want to enter coordinates? y to continue entering coordinates, n to go to next option");
a = Keyboard.readString();
if (a.equals("y")) {
i = 0;
while (i == 0) {
System.out.println("Please enter a value for an X coordinate from 0 to " + (scale - 1));
b = Keyboard.readInt();
if (b >= 0) {
if (b < scale) {
i = 1;
x = b;
}
}
}
i = 0;
while (i == 0) {
System.out.println("Please enter a value for a Y coordinate from 0 to " + (scale - 1));
b = Keyboard.readInt();
if (b >= 0) {
if (b < scale) {
i = 1;
y = b;
}
}
}
map[y][x] = true;
printgame(map);
} else {
if (a.equals("n")) {
j = 1;
}
}
}
i = 0;
while (i == 0) {
System.out.println("How many generations would you like to skip ahead? Please enter a value greater than 0");
b = Keyboard.readInt();
if (b > 0) {
gen = b;
i = 1;
}
}
i = 0;
if (r == 0) {
for (i = 0; i <= gen; i++) {
nextGeneration(map);
}
printgame(map);
} else {
if (r == 1) {
for (i = 0; i <= gen; i++) {
FredGen(map);
}
printgame(map);
}
}
}
}
public static void printgame(boolean[][] map) {
int x = map[0].length;
int y = map[0].length;
int i = 0;
int j = 0;
char c;
String Printer = "";
for (j = 0; j < y; j++) {
for (i = 0; i < x; i++) {
if (map[j][i]) {
c = '0';
} else {
c = '.';
}
Printer = (Printer + " " + c);
}
System.out.println(Printer);
Printer = new String("");
}
}
private static void nextGeneration(boolean[][] map) {
int x = map[0].length;
int y = map[0].length;
int[][] neighborCount = new int[y][x];
boolean[][] map2 = new boolean[y][x];
for (int j = 0; j < y; j++)
for (int i = 0; i < x; i++)
neighborCount[j][i] = countNeighbors(j, i, map);
//this makes a new generation array
for (int j = 0; j < y; j++) {
for (int i = 0; i < x; i++) {
if (map[j][i] = true) { //assumes initial value of array is true (AKA "ALIVE")
if (neighborCount[j][i] == 3) { //check if alive AND meeting condition for life
map2[j][i] = true; //sets character array coordinate to ALIVE: "0"
} else if ((neighborCount[j][i] <= 2) || (neighborCount[j][i] > 3)) { //check if dead from isolation or overcrowding
map2[j][i] = false; //sets character array coordinate to DEAD: "."
}
}
}
}
map = map2;
}
private static int countNeighbors(int j, int i, boolean[][] map) { //counts all 8 elements living/dea of 3x3 space surrounding and including living/dead central coordinate)
return living(j - 1, j - 1, map) + living(j - 1, i, map) +
living(j - 1, i + 1, map) + living(j, i - 1, map) + living(j, i + 1, map) +
living(j + 1, i - 1, map) + living(j + 1, i, map) + living(j + 1, i + 1, map);
}
private static int living(int j, int i, boolean[][] map) {
int x = map[0].length - 1;
if (i < 0) {
i = i + x;
} else {
i = i % x;
}
if (j < 0) {
j = j + x;
} else {
j = j % x;
}
if (map[j][i] == true) {
return 1;
} else {
return 0;
}
}
private static void FredGen(boolean[][] map) {
int x = map[0].length;
int y = map[0].length;
int[][] neighborCount = new int[y][x];
for (int j = 0; j < y; j++)
for (int i = 0; i < x; i++)
neighborCount[j][i] = Freddysdeady(j, i, map);
//this makes a new generation array
for (int j = 0; j < y; j++)
for (int i = 0; i < x; i++)
if (map[j][i] = true) { //assumes initial value of array is true (AKA "ALIVE")
if ((neighborCount[j][i] < 1) || (neighborCount[j][i] == 2) || (neighborCount[j][i] > 3)) { //check if dead from isolation or overcrowding
map[j][i] = false; //sets chracter array coordinate to DEAD: "."
} else if ((neighborCount[j][i] == 1) || (neighborCount[j][i] == 3)) { //check if alive AND meeting condition for life
map[j][i] = true; //sets character array coordinate to ALIVE: "0"
}
}
}
private static int Freddysdeady(int j, int i, boolean[][] map) {
return living(j - 1, i, map) + living(j, i - 1, map) + living(j, i + 1, map) + living(j + 1, i, map);
}
}
There might be other problems, here are a few that I could spot by eye:
In the nextGeneration method, you handle cases where a cell should stay alive or die, but you do not have anything for when cells should be born. You should have something like this:
if(map[x][y]) {
//should this cell stay alive? if yes = live, else die
} else {
//should a cell be born in this slot? if yes = born, else nothing
}
This is a minor issue, still in nextGeneration, in if(count==3)live; else if(count <=2 || count > 3) die; is redundant, you only need if(count == 3) live; else die;
let us know, if you still have problems
When I call method backtrack a second time from within it (backtrack) because I need to go back two moves, it does not work. Does anyone have any idea? Here is my code:
// width of board
static final int SQUARES = 8;
// board
static boolean[][] board = new boolean[SQUARES][SQUARES];
// represents values for number of squares eliminated if queen is placed in square
static int[][] elimination = new int[SQUARES][SQUARES];
// store position of queens
static boolean[][] position = new boolean[SQUARES][SQUARES];
// store row
static int[] row = new int[8];
// store column
static int[] column = new int[8];
// Write a program to solve the Eight Queens problem
public static void main(String[] args)
{
Arrays.fill(row, -1);
Arrays.fill(column, -1);
// reset elimination table
fillElim();
// count queens on board
short counter = 0;
// while board is not full
while(counter < 8) {
// place next queen on board
placeQueen(-1, -1);
// reset elimination table
fillElim();
// backtrack and fill board back to this point
while(isFull() && counter < 7)
backtrack(counter);
counter++;
} // end while
System.out.println("Queens on board: " + counter);
printBoard();
for(int i = 0; i < row.length; i++)
System.out.println(column[i] + "/" + row[i]);
} // end method main
// Print elimination table
public static void printE()
{
for(int i[] : elimination) {
for(int j = 0; j < i.length; j++)
System.out.printf("%-3d", i[j]);
System.out.println();
} // end for
} // end printE
public static void printBoard()
{
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board.length; j++) {
if(board[i][j] && position[i][j])
System.out.print("o ");
else if(board[i][j])
System.out.print("x ");
else
System.out.print("% ");
} // end inner for
System.out.println();
} // end outer for
} // end method printBoard
// Write method to calculate how many squares are eliminated if queen is placed in that square
public static void fillElim()
{
// if any squares that could be eliminated already are eliminated, subtract 1
for(int i = 0; i < elimination.length; i++) {
for(int j = 0; j < elimination[i].length; j++) {
elimination[i][j] = openSquares(i, j);
} // end inner for
} // end outer for
} // end method fillElimination
// Number of squares eliminatable by placing queen in any given square
public static int openSquares(int row, int column)
{
// if square is already eliminated, it cannot be used
if(board[row][column])
return 0;
// total number of squares elimintable from any given square, count square itself
int total = 1 + openHorizontal(row) + openVertical(column) + openUpSlope(row, column) + openDownSlope(row, column);
return total;
} // end method openSquares
// Return number of open squares in a row
public static int openHorizontal(int row)
{
// total of row
int total = 0;
for(boolean b : board[row]) {
// if square is "true" (open), increment total open squares
if(!b)
total++;
} // end for
// return total not counting current square
return total - 1;
} // end method openHorizontal
// Return number of open squares in a column
public static int openVertical(int column)
{
// total of column
int total = 0;
// if square is "true" (open), increment total open squares
for(boolean[] b : board) {
// if square is "true" (open), increment total open square
if(!b[column])
total++;
} // end for
// return total not counting current square
return total - 1;
} // end method openVertical
// Return number of open squares in a column
public static int openDownSlope(int x, int y)
{
// total of downward-sloping diagonal
int total = 0;
// if square is "true" (open), increment total open squares
for(int i = 0; i < board.length; i++) {
// test all values before use to prevent array index errors
// all squares to the top right of the checking square
if(x+i >= 0 && x+i < board.length && y+i >= 0 && y+i < board.length) {
// else increment total
if(!board[x+i][y+i])
total++;
} // end if
// all squares to the bottom left of the checking square
if(x-i >= 0 && x-i < board.length && y-i >= 0 && y-i < board.length) {
// else increment total
if(!board[x-i][y-i])
total++;
} // end if
} // end for
// return total not counting current square
return total - 2;
} // end method openDownSlope
// Return number of open squares in a column
public static int openUpSlope(int x, int y)
{
// total of upward-sloping diagonal
int total = 0;
// if square is "true" (open), increment total open squares
for(int i = 0; i < board.length; i++) {
// test all values before use to prevent array index errors
// all squares to the top right of the checking square
if(x+i >= 0 && x+i < board.length && y-i >= 0 && y-i < board.length) {
// else increment total
if(!board[x+i][y-i])
total++;
} // end if
// all squares to the bottom left of the checking square
if(x-i >= 0 && x-i < board.length && y+i >= 0 && y+i < board.length) {
// else increment total
if(!board[x-i][y+i])
total++;
} // end if
} // end for
// return total not counting current square
return total - 2;
} // end method openDownSlope
// Are all squares on the board filled?
public static boolean isFull()
{
for(boolean b[] : board) {
for(boolean bb : b) {
if(!bb)
return false;
} // end inner for
} // end outer for
// if this point is reached, board is full
return true;
} // end method isFull
// Place a queen on the board
public static void placeQueen(int lastRow, int lastCol)
{
int[] bestSquare = bestMove(lastRow, lastCol);
System.out.println("&&&&&&");
for(int i = 0; i < row.length; i++)
System.out.println(row[i] + "/" + column[i]);
System.out.println("&&&&&&");
// assign queen to board
board[bestSquare[0]][bestSquare[1]] = true;
printBoard();
System.out.println();
// clear blocked squares from board
elimSquares(bestSquare[0], bestSquare[1]);
// reset elimination table
fillElim();
// store squares
for(int i = 0; i < row.length; i++) {
if(row[i] == -1) {
row[i] = bestSquare[0];
column[i] = bestSquare[1];
break;
} // end if
} // end for
// mark queen's position
position[bestSquare[0]][bestSquare[1]] = true;
printBoard();
} // end method placeQueen
// Return lowest number in elimination table
public static int[] bestMove(int lastRow, int lastCol)
{
// store lowest number - set to impossibly low
int low = 100;
// store coordinates
int[] move = {-1, -1};
// store limit of use
int limit;
if(lastRow == -1)
limit = 0;
else
limit = elimination[lastRow][lastCol];
// if lastRow is not -1, search for duplicate numbers after current square
if(lastRow != -1) {
// test for equal elimination numbers farther down on board
for(int i = lastRow; i < board.length; i++) {
for(int j = lastCol+1; j < board[i].length; j++) {
if(!board[i][j] && elimination[i][j] == limit) {
move[0] = i;
move[1] = j;
return move;
}
} // end inner for
} // end outer for
} // end if
// test for any available squares left on board
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[i].length; j++) {
if(!board[i][j] && elimination[i][j] > limit && elimination[i][j] < low)
low = elimination[i][j];
} // end inner for
} // end outer for
// get move coordinates for square, if needed to get best square after two backtracks
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[i].length; j++) {
if(!board[i][j] && elimination[i][j] == low) {
move[0] = i;
move[1] = j;
return move;
} // end if
} // end inner for
} // end outer for
return move;
} // end method bestMove
public static void elimSquares(int row, int column)
{
// total number of squares elimintable from any given square, count square itself
elimHorizontal(row);
elimVertical(column);
elimUpSlope(row, column);
elimDownSlope(row, column);
} // end method openSquares
// Eliminate row
public static void elimHorizontal(int row)
{
// eliminate row
for (int i = 0; i < board[row].length; i++)
board[row][i] = true;
} // end method elimHorizontal
// Eliminate column
public static void elimVertical(int column)
{
// eliminate column
for(boolean[] b : board)
b[column] = true;
} // end method elimVertical
// Eliminate downward slope
public static void elimDownSlope(int x, int y)
{
// loop through downward slope
for(int i = 0; i < board.length; i++) {
// test all values before use to prevent array index errors
// eliminate all squares to the bottom right of the checking square
if(x+i >= 0 && x+i < board.length && y+i >= 0 && y+i < board.length)
board[x+i][y+i] = true;
// eliminate all squares to the top left of the checking square
if(x-i >= 0 && x-i < board.length && y-i >= 0 && y-i < board.length)
board[x-i][y-i] = true;
} // end for
} // end method elimDownSlope
// Eliminate upward slope
public static void elimUpSlope(int x, int y)
{
// loop through upward slope
for(int i = 0; i < board.length; i++) {
// test all values before use to prevent array index errors
// eliminate all squares to the bottom right of the checking square
if(x+i >= 0 && x+i < board.length && y-i >= 0 && y-i < board.length)
board[x+i][y-i] = true;
// eliminate all squares to the top left of the checking square
if(x-i >= 0 && x-i < board.length && y+i >= 0 && y+i < board.length)
board[x-i][y+i] = true;
} // end for
} // end method elimDownSlope
// If not found solution and board is full
public static void backtrack(int lastMove)
{
// store last move
int lastRow = row[lastMove];
int lastCol = column[lastMove];
// clear board
resetBoard();
// go back 1 move
goBack(lastMove);
// refill board
for(int i = 0; i < row.length; i++) {
// escape if out of bounds
if(row[i] == -1)
break;
// replace queens
board[row[i]][column[i]] = true;
// fill elimination table
elimSquares(row[i], column[i]);
} // end for
// while no open squares, go back one more row
// keep track of times looped
int counter = 0;
while(!openSpaces(lastRow, lastCol)) {
System.out.println("backtrack " + counter);
backtrack(lastMove-1);
counter++;
} // end while
// set queen in square
placeQueen(lastRow, lastCol);
} // end method backtrack
// Clear board
public static void resetBoard()
{
// clear board
for(boolean[] b : board)
for(int j = 0; j < b.length; j++)
b[j] = false;
} // end method resetBoard
// Go back 1 move
public static void goBack(int lastMove)
{
// remove queen from last position
position[row[lastMove]][column[lastMove]] = false;
// remove last move from table
row[lastMove] = -1;
column[lastMove] = -1;
} // end method goBack
// Return number of open, untested spaces on board
public static boolean openSpaces(int lastRow, int lastCol)
{
// store number of open, untested squares
int squares = 0;
// store limit of use
int limit = elimination[lastRow][lastCol];
// store next limit for use if no more squares at limit
int nextLimit = limit + 1;
// test for equal elimination numbers farther down on board
for(int i = lastRow; i < board.length; i++) {
for(int j = lastCol+1; j < board[i].length; j++) {
if(!board[i][j] && elimination[i][j] == limit)
squares++;
} // end inner for
} // end outer for
// test for any available squares left on board
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[i].length; j++) {
if(!board[i][j] && elimination[i][j] >= nextLimit)
squares++;
} // end inner for
} // end outer for
return squares != 0;
} // end method openSpaces
This calls method goBack; method placeQueen, which calls method bestMove; and a few others. These three mentioned methods may also have an error, I do not know for sure:
// Go back 1 move
public static void goBack(int lastMove)
{
// remove queen from last position
position[row[lastMove]][column[lastMove]] = false;
// remove last move from table
row[lastMove] = -1;
column[lastMove] = -1;
} // end method goBack
// Place a queen on the board
public static void placeQueen(int lastRow, int lastCol)
{
int[] bestSquare = bestMove(lastRow, lastCol);
System.out.println("&&&&&&");
for(int i = 0; i < row.length; i++)
System.out.println(row[i] + "/" + column[i]);
System.out.println("&&&&&&");
// assign queen to board
board[bestSquare[0]][bestSquare[1]] = true;
printBoard();
System.out.println();
// clear blocked squares from board
elimSquares(bestSquare[0], bestSquare[1]);
// reset elimination table
fillElim();
// store squares
for(int i = 0; i < row.length; i++) {
if(row[i] == -1) {
row[i] = bestSquare[0];
column[i] = bestSquare[1];
break;
} // end if
} // end for
// mark queen's position
position[bestSquare[0]][bestSquare[1]] = true;
printBoard();
} // end method placeQueen
// Return lowest number in elimination table
public static int[] bestMove(int lastRow, int lastCol)
{
// store lowest number - set to impossibly low
int low = 100;
// store coordinates
int[] move = {-1, -1};
// store limit of use
int limit;
if(lastRow == -1)
limit = 0;
else
limit = elimination[lastRow][lastCol];
// if lastRow is not -1, search for duplicate numbers after current square
if(lastRow != -1) {
// test for equal elimination numbers farther down on board
for(int i = lastRow; i < board.length; i++) {
for(int j = lastCol+1; j < board[i].length; j++) {
if(!board[i][j] && elimination[i][j] == limit) {
move[0] = i;
move[1] = j;
return move;
}
} // end inner for
} // end outer for
} // end if
// test for any available squares left on board
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[i].length; j++) {
if(!board[i][j] && elimination[i][j] > limit && elimination[i][j] < low)
low = elimination[i][j];
} // end inner for
} // end outer for
// get move coordinates for square, if needed to get best square after two backtracks
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[i].length; j++) {
if(!board[i][j] && elimination[i][j] == low) {
move[0] = i;
move[1] = j;
return move;
} // end if
} // end inner for
} // end outer for
return move;
} // end method bestMove
I think that placeQueen is somehow being called before backtrack within the backtrack method.
P.S. This is not the same question as https://stackoverflow.com/questions/20111154/use-elimination-heuristic-to-solve-eight-queens-puzzle. There I was asking what I needed to do; here I am asking why my method did not work.
There is btw. a simpler way to solve the queens problem.
This program will print out all 92 solutions.
public class Queens {
static int counter = 0;
static int[] pos = new int[8];
static void printBoard(){
for(int p: pos) {
for(int i = 0; i < p; i++) System.out.print(".");
System.out.print("Q");
for(int i = p+1; i < 8; i++) System.out.print(".");
System.out.println();
}
System.out.println();
}
static boolean threatened(int x, int y){
for (int i = 0; i < y; i++){
int d = y - i;
if(pos[i] == x || pos[i] == x - d || pos[i] == x + d) {
return true;
}
}
return false;
}
static void place(int y) {
for(int x = 0; x < pos.length ; x++){
if(!threatened(x, y)){
pos[y] = x;
if(y == 7){
printBoard();
counter++;
} else{
place(y + 1);
}
}
}
}
public static void main(String[] args){
place(0);
System.out.print("found " + counter + " solutions");
}
}