Why isn't my game of life working correctly?
They don't always die when they're too crowded.
Relevant code is grann(x,y) which is supposed to return the number of living cells surrounding matrix[x][y],
run is supposed to calculate the next generation:
private int grann(int x,int y) {
int n = 0;
for(int i=-1; i<2; i++) {
for(int j=-1; j<2; j++) {
if(i!=0 || j!=0) {
if(matrix[x+i][y+j]) {
n++;
}
}
}
}
return n;
}
public void run() {
boolean[][] next = matrix;
for(int i=1; i<w; i++) {
for(int j=1; j<h; j++) {
int n = grann(i,j);
if(matrix[i][j]) {
if(!(n==2 || n==3)) {
next[i][j] = false;
}
} else {
if(n==3) {
next[i][j] = true;
}
}
}
}
matrix = next;
}
The object has a matrix, width and height.
matrix is a boolean[w+2][h+2], and w and h are ints.
If you don't know the rules of Conway's game of life:
http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
I think the problem is that grann should say:
if(i != 0 && j != 0)
because you want to eliminate just the centre square of the 3x3 area you are checking (the cell itself), not the row and column it is in also.
Related
While this code works and executes, there's a problem with it. The goal of the code is to move [x] across the matrix. It does but, after completing the first row, it prints a completely blank array. Meaning there is no point where both i == x and j == y.
Then, after it prints again, it continues where it left off. This means it never finishes circling the array by the prints allotted.
A picture to showcase what I mean:
.
How would I solve this? It's happening because, after that else property of moveX activates, j == 0 and y == 1; at least, that's what I have to assume is causing the blank print.
public class MovingX {
private int rowsN;
private int columnsM;
private int[][] matrixArr = new int[rowsN][columnsM];
private int x = 0;
private int y = 0;
public MovingX(int n, int m) {
rowsN = n;
columnsM = m;
matrixArr = new int[n][m];
}
public void forLoopGrid() {
for(int i = 0; i < matrixArr.length; i++) {
for(int j = 0; j < matrixArr.length; j++) {
if(i == x && j == y) System.out.print("[x] ");
else {
System.out.print("[ ] ");
}
}
System.out.println();
}
System.out.println();
}
public void moveX() {
if(x < 4) x++;
else {
x = 0;
y++;
}
}
public void runProgram() {
System.out.println("Program Starting");
System.out.println("Rows, Columns: " + rowsN + " " + columnsM);
for(int i = 0; i < (rowsN * columnsM); i++) {
forLoopGrid();
moveX();
}
System.out.println("Program Ending");
}
public static void main(String[] args) {
MovingX xLoop = new MovingX(4, 4);
xLoop.runProgram();
}
}
In your function moveX() you should change condition inside if-statement. Below correct version:
public void moveX(){
if(x < 3) x++;
else{
x = 0;
y++;
}
}
0 indexing can play a tricky factor in all kinds of loops. Since your moveX() method goes up to x = 4, the 0-index count of up to for is 0,1,2,3,4. That is 5 elements. Your matrix is 4x4. You want a count of x=3, giving 0,1,2,3. 4 elements!
You must change your moveX() to
public void moveX(){
if (x < 3)
x++;
else {
x = 0;
y++;
}
}
so basically I've been making a minesweeper clone in Java. I had it working perfectly until I added the game win and lose parts and the big opening print. Now when I run it some of the spots that are next to zero's don't get revealed, even though they should. I can't figure out where the bug is though. Here's my code:
/**
* A program to play Scat Scout...
*/
import static java.lang.System.*; // so you can write out.println() instead of System.out.println()
import java.util.*;
class ScatScout {
static final int boardSize = 10;
static final Random rand = new Random();
static final boolean SCAT = true;
static final boolean CLEAR = false;
static int clearCounter = 100;
static boolean gameWon = false;
static boolean gameLost = false;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean[][] board = new boolean[boardSize+2][boardSize+2]; // scat or no scat
boolean[][] exposed = new boolean[boardSize+2][boardSize+2]; // showing or hidden
int[][] counts = new int[boardSize+2][boardSize+2]; // number of neighbors with scat
if (args.length > 0) {
rand.setSeed(Integer.parseInt(args[0]));
}
System.out.println("comment explaining game");
createScat(board); //initialize the board
compareScat(board, counts); //find how many scat are next to each spot
while(!gameWon&&!gameLost){ //keep going until game win or loss
printBoard(board, counts, exposed);
System.out.println("Enter two integers (row and column):");
expose(input.nextInt()+1, input.nextInt()+1, board, exposed, counts);
if (gameLost){
for (int i = 1; i<= board.length-2; i++){
for (int j = 1; j<= board.length-2; j++){
if (!board[i][j]){
exposed[i][j] = true;
}
}
}
printBoard(board, counts, exposed);
System.out.print("You stepped in it! Yucky!"); //game lose
break;
}
gameWon = true; //game is one if all blanks but the bombs are exposed
for(int i = 1; i<= board.length-2; i++){
for(int j = 1; j<= board[0].length-2; j++){
if(!exposed[i][j]&&!board[i][j]){
gameWon=false; //otherwise continue loop
}
}
}
if (gameWon){
System.out.print("You cleared the scat! Congrats!"); //game win message
break;
}
}
input.close();
}
public static void printBoard(boolean[][] board, int[][] counts, boolean[][] exposed){ //initialize board
int numRows = counts.length;
int numCols = counts[0].length;
System.out.println(" 0123456789"); //print the border
for(int i=1; i<=numRows-2; i++){
System.out.print(i-1 + " "); //border
for(int j=1; j<=numCols-2; j++){
if (exposed[i][j] == true){
System.out.print(counts[i][j]); //print the scat near a spot if it's exposed
}
else{
System.out.print("*"); //print unknown spot
}
}
System.out.print(" ");
System.out.print(i-1); //border
System.out.println(" ");
}
System.out.println(" 0123456789"); //border
}
public static void createScat(boolean[][] board){ //randomly seed scat into field
for(int i=1; i<= board.length-2; i++){
int x = rand.nextInt(board.length-3)+1;
int y = rand.nextInt(board.length-3)+1;
if(x!=0&&x!=11&&y!=0&&y!=11&&board[x][y]==CLEAR){
board[x][y]=SCAT; //scat in this random spot
}
}
}
public static void compareScat(boolean[][] board, int[][] counts){ //checks #scat in surrounding spots
int numRows = counts.length;
int numCols = counts[0].length;
for(int i=1; i<=numRows-2; i++){
for(int j=1; j<=numCols-2; j++){
for(int ii=i-1; ii<=i+1; ii++){
for(int jj=j-1; jj<=j+1; jj++){
if(board[ii][jj]==SCAT){ //this looks at all scat in all directions around the original spot
counts[i][j]=counts[i][j]+1; //adds to the counter if scat found around it
}
}
}
}
}
}
static void expose(int c, int r, boolean[][] board, boolean[][] exposed, int[][] counts) { //exposes chosen spot
if (exposed[r][c]) return; // nothing to do
if (board[r][c]== SCAT){
gameLost=true; //lose game if choose a spot with scat
}
exposed[r][c] = true; // expose any neighbors that have zero counts
if (counts[r][c] > 0) return;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
int x = r+i;
int y = c+j;
if (!(i==1 && j==1) && x >= 1 && x < board.length-1 && y >= 1 && y < board[x].length-1) {
if (counts[x][y] == 0) {
expose(x, y, board, exposed, counts);
}
else {
exposed[x][y] = true;
}
}
}
}
}
}
I am doing a game called 1010! Probably some of you have heard of it. Bascially I encouter some trouble when writing the Algorithm for clearance.
The rule is such that if any row or any column is occupied, then clear row and column respectively.
The scoring is such that each move gains a+10*b points. a is the number of square in the input piece p and b is the total number of row&column cleared.
To start, I create a two dimensional Array board[10][10], poulate each elements in the board[][] with an empty square.
In the class of Square, it has public void method of unset()-> "empty the square" & boolean status() -> "judge if square is empty"In the class of piece, it has int numofSquare -> "return the number of square in each piece for score calculation"
In particular, I don't know how to write it if both row and column are occupied as they are inter-cross each other in an two dimensional array.
It fail the test under some condition, in which some of the squares are not cleared but they should have been cleared and I am pretty sure is the logic problem.
My thinking is that:
Loop through squares in first row and first column, record the number of square that are occupied (using c and r); if both are 10, clear row&column, otherwise clear row or column or do nothing.
reset the c &r to 0, loop through square in the second row, second column…
update score.
Basically the hard part is that if I seperate clear column and clear row algorithm ,I will either judge row or column first then clear them . However, as every column contains at least one square belong to the row, and every row contains at least one square belong to the column, there will be mistake when both row and column are full.
Thanks for help.
import java.util.ArrayList;
public class GameState{
public static final int noOfSquares = 10;
// the extent of the board in both directions
public static final int noOfBoxes = 3;
// the number of boxes in the game
private Square[][] board; // the current state of the board
private Box[] boxes; // the current state of the boxes
private int score; // the current score
// initialise the instance variables for board
// all squares and all boxes are initially empty
public GameState()
{
getboard();
score = 0;
board = new Square[10][10];
for(int i =0;i<board.length;i++){
for(int j =0;j<board[i].length;j++){
board[i][j] = new Square();
}
}
boxes = new Box[3];
for(int k =0;k<boxes.length;k++){
boxes[k] = new Box();
}
}
// return the current state of the board
public Square[][] getBoard()
{
return board;
}
// return the current score
public int getScore()
{
return score;
}
// place p on the board with its (notional) top-left corner at Square x,y
// clear columns and rows as appropriate
int r =0;
int c = 0;
int rowandcolumn = 0;
for (int row=0;row<10;row++){
for (int column=0;column<10;column++) {
if (board[row][column].status() == true){
c = c + 1;
if( c == 10 ) {
rowandcolumn = rowandcolumn + 1;
for(int z=0;z<10;z++){
board[row][z].unset(); //Clear column
}
}
}
if (board[column][row].status() == true){
r = r + 1;
if( r == 10) {
rowandcolumn = rowandcolumn + 1;
for(int q=0;q<10;q++){
board[q][row].unset(); //Clear row
}
}
}
}
r=0; //reset
c=0;
}
score = score + p.numberofBox()+10*rowandcolumn;
}
how about this
void Background::liquidate(int &score){
int arr_flag[2][10]; //0 is row,1 is column。
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 10; j++)
{
arr_flag[i][j] = 1;
}
}
//column
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (arr[i][j].type == 0)
{
arr_flag[0][i] = 0;
break;
}
}
}
//row
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (arr[j][i].type == 0)
{
arr_flag[1][i] = 0;
break;
}
}
}
//clear column
for (int i = 0; i < 10; i++)
{
if (arr_flag[0][i] == 1)
{
for (int j = 0; j < 10; j++)
{
arr[i][j].Clear();
}
}
}
//clear row
for (int i = 0; i < 10; i++)
{
if (arr_flag[1][i] == 1)
{
for (int j = 0; j < 10; j++)
{
arr[j][i].Clear();
}
}
}
}
I tried to write somme code for the idea I posted
// place p on the board with its (notional) top-left corner at Square x,y
// clear columns and rows as appropriate
int r =0;
int c = 0;
int rowandcolumn = 0;
int row=FindFirstRow();
int column=FindFirstColumn();
if(row!=-1 && column!=-1)
{
rowandcolumn++;
//actions here: row found and column found
//clear row and column
clearRow(row);
clearColumn(column);
}
else if(row!=-1)
{
//only row is found
//clear row
clearRow(row);
}
else if(column!=-1)
{
//only column is found
//clear column
clearColumn(column);
}
else
{
//nothing is found
}
public void clearRow(int row)
{
for(int i=0; i<10;i++)
{
board[row][i].unset();
}
}
public void clearColumn(int column)
{
for(int i=0; i<10;i++)
{
board[i][column].unset();
}
}
//this method returns the first matching row index. If nothing is found it returns -1;
public int FindFirstRow()
{
for (int row=0;row<10;row++)
{
int r=0;
for (int column=0;column<10;column++)
{
if (board[row][column].status() == true)
{
r = r + 1;
if( r == 10)
{
//row found
return row;
}
}
}
r=0; //reset
}
//nothing found
return -1;
}
//this method returns the first matching column index. If nothing is found it returns -1;
public int FindFirstColumn()
{
for (int column=0;column<10;column++)
{
int c=0;
for (int row=0;row<10;row++)
{
if (board[row][column].status() == true)
{
c = c + 1;
if( c == 10 )
{
//matching column found
return column;
}
}
}
c=0; //reset
}
//nothing found
return -1;
}
I'm attempting to write a program which solves the 8 Queens Problem using a 2 dimensional array of booleans. I will use backtracking to find the solution. I know this is not the optimal way to solve this problem, and that I should probably go for a 1D array for simplicity, but I want to solve it this way.
Right now I'm stuck on the function which is supposed to check whether a queen fits at a given coordinate. My row, column and down-right diagonal checks work, but I can't get the down-left diagonal check to work. I'm struggling to find the correct indexes of i and j (x and y) to start at, and which counter to increment/decrement for each iteration. Right now my function looks like this:
public static boolean fits(int x, int y) {
for(int i = 0; i < N; i++) {
if(board[x][i]) {
return false; // Does not fit on the row
}
}
for(int i = 0; i < N; i++) {
if(board[i][y]) {
return false; // Does not fit on the column
}
}
for(int i = Math.max(x-y, 0), j = Math.max(y-x, 0); i < N && j < N; i++, j++) {
if(board[i][j]) {
return false; // Down right diagonal issue
}
}
for(int i = Math.min(x+y, N-1), j = Math.max(N-1-x, 0); i >= 0 && j < N; i--, j++) {
if(board[i][j]) {
return false; // Supposed to check the down-left diagonal, but does not work.
}
}
return true;
}
As you can see there's a problem with the last loop here. I'd be very, very happy if someone could give me a working for-loop to check the down-left diagonal. Thanks in advance!
Edit: Here's the working code:
public class MyQueens {
static boolean[][] board;
static final int N = 8;
public static void main(String[] args) {
int p = 0;
board = new boolean[N][N];
board[1][1] = true;
System.out.println(fits(0, 2));
System.out.println(fits(2, 2));
}
public static boolean fits(int x, int y) {
for(int i = 0; i < N; i++) {
if(board[x][i]) {
return false; // Row
}
}
for(int i = 0; i < N; i++) {
if(board[i][y]) {
return false; // Column
}
}
for(int i = 0, j = 0; i < N && j < 0; i++, j++) {
if(board[i][j]) {
return false; // for right diagonal
}
}
int mirrorx = (N-1)-x;
for(int i = Math.max(mirrorx-y, 0), j = Math.max(y-mirrorx, 0); i < N && j < N; i++, j++) {
if(board[(N-1)-i][j]) {
return false;
}
}
return true;
}
}
I'm attempting to write a program which solves the 8 Queens Problem using a 2 dimensional array of booleans.
This is not the optimal representation, because you must use four loops to check if a queen can be placed or not. A much faster way of doing it is available.
For the purposes of your program, there are four things that must be free of threats in order for a queen to be placed:
A row,
A column,
An ascending diagonal, and
A descending diagonal
Each of these four things can be modeled with a separate array of booleans. There are eight rows, eight columns, fifteen ascending diagonals, and fifteen descending diagonals (including two degenerate cases of one-cell "diagonals" in the corners).
Declare four arrays row[8], col[8], asc[15] and desc[15], and use these four methods to work with it:
public static boolean fits(int r, int c) {
return !row[r] && !col[c] && !asc[r+c] && !desc[c-r+7];
}
public static void add(int r, int c) {
set(r, c, true);
}
public static void remove(int r, int c) {
set(r, c, false);
}
private static void set(int r, int c, boolean q) {
row[r] = col[c] = asc[r+c] = desc[c-r+7] = q;
}
Just flip the board horizontally and reuse the same algorithm as for the down right diagonal:
int mirrorx = (N-1)-x;
for(int i = Math.max(mirrorx-y, 0), j = Math.max(y-mirrorx, 0); i < N && j < N; i++, j++) {
if(board[(N-1)-i][j]) {
return false;
}
}
You could re-arrange it to make it more optimal.
Why don't you just use:
for(int i = 0, j = 0; i < N && j < 0; i++, j++) {
if(board[i][j]) {
return false; // for right diagonal
}
}
Similarly:
for(int i = 0, j = N-1; i < N && j >= 0; i++, j--) {
if(board[i][j]) {
return false; // for left diagonal
}
}
I'm working on the Conway's game of life program. I have the first two generations of cells printed out, but I can not get anymore printed. So I decided to use recursion so multiple batches of cells can be printed. My NewCells method creates the second generation. I thought that If I were to repeat said method by returning NewCells(c) instead of c, It would print out different results, but it prints out the same batch of cells over and over again.
public class Life {
public static boolean[][] NewCells(boolean[][] c)
{
int N = 5;
int o=0;
int p=0;
int livecnt = 0; //keeps track of the alive cells surrounding cell
int store = 0; //amount of surrounding cells for each individual cell
int livestore[] = new int[N*N];
System.out.println("Next Generation");
// Checks for the amount of "*" surrounding (o,p)
for (o=0; o < N; o++)
{
for (p=0; p<N; p++)
{
for (int k=(o-1); k <= o+1; k++)
{
for (int l =(p-1); l <=p+1; l++)
{
if ( k >= 0 && k < N && l >= 0 && l < N) //for the border indexes.
{
if (!(k== o && l==p)) //so livecnt won't include the index being checked.
{
if (c[k][l] == true)
{
livecnt++;
}
}
}
}
}
livestore[store]= livecnt;
livecnt = 0;
store++;
}
}
//Prints the next batch of cells
int counter= 0;
for (int i2 = 0; i2 <N; i2++)
{
for (int j2 = 0; j2 < N; j2++)
{
if (c[i2][j2] == false)
{
if (livestore[counter] ==3)
{
c[i2][j2]=true;
System.out.print("* ");
}
else
System.out.print("- ");
}
else if (c[i2][j2] == true)
{
if (livestore[counter] ==1)
{
c[i2][j2]= false;
System.out.print("- ");
}
else if (livestore[counter] >3)
{
c[i2][j2]= false;
System.out.print("- ");
}
else
System.out.print("* ");
}
counter++;
}
System.out.println();
}
return NewCell(c);
}
/*************************************************************************************************************************************************/
public static void main(String[] args)
{
int N = 5;
boolean[][] b = new boolean[N][N];
double cellmaker = Math.random();
int i = 0;
int j = 0;
int o=0;
int p=0;
int livecnt = 0; //keeps track of the alive cells surrounding cell
int store = 0; //amount of surrounding cells for each individual cell
int livestore[] = new int[N*N];
System.out.println("First Generation:");
// Makes the first batch of cells
for ( i = 0; i < N ; i++)
{
for ( j = 0; j< N; j++)
{
cellmaker = Math.random();
if (cellmaker > 0.5) // * = alive; - = dead
{
b[i][j]=true;
System.out.print( "* ");
}
if (cellmaker < 0.5)
{ b[i][j] = false;
System.out.print("- ");
}
}
System.out.println();
}
boolean[][] newcells = new boolean[N][N];
newcells = NewCells(b);
}
}
I do not think recursion is a good idea for this application. It leads to a StackOverflowError because each generation pushes another call stack frame. Recursion, as this program uses it, has no advantage over iteration.
Instead, put the main method call to NewCells in a loop. That way, you can run as many iterations as you like, regardless of stack size.
You are not calling NewCell from within NewCell, which is how recursion works.
I'm assuming it's not a typo in your question, but rather a lack of understanding of what it is and how it works, I recommend some reading on recursion in Java.
After you understand the basics, come back here for more help!