Java passing value back as 3 but shows as zero - java

For some reason the 'numAlive' variable shows as 3 but when passed back to numAlivePass it appears as '0' This is for Conways game of life
Edited as per comments below
public int countLiveNeighbour(int x, int y){
int numAlive = 0;
if(x >= 3 && y >= 3 && x < HEIGHT-3 && y < WIDTH-3)
{
if(generation[x][y+1] == ALIVE) {numAlive++;}
if(generation[x][y-1] == ALIVE) {numAlive++;}
if(generation[x+1][y] == ALIVE) {numAlive++;}
if(generation[x+1][y+1] == ALIVE) {numAlive++;}
if(generation[x+1][y-1] == ALIVE) {numAlive++;}
if(generation[x-1][y-1] == ALIVE) {numAlive++;}
if(generation[x-1][y+1] == ALIVE) {numAlive++;}
}
if(x ==31 && y==16){
System.out.println("ALIVE INclass: " + numAlive);
}
return numAlive;
}
//cell will be alive in next generation if alive cells = 3 or if already alive then 2 or 3
private int aliveCell(int x, int y){
int numAlivePass = 0;
numAlivePass = countLiveNeighbour(x, y);
if(x ==31 && y==16){
System.out.println(" NumAlivePass(ed) = " +numAlivePass+ " Live Neighbour Call = " + countLiveNeighbour(x, y));
}
int aliveState= 0;
if(x ==31 && y==16){
System.out.println(x + " x val 1, " + y + " x val 1, ALIVE 1: " + numAlivePass + " Alive State 1: " + aliveState);
}
if (numAlivePass > 3 || numAlivePass < 2){
aliveState = DEAD;
}
if(numAlivePass == 3){
aliveState = ALIVE;
System.out.println("Alive");
}
if (generation[x][y] == ALIVE && numAlivePass == 2){
aliveState = ALIVE;
System.out.println("Alive");
}
return aliveState;
}
This is all the code in this class inclusive of the code above:
package game_of_life;
import java.awt.Color;
import java.awt.Graphics;
public class CellularAnimation implements Animatable{
public static final int ALIVE = -1;
public static final int DEAD = 0;
public static final int HEIGHT = 100;
public static final int WIDTH = 100;
public static final int CELL_SIZE = 5;
int generation[][] = new int[HEIGHT][WIDTH];
int nextGeneration[][] = new int[HEIGHT][WIDTH];
public int getCellStatus(int x, int y) {
// TODO Auto-generated method stub
return generation[x][y];
}
public void populateNextGen(){
for(int x=0; x<=WIDTH-1; x++){
for(int y=0; y<=HEIGHT-1; y++){
nextGeneration[x][y] = aliveCell(x,y);
}
}
for(int x=0; x<=WIDTH-1; x++){
for(int y=0; y<=HEIGHT-1; y++){
generation[x][y] = nextGeneration[x][y];
}
}
}
public void initialise(){
for(int i = 0;i<HEIGHT-1;i++){
for(int z = 0;z<WIDTH-1;z++){
generation[z][i]= DEAD;
}
}
System.out.println("test1");
generation[30][15]= ALIVE;
generation[30][16]= ALIVE;
generation[30][17]= ALIVE;
}
public int countLiveNeighbour(int x, int y){
int numAlive = 0;
if(x >= 3 && y >= 3 && x < HEIGHT-3 && y < WIDTH-3)
{
if(generation[x][y++] == ALIVE) {numAlive++;}
if(generation[x][y--] == ALIVE) {numAlive++;}
if(generation[x++][y] == ALIVE) {numAlive++;}
if(generation[x++][y++] == ALIVE) {numAlive++;}
if(generation[x++][y--] == ALIVE) {numAlive++;}
if(generation[x--][y--] == ALIVE) {numAlive++;}
if(generation[x--][y++] == ALIVE) {numAlive++;}
}
if(x ==31 && y==16){
System.out.println("ALIVE INclass: " + numAlive);
}
return numAlive;
}
//cell will be alive in next generation if alive cells = 3 or if already alive then 2 or 3
private int aliveCell(int x, int y){
int numAlivePass = 0;
numAlivePass = countLiveNeighbour(x, y);
if(x ==31 && y==16){
System.out.println(" NumAlivePass(ed) = " +numAlivePass+ " Live Neighbour Call = " + countLiveNeighbour(x, y));
}
int aliveState= 0;
if(x ==31 && y==16){
System.out.println(x + " x val 1, " + y + " x val 1, ALIVE 1: " + numAlivePass + " Alive State 1: " + aliveState);
}
if (numAlivePass > 3 || numAlivePass < 2){
aliveState = DEAD;
}
if(numAlivePass == 3){
aliveState = ALIVE;
System.out.println("Alive");
}
if (generation[x][y] == ALIVE && numAlivePass == 2){
aliveState = ALIVE;
System.out.println("Alive");
}
return aliveState;
}
#Override
public void step() {
populateNextGen();
//paint(null);
//implement paint ect here
}
#Override
public void paint(Graphics pGraphics) {
//super.paint(pGraphics);
for(int i = 0; i<HEIGHT; i++){
for(int z = 0; z<WIDTH; z++){
if(generation[z][i] == ALIVE){
pGraphics.setColor(Color.BLACK);
System.out.println("test");
}
else{
pGraphics.setColor(Color.WHITE);
}
pGraphics.fillRect(z*CELL_SIZE,i*CELL_SIZE, CELL_SIZE, CELL_SIZE);
}
}
}
#Override
public int getWidth() {
// TODO Auto-generated method stub
return WIDTH*CELL_SIZE;
}
#Override
public int getHeight() {
// TODO Auto-generated method stub
return HEIGHT*CELL_SIZE;
}
}

Related

Game of life Oscillators and Spaceships not working

Hi so I am currently working on a game of life with javafx canvas. However there seems to be a bug in my algorithm. The still lifes are working however the rest is not, the patterns like the glider aren't moving the way they should. Im using a 2d int array, ALIVE is 1 and DEAD is 0. Here is my algorithm:
private void checkRules() {
int[][] newBoard = board;
int amountOfAliveNeighbours;
for (int y = 0; y < board.length; y++) {
for (int x = 0; x < board[y].length; x++) {
amountOfAliveNeighbours = getAmountOfAliveNeighbours(x, y);
if (board[y][x] == ALIVE) {
if (amountOfAliveNeighbours == 2 || amountOfAliveNeighbours == 3) {
newBoard[y][x] = ALIVE;
}else{
newBoard[y][x] = DEAD;
}
} else if (board[y][x] == DEAD){
if (amountOfAliveNeighbours == 3) {
newBoard[y][x] = ALIVE;
}else{
newBoard[y][x] = DEAD;
}
}
}
}
board = newBoard;
}
private int getAmountOfAliveNeighbours(int x, int y) {
int neighbours = 0;
// top left
if (x - 1 >= 0 && y - 1 >= 0) {
if (board[y - 1][x - 1] == ALIVE)
neighbours++;
}
// top center
if (y - 1 >= 0) {
if (board[y - 1][x] == ALIVE)
neighbours++;
}
// top right
if (x + 1 < board[0].length && y - 1 >= 0) {
if (board[y - 1][x + 1] == ALIVE)
neighbours++;
}
// middle left
if (x - 1 >= 0) {
if (board[y][x - 1] == ALIVE)
neighbours++;
}
// middle right
if (x + 1 < board[0].length) {
if (board[y][x + 1] == ALIVE)
neighbours++;
}
// bottom left
if (x - 1 >= 0 && y + 1 < board.length) {
if (board[y + 1][x - 1] == ALIVE)
neighbours++;
}
// bottom center
if (y + 1 < board.length) {
if (board[y + 1][x] == ALIVE)
neighbours++;
}
// bottom right
if (x + 1 < board[0].length && y + 1 < board.length) {
if (board[y + 1][x + 1] == ALIVE)
neighbours++;
}
return neighbours;
}
Allocate the memory for the temporary board like this:
int[][] newBoard = new int[board.length][board[0].length];
I would suggest to refactor calculation of neighbours:
private int getAmountOfAliveNeighbours(int x, int y) {
int neighbours = 0;
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
if ((dx !=0 || dy != 0) && isAlive(x + dx, y + dy)) {
neighbours++;
}
}
}
return neighbours;
}
private boolean isAlive(int x, int y) {
return (x >= 0) && (x < board.length) &&
(y >= 0) && (y < board[0].length) &&
(board[x][y] == ALIVE);
}

Unable to print values from Java program

I'm coding a knights tour program for a project and I have to print out starting coordinates, move count, and ending coordinates but they won't print. The code compiles I just can't get it to print the values at the end. I left out the instance field because it said I'm not allowed to post that much code.
import java.util.Random;
public class NonHeuristic {
public static boolean boundCheck() {
if((randX + x) <= 7 && (randX + x) >= 0)
if((randY + y) <= 7 && (randY + y) >= 0) {
return true;
}
else {
return false;
}
else {
return false;
}
}
public static void moveGenerator() {
Random rand = new Random();
int z = 0;
while(z == 0){
randX = rand.nextInt(5) - 2;
if(randX % 2 == 0 && randX != 0) {
randY = rand.nextInt(3) - 1;
if(randY != 0 && boundCheck() && newMoveCheck()) {
xMove = randX;
yMove = randY;
z = 1;
}//close nested if
}//close if
else if(randX % 2 != 0 && randX != 0) {
randY = rand.nextInt(5) - 2;
if(randY != 0 && Math.abs(randY) > 1 && boundCheck() && newMoveCheck()) {
xMove = randX;
yMove = randY;
z = 1;
}//close nested if
}//close if loop
}//close while loop
}//close moveGenerator
public static void startPoint() {
Random start = new Random();
xStart = start.nextInt(8);
x = xStart;
yStart = start.nextInt(8);
y = yStart;
//System.out.println(xStart + " " + yStart);
}//close startPoint
public static boolean newMoveCheck() {
if(chessboard[randX + x][randY + y] == 0)
return true;
else
return false;
}//close newmoveCheck
public static void firstMove(){
moveCount = 0;
startPoint();
chessboard[x][y] = moveCount;
moveCount ++;
}//close firstMove
public static void move() {
for(int i = 1; i <= 64; i++) {
moveGenerator();
chessboard[x + xMove][y + yMove] = moveCount;
moveCount ++;
x = x + xMove;
y = y + yMove;
}
xEnd = x;
yEnd = y;
}//close move
}
public class NonHeuristicApplication extends NonHeuristic {
public static void main(String[] args) {
for(int j = 1; j < 10; j++) {
firstMove();
move();
System.out.print("[" + xStart + "," + yStart + "]," + moveCount + ",[" + xEnd + "," + yEnd + "]");
}
}
} //close class
I think you do not understand static variable. Your code is not compilable. To print required data, you have to get an instance with these values. It could be given NonHeuristic class.
Remember, that static variables and methods belong to class object but not to the class' instance, therefore all static variables and methods are the same for all instances for given class.
public class NonHeuristic {
private static final int SIZE = 8;
private final int[][] chessboard = new int[SIZE][SIZE];
private final Random random = new Random();
private int xStart;
private int yStart;
private int moveCount;
private int xEnd;
private int yEnd;
private int x;
private int y;
private int randX;
private int randY;
private int xMove;
private int yMove;
public static void main(String... args) {
NonHeuristic obj = new NonHeuristic();
for (int j = 1; j < 10; j++) {
obj.firstMove();
obj.move();
System.out.print("[" + obj.xStart + ',' + obj.yStart + "]," + obj.moveCount + ",[" + obj.xEnd + ',' + obj.yEnd + ']');
}
}
public void firstMove() {
moveCount = 0;
startPoint();
chessboard[x][y] = moveCount;
moveCount++;
}
public void startPoint() {
xStart = random.nextInt(SIZE);
x = xStart;
yStart = random.nextInt(SIZE);
y = yStart;
System.out.println(xStart + " " + yStart);
}
public void move() {
for (int i = 1; i <= SIZE * SIZE; i++) {
moveGenerator();
chessboard[x + xMove][y + yMove] = moveCount;
moveCount++;
x += xMove;
y += yMove;
}
xEnd = x;
yEnd = y;
}
public void moveGenerator() {
int z = 0;
while (z == 0) {
randX = random.nextInt(5) - 2;
if (randX % 2 == 0 && randX != 0) {
randY = random.nextInt(3) - 1;
if (randY != 0 && boundCheck() && newMoveCheck()) {
xMove = randX;
yMove = randY;
z = 1;
}
} else if (randX % 2 != 0) {
randY = random.nextInt(5) - 2;
if (randY != 0 && Math.abs(randY) > 1 && boundCheck() && newMoveCheck()) {
xMove = randX;
yMove = randY;
z = 1;
}
}
}
}
public boolean boundCheck() {
return (randX + x) <= 7 && (randX + x) >= 0 && (randY + y) <= 7 && (randY + y) >= 0;
}
public boolean newMoveCheck() {
return chessboard[randX + x][randY + y] == 0;
}
}

Stack Overflow Error in a Self Calling Function in Java (Number of Islands)

I did some research on what causes a stack overflow errors, and I can conclude it is being caused by a recursive function in a program that is supposed to "count the number of islands" in an array. I understand what is causing the issue, but not sure why this is happening, or my main question is what to actually do about it. I found that if I slow down the program by having it repeatedly printing out something to the console, it works, but it takes forever to complete. Is there a way I can keep the program speed without the error, or a better way to solve the problem (search up "number of islands" to find the problem). Also, the array is two dimensional with a size of 1050 by 800.
public class NumOfIslands {
static boolean[][] dotMap = new boolean[1050][800];
static boolean visited[][] = new boolean[1050][800];
static int total = 0;
public static void main(String args[]) {
defineArrays();
run();
}
public static void findObjects(int xCord, int yCord) {
for(int y = yCord - 1; y <= yCord + 1; y++) {
for(int x = xCord - 1; x <= xCord + 1; x++) {
if(x > -1 && y > -1 && x < dotMap[0].length && y < dotMap.length) {
if((x != xCord || y != yCord) && dotMap[x][y] == true && visited[x][y] != true) {
visited[x][y] = true;
findObjects(x,y);
//System.out.println("test");
}
}
}
}
}
public static void defineArrays() {
for(int y = 0; y < 800; y++) {
for(int x = 0; x < 1050; x++) {
dotMap[x][y] = true;
}
}
}
public static int run() {
//dotMap = DisplayImage.isYellow;
System.out.println(dotMap.length + " " + dotMap[0].length);
int objects = 0;
for(int y = 439; y < 560/*dotMap[0].length*/; y++) {
for(int x = 70; x < 300/*dotMap.length*/; x++) {
if(dotMap[x][y] == true && visited[x][y] != true) {
visited[x][y] = true;
objects++;
findObjects(x,y);
}
}
}
System.out.println("total" + total);
System.out.println(objects);
return objects;
}
}
StackOverflowError reasons. In your example each call to findObjects adds 2 variables to the stack int x and int y from loops.
One of the fastest solution:
class Solution {
int m, n;
public int numIslands(char[][] grid) {
if (grid == null || grid.length == 0) {
return 0;
}
m = grid.length;
n = grid[0].length;
int counter = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
visit(grid, i, j);
counter++;
}
}
}
return counter;
}
public void visit(char[][] grid, int i, int j) {
if (i < 0 || i >= m || j < 0 || j >= n) {
return;
}
if (grid[i][j] == '0') {
return;
}
grid[i][j] = '0';
visit(grid, i - 1, j);
visit(grid, i + 1, j);
visit(grid, i, j - 1);
visit(grid, i, j + 1);
}
}
All recursive algorithms can be implemented with loops. One of the example is below. The Solution implements BFS (Breadth-first search) algorithm, more details on wikipedia.
class Solution {
public int numIslands(char[][] grid) {
if (grid == null || grid.length == 0) {
return 0;
}
int nr = grid.length;
int nc = grid[0].length;
int num_islands = 0;
for (int r = 0; r < nr; ++r) {
for (int c = 0; c < nc; ++c) {
if (grid[r][c] == '1') {
++num_islands;
grid[r][c] = '0'; // mark as visited
Queue<Integer> neighbors = new LinkedList<>();
neighbors.add(r * nc + c);
while (!neighbors.isEmpty()) {
int id = neighbors.remove();
int row = id / nc;
int col = id % nc;
if (row - 1 >= 0 && grid[row-1][col] == '1') {
neighbors.add((row-1) * nc + col);
grid[row-1][col] = '0';
}
if (row + 1 < nr && grid[row+1][col] == '1') {
neighbors.add((row+1) * nc + col);
grid[row+1][col] = '0';
}
if (col - 1 >= 0 && grid[row][col-1] == '1') {
neighbors.add(row * nc + col-1);
grid[row][col-1] = '0';
}
if (col + 1 < nc && grid[row][col+1] == '1') {
neighbors.add(row * nc + col+1);
grid[row][col+1] = '0';
}
}
}
}
}
return num_islands;
}
}
the problem is in this function
public static void findObjects(int xCord, int yCord) {
for(int y = yCord - 1; y <= yCord + 1; y++) {
for(int x = xCord - 1; x <= xCord + 1; x++) {
if(x > -1 && y > -1 && x < dotMap[0].length && y < dotMap.length) {
if((x != xCord || y != yCord) && dotMap[x][y] == true && visited[x][y] != true) {
visited[x][y] = true;
findObjects(x,y);
//System.out.println("test");
}
}
}
}
}`
at here you are builiding a stack of recursive calls to findobjects and ultimately it has no termination condition so it ends up at infinite stacks of findobjects, so my solution is if you are just checking that if x and y varaibles are not equal and visited[x][y] is not true then there is no need to call for recursion just comment the recursive call, because your loop already do what you want the recursive call to do.
public static void findObjects(int xCord, int yCord) {
for(int y = yCord - 1; y <= yCord + 1; y++) {
for(int x = xCord - 1; x <= xCord + 1; x++) {
if(x > -1 && y > -1 && x < dotMap[0].length && y < dotMap.length) {
if((x != xCord || y != yCord) && dotMap[x][y] == true && visited[x][y] != true) {
visited[x][y] = true;
//findObjects(x,y);
//System.out.println("test");
}
}
}
}
}

Java: Tic-Tac-Toe - How To AVOID Repeated Cell From Being Input By User?

How do I prevent the same tic tac toe coordinate from being inputted by the user?
The user input is taken at the main method in the Game Class.
The tic tac toe cells with [x, y] coordinates ranging from (0-2) can be either:
0(_), 1 (X) or 2 (O)
Grid Class with alpha beta search tree pruning algorithm
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
class Grid {
List<Cell> availableCells;
int[][] board = new int[3][3];
Scanner scan = new Scanner(System.in);
// Set limit to search tree depth
int treeDepth = 9;
List<CellsAndScores> rootsChildrenScore = new ArrayList<>();
public int score() {
int score = 0;
// Check all columns
for (int j = 0; j < 3; ++j) {
int X = 0;
int O = 0;
for (int i = 0; i < 3; ++i) {
if (board[i][j] == 0) {
} else if (board[i][j] == 1) {
X++;
} else {
O++;
}
}
score += changeInScore(X, O);
}
// Check all rows
for (int i = 0; i < 3; ++i) {
int X = 0;
int O = 0;
for (int j = 0; j < 3; ++j) {
if (board[i][j] == 0) {
} else if (board[i][j] == 1) {
X++;
} else {
O++;
}
}
score += changeInScore(X, O);
}
int X = 0;
int O = 0;
// Check diagonal (first)
for (int i = 0, j = 0; i < 3; ++i, ++j) {
if (board[i][j] == 1) {
X++;
} else if (board[i][j] == 2) {
O++;
} else {
}
}
score += changeInScore(X, O);
X = 0;
O = 0;
// Check Diagonal (Second)
for (int i = 2, j = 0; i > -1; --i, ++j) {
if (board[i][j] == 1) {
X++;
} else if (board[i][j] == 2) {
O++;
} else {
}
}
score += changeInScore(X, O);
return score;
}
private int changeInScore(int X, int O) {
int change;
if (X == 3) {
change = 100;
} else if (X == 2 && O == 0) {
change = 10;
} else if (X == 1 && O == 0) {
change = 1;
} else if (O == 3) {
change = -100;
} else if (O == 2 && X == 0) {
change = -10;
} else if (O == 1 && X == 0) {
change = -1;
} else {
change = 0;
}
return change;
}
public int alphaBetaMinimax(int alpha, int beta, int depth, int turn) {
if (beta <= alpha) {
System.out.println("Pruning at tree depth = " + depth + " alpha: " + alpha + " beta: " + beta);
if (turn == 1)
return Integer.MAX_VALUE;
else
return Integer.MIN_VALUE;
}
if (depth == treeDepth || gameOver()) {
return score();
}
List<Cell> cellsAvailable = getAvailableStates();
if (cellsAvailable.isEmpty()) {
return 0;
}
if (depth == 0) {
rootsChildrenScore.clear();
}
int maxValue = Integer.MIN_VALUE, minValue = Integer.MAX_VALUE;
for (int i = 0; i < cellsAvailable.size(); ++i) {
Cell cell = cellsAvailable.get(i);
int currentScore = 0;
if (turn == 1) {
placeAMove(cell, 1);
currentScore = alphaBetaMinimax(alpha, beta, depth + 1, 2);
maxValue = Math.max(maxValue, currentScore);
// Set alpha
alpha = Math.max(currentScore, alpha);
if (depth == 0) {
rootsChildrenScore.add(new CellsAndScores(currentScore, cell));
}
} else if (turn == 2) {
placeAMove(cell, 2);
currentScore = alphaBetaMinimax(alpha, beta, depth + 1, 1);
minValue = Math.min(minValue, currentScore);
// Set beta
beta = Math.min(currentScore, beta);
}
// reset board
board[cell.x][cell.y] = 0;
// Do not evaluate the rest of the branches after search tree is pruned
if (currentScore == Integer.MAX_VALUE || currentScore == Integer.MIN_VALUE)
break;
}
return turn == 1 ? maxValue : minValue;
}
public boolean gameOver() {
// Game is over is someone has won, or board is full (draw)
return (hasXWon() || hasOWon() || getAvailableStates().isEmpty());
}
public boolean hasXWon() {
if ((board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] == 1)
|| (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] == 1)) {
// System.out.println("X Diagonal Win");
return true;
}
for (int i = 0; i < 3; ++i) {
if (((board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] == 1)
|| (board[0][i] == board[1][i] && board[0][i] == board[2][i] && board[0][i] == 1))) {
// System.out.println("X Row or Column win");
return true;
}
}
return false;
}
public boolean hasOWon() {
if ((board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] == 2)
|| (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] == 2)) {
// System.out.println("O Diagonal Win");
return true;
}
for (int i = 0; i < 3; ++i) {
if ((board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] == 2)
|| (board[0][i] == board[1][i] && board[0][i] == board[2][i] && board[0][i] == 2)) {
// System.out.println("O Row or Column win");
return true;
}
}
return false;
}
public List<Cell> getAvailableStates() {
availableCells = new ArrayList<>();
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (board[i][j] == 0) {
availableCells.add(new Cell(i, j));
}
}
}
return availableCells;
}
public void placeAMove(Cell Cell, int player) {
board[Cell.x][Cell.y] = player; // player = 1 for X, 2 for O
}
public Cell returnBestMove() {
int MAX = -100000;
int best = -1;
for (int i = 0; i < rootsChildrenScore.size(); ++i) {
if (MAX < rootsChildrenScore.get(i).score) {
MAX = rootsChildrenScore.get(i).score;
best = i;
}
}
return rootsChildrenScore.get(best).cell;
}
public void displayBoard() {
System.out.println();
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (board[i][j] == 0)
System.out.print("_" + " ");
if (board[i][j] == 1)
System.out.print("X" + " ");
if (board[i][j] == 2)
System.out.print("O" + " ");
}
System.out.println("");
}
System.out.println();
}
public void resetGrid() {
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
board[i][j] = 0;
}
}
}
}
Cell class
class Cell {
int x, y;
public Cell(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return "[" + x + ", " + y + "]";
}
}
class CellsAndScores {
int score;
Cell cell;
CellsAndScores(int score, Cell cell) {
this.score = score;
this.cell = cell;
}
}
Game Class with main method - takes user input
import java.util.Random;
public class Game {
public static void main(String[] args) {
Grid grid = new Grid();
Random random = new Random();
grid.displayBoard();
System.out.print("Who moves first? [1]Computer(X) [2]User(O): ");
int turn = grid.scan.nextInt();
if (turn == 1) {
Cell p = new Cell(random.nextInt(3), random.nextInt(3));
grid.placeAMove(p, 1);
grid.displayBoard();
}
while (!grid.gameOver()) {
int x = 0, y = 0;
System.out.print("Please enter an x coordinate [0-2]: ");
x = grid.scan.nextInt();
System.out.print("Please enter an y coordinate [0-2]: ");
y = grid.scan.nextInt();
Cell userMove = new Cell(y, x);
grid.placeAMove(userMove, 2); // 2 for O and O is the user
grid.displayBoard();
if (grid.gameOver())
break;
grid.alphaBetaMinimax(Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 1);
for (CellsAndScores pas : grid.rootsChildrenScore)
System.out.println("Cell: " + pas.cell + " Score: " + pas.score);
grid.placeAMove(grid.returnBestMove(), 1);
grid.displayBoard();
}
if (grid.hasXWon()) {
System.out.println("Unfortunately, you lost!");
grid.resetGrid();
} else if (grid.hasOWon()) {
System.out.println("You win!");
grid.resetGrid();
} else {
System.out.println("It's a draw!");
grid.resetGrid();
}
}
}
My answer would be to add a boolean check method into your Grid.java class and then in your main method - call this boolean check method before the placeAMove() method.
For example, in your Grid.java class, adding the following method:
/*
* Return true if space is ok to use.
*/
public boolean isMoveOK(Cell cell) {
return board[cell.x][cell.y] == 0;
}
This way, using your pre-existing 0/1/2 values that keep track of empty/X/O space values, you may provide a check to see if the space value is zero or not.
This would be one way to use it in your main method, to answer your question of, 'How do I prevent the same tic tac toe coordinate from being inputted by the user?'
Cell userMove = new Cell(y, x);
if (grid.isMoveOK(userMove)) {
grid.placeAMove(userMove, 2); // 2 for O and O is the user
} else {
System.out.println("Please try a different space/cell");
continue;
}
grid.displayBoard();
if (grid.gameOver())
break;
In this way, I am skipping the remaining loop code in your main method loop, until there's a valid open space. (When there is, then the program should proceed to check for winning values or whether to proceed playing)
Hope this answers your question! :)
Cheers

Conway's game of life out of boundaries when counting neighbours - java

I am trying to create the game of life in java but I have difficulty writing the part that checks the number of neighbours. I understand that the problem is when the program gets to the edges of the grid it won't work because the indexes are greater/smaller than the bounds of the array. So the problem is in my Neighbours(). I am not sure how to fix it, I tried expanding the if statements and I also tried putting the whole set of statements in a while loop. The program seems to be working unless there are live cells at the edges of the grid. Any suggestions on this? Thanks in advance.
import java.io.*;
import java.util.Scanner;
public class LifeGrid
{
public int[][] grid;
public int[][] newgrid;
public int getX()
{
return grid[0].length;
}
public int getY()
{
return grid.length;
}
public int getcurrentgen()
{
return currentgen;
}
public int currentgen=0;
// modify neighbours out of boundary problem.
int Neighbours(int x, int y)
{
int neighbours = 0;
if (grid[y][x-1] == 1)
{ neighbours++; }
if (grid[y][x+1] ==1)
{ neighbours++; }
if (grid[y+1][x-1] ==1)
{ neighbours++; }
if (grid[y+1][x+1] ==1)
{ neighbours++; }
if (grid[y+1][x] ==1)
{ neighbours++; }
if (grid[y-1][x-1] ==1)
{ neighbours++; }
if (grid[y-1][x+1] ==1)
{ neighbours++; }
if (grid[y-1][x] ==1)
{ neighbours++; }
return neighbours;
}
public LifeGrid(int x, int y, String filename)
{
grid = new int [y][x];
newgrid = new int[y][x];
File input = new File(filename);
Scanner sc;
try
{
sc = new Scanner(input);
}
catch (FileNotFoundException e)
{
System.out.println("File error");
return;
}
for ( y=0; y< getY(); y++)
{
String line = sc.nextLine();
for( x = 0; x < getX(); x++)
{
if (line.charAt(x) == '*')
{
grid[y][x] = 1;
}
else
{
grid[y][x] = 0;
}
}
}
}
public void run()
{
show();
while(getcurrentgen() < 3)
{
setup();
grid = newgrid;
currentgen++;
show();
}
}
public void setup()
{
for (int y = 0; y < getY(); y++)
{
for (int x = 0;x < getX();x++)
{
if (grid[y][x]== 1)
{
if (Neighbours(x,y) < 2)
{
newgrid[y][x] = 0;
}
if (Neighbours(x,y) > 3)
{
newgrid[y][x] = 0;
}
if (Neighbours(x,y) == 3 || Neighbours(x,y) == 2)
{
newgrid[y][x] = 1;
}
}
if(grid[y][x]==0)
{
if(Neighbours(x,y) == 3)
{
newgrid[y][x]= 1;
}
}
}
}
}
public void show()
{
for(int y =0; y < getY(); y++)
{
for(int x = 0; x < getX(); x++)
{
System.out.print(grid[y][x]);
}
System.out.println();
}
System.out.println("Current generation: "+getcurrentgen());
}
}
you need to add checks for all your points to make sure they are not on boundary. This means checking for both x and y coordinates:
if (x > 0 && grid[y][x - 1] == 1) {
neighbours++;
}
if (x < grid[y].length - 1 && grid[y][x + 1] == 1) {
neighbours++;
}
if (x > 0 && y < grid.length - 1 && grid[y + 1][x - 1] == 1) {
neighbours++;
}
if (x < grid[y].length - 1 && y < grid.length - 1 && grid[y + 1][x + 1] == 1) {
neighbours++;
}
if (y < grid.length - 1 && grid[y + 1][x] == 1) {
neighbours++;
}
if (x > 0 && y > 0 && grid[y - 1][x - 1] == 1) {
neighbours++;
}
if (y > 0 && x < grid[y].length - 1 && grid[y - 1][x + 1] == 1) {
neighbours++;
}
if (y > 0 && grid[y - 1][x] == 1) {
neighbours++;
}
int Neighbours(int x, int y) is called with x=0 and y=0, right?
How do you then evaluate grid[y-1][x-1]?
Where you have
if (grid[y][x-1] == 1)
You just need to skip if this would go out of bounds:
if (x > 0 && grid[y][x-1] == 1)
And similar for all of the others.

Categories

Resources