Java Connect 4 MinMax Algorithm - java

EDIT: I don't know why somebody links me a TicTacToe as duplicate for my question, there isn't even a MinMax-Algorithm in it.
Currently i'm working on a Connect4 game against the computer which should use the MinMax-Algorithm.
Before that, we wrote a TicTacToe which also uses the MinMax, but i'm not sure how to change my old algorithm to match the Connect4-Game :/.
In TicTacToe i evaluated each possible move with the win-conditions i wrote, it worked fine, but now it won't work with my new conditions.
My makeAMove etc. works fine!
These are my old conditions and the MinMax for TicTacToe:
//Player 1 wins
static boolean has1Won(int[][] array) {
gameBoard = array;
//Diagonal
if ((gameBoard[0][0] == gameBoard[1][1] && gameBoard[0][0] == gameBoard[2][2] && gameBoard[0][0] == 1)
|| (gameBoard[0][2] == gameBoard[1][1] && gameBoard[0][2] == gameBoard[2][0] && gameBoard[0][2] == 1)) {
return true;
}
//Spalten/Zeilen
for (int i = 0; i < 3; ++i) {
if (((gameBoard[i][0] == gameBoard[i][1] && gameBoard[i][0] == gameBoard[i][2] && gameBoard[i][0] == 1)
|| (gameBoard[0][i] == gameBoard[1][i] && gameBoard[0][i] == gameBoard[2][i] && gameBoard[0][i] == 1))) {
return true;
}
}
return false;
}
// Player 2 wins
static boolean has2Won(int[][] array) {
gameBoard = array;
//Diagonal
if ((gameBoard[0][0] == gameBoard[1][1] && gameBoard[0][0] == gameBoard[2][2] && gameBoard[0][0] == 2)
|| (gameBoard[0][2] == gameBoard[1][1] && gameBoard[0][2] == gameBoard[2][0] && gameBoard[0][2] == 2)) {
return true;
}
//Spalten/Zeilen
for (int i = 0; i < 3; ++i) {
if (((gameBoard[i][0] == gameBoard[i][1] && gameBoard[i][0] == gameBoard[i][2] && gameBoard[i][0] == 2)
|| (gameBoard[0][i] == gameBoard[1][i] && gameBoard[0][i] == gameBoard[2][i] && gameBoard[0][i] == 2))) {
return true;
}
}
return false;
}
As I said, i used these conditions for my MinMax like this:
public static int minimax(int depth, int turn) {
if (Board.has1Won(Board.gameBoard)){
return +1; // Der Computer gewinnt
}
if (Board.has2Won(Board.gameBoard)){
return -1; // Der Spieler gewinnt
}
List<GameMove> gameMovesAvailable = GameMove.getAvailableGameMoves();
if (gameMovesAvailable.isEmpty()){
return 0; // Das Spiel endet unentschieden
}
...
I'm not sure how i can get this to work with my new conditions:
I think i have to write an evaluating function which checks this for example (this is my wincondition for Rows):
boolean getWinnerInRow (Playboard brd){
int count = 0;
for (int i = 0; i < 6; i++){
for (int j = 0; j < 7; j++){
if (brd.gameBoard[i][j] != 0 && brd.gameBoard[i][j] == brd.gameBoard[i][j+1]){
count++;
} else {
count = 1;
}
if (count >= 4){
return true;
}
}
}
return false;
I know it's a lot of text, but maybe somebody can give me some useful tips :)
Thanks!
Max

I'm not sure that your test to find the winner is correct. Try this (you'll need to change it a little bit, but at least I'm sure that it's correct):
public static boolean testWinner(int[][] game, int lastColumn, Integ e) {
int lastRow = 0;
while (lastRow < 6 && game[lastRow][lastColumn] == 0) {
lastRow++;
}
lastRow = lastRow;
int i = 0;
int j = 0;
int currentPlayer = game[lastRow][lastColumn];
e.setI(currentPlayer);
int sequence = 0;
i = lastRow;
boolean b = i < 3
&& game[i][lastColumn] == currentPlayer
&& game[i+1][lastColumn] == currentPlayer
&& game[i+2][lastColumn] == currentPlayer
&& game[i+3][lastColumn] == currentPlayer;
if(b) {
return true;
}
sequence = 0;
j = lastColumn;
do {
j--;
} while(0 < j && game[lastRow][j] == currentPlayer);
if(j < 0 || game[lastRow][j] != currentPlayer) {
j++;
}
while(j <= 6 && game[lastRow][j] == currentPlayer) {
j++;
sequence++;
}
if (sequence >= 4) {
return true;
}
sequence = 0;
i = lastRow;
j = lastColumn;
do {
i--;
j--;
} while(0 < i && 0 < j && game[i][j] == currentPlayer);
if(i < 0 || j < 0 || game[i][j] != currentPlayer) {
i++;
j++;
}
while(i <= 5 && j <= 6 && game[i][j] == currentPlayer) {
i++;
j++;
sequence++;
}
if (sequence >= 4) {
return true;
}
sequence = 0;
i = lastRow;
j = lastColumn;
do {
i++;
j--;
} while(i < 5 && 0 < j && game[i][j] == currentPlayer);
if (5 < i || j < 0 || game[i][j] != currentPlayer) {
i--;
j++;
}
while(0 <= i && j <= 6 && game[i][j] == currentPlayer) {
i--;
j++;
sequence++;
}
if (sequence >= 4) {
return true;
}
return false;
}
Integ is just a class with an integer. I've created it because the wrapper is not really an object (can't pass by reference).
private static class Integ {
private int i;
public Integ() {
this.i = 0;
}
public void increment() {
this.i = this.i + 1;
}
public int getI() {
return this.i;
}
public void setI(int i) {
this.i = i;
}
}

Related

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

2D grid movement checking

The purpose of the program is to generate a two-dimensional grid array made of periods ( . ). The user designates a starting point for the 'walker' which is marked by 'A', and then the walker will generate numbers from 0-3 to represent the four cardinal directions. It will move in these random directions while incrementing the alphabet with each mark it leaves until it either runs in to the wall and is "arrested" or reaches 'Z' at which it "made it home". If it runs in to a space it has already been to, it has to jump ahead in the same direction until it reaches an empty space or hits the wall.
My problem now is that I have it on a counter to make sure it doesn't run past 'Z', and will "make it home" if it reaches that point. But even the movements that it is taking to avoid overwriting where it has already been are registering on the counter (which they shouldn't be), so its returning true even though it hasn't hit Z yet, and its also still calling my random number generator so its not keeping to the same direction when it tries to correct itself. It also seems to be occasionally even jumping over empty spaces.
The problem is in processing()
package walktester;
import java.lang.Math;
import java.util.Random;
import java.util.Scanner;
class DrunkWalker {
private char[][] walkgrid = new char[10][10];
private static int randNSEW;
private int randomnum;
private int startrow;
private int startcol;
private char alpha = 'A';
private int nextrow;
private int nextcol;
public DrunkWalker(int r, int c) {
startrow = r;
startcol = c;
nextrow = startrow;
nextcol = startcol;
for (int i = 0; i < 10; i ++) {
for (int j = 0; j < 10; j++)
walkgrid[i][j] = '.';
}
walkgrid[r][c] = alpha++;
}
public static void getRand(){
int x100 = 0;
double randomNum = 0.0;
randomNum = Math.random();
x100 = (int) (randomNum * 100);
randNSEW = x100 % 4;
}
public int getNextRow(){
return nextrow;
}
public int getNextCol(){
return nextcol;
}
public boolean processing(){
for(int i = 1; i < 26; i ++){
getRand();
if(randNSEW == 0){
nextcol--;
}
if(randNSEW == 1){
nextrow++;
}
if(randNSEW == 2){
nextcol++;
}
if(randNSEW == 3){
nextrow--;
}
if(nextrow < 0 || nextrow >= 10 || nextcol < 0 || nextcol >= 10) {
return false;
}
if(randNSEW == 0 && walkgrid[nextrow][nextcol] != '.'){
nextcol--;
continue;
}
if(randNSEW == 1 && walkgrid[nextrow][nextcol] != '.'){
nextrow++;
continue;
}
if(randNSEW == 2 && walkgrid[nextrow][nextcol] != '.'){
nextcol++;
continue;
}
if(randNSEW == 3 && walkgrid[nextrow][nextcol] != '.'){
nextrow--;
continue;
}
walkgrid[nextrow][nextcol] = alpha++;
}
return true;
}
public char[][] DisplayGrid() {
for(int y = 0; y < 10; y++) {
for(int x = 0; x < 10; x++) {
System.out.print(walkgrid[x][y] + " ");
}
System.out.println();
}
return walkgrid;
}
}
public class WalkTester {
public static void main(String[] args) {
Scanner inpr = new Scanner(System.in);
Scanner inpc = new Scanner(System.in);
Scanner inpchoice = new Scanner(System.in);
int r = 0;
int c = 0;
char choice = 'y';
while(choice == 'y' || choice == 'Y') {
System.out.println("Please enter x coordinate between 1 and 10.");
r = inpr.nextInt();
r = r - 1;
System.out.println("Please enter y coordinate between 1 and 10");
c = inpr.nextInt();
c = c - 1;
if(r < 0 || r > 9 || c < 0 || c > 9){
System.out.println("Invalid Entry. Restart? y/n");
choice = inpchoice.next().charAt(0);
if(choice == 'y' || choice == 'Y'){
continue;
}
else if(choice == 'n' || choice == 'N'){
return;
}
else{
System.out.println("Invalid Entry. Restart? y/n");
choice = inpchoice.next().charAt(0);
}
}
DrunkWalker drunkwalker = new DrunkWalker(r, c);
boolean walkerSucceeded = drunkwalker.processing();
drunkwalker.DisplayGrid();
if(walkerSucceeded) {
System.out.println("You made it home");
} else {
System.out.println("You were arrested");
}
System.out.println("Restart? y/n");
choice = inpchoice.next().charAt(0);
if(choice == 'y' || choice == 'Y'){
continue;
}
else if(choice == 'n' || choice == 'N'){
return;
}
else{
System.out.println("Invalid Entry. Restart? y/n");
choice = inpchoice.next().charAt(0);
}
}
}
}
The following code fixes your problems. You basically did not have 'state' distinguishing a valid move, vs. moving to 'jump' over past visit points. I tried to keep the code as close as possible to your existing code.
class DrunkWalker {
private char[][] walkgrid = new char[10][10];
private static int randNSEW;
private int randomnum;
private int startrow;
private int startcol;
private char alpha = 'A';
private int nextrow;
private int nextcol;
public DrunkWalker(int r, int c) {
startrow = r;
startcol = c;
nextrow = startrow;
nextcol = startcol;
for (int i = 0; i < 10; i ++) {
for (int j = 0; j < 10; j++)
walkgrid[i][j] = '.';
}
walkgrid[r][c] = alpha++;
}
public static void getRand(){
int x100 = 0;
double randomNum = 0.0;
randomNum = Math.random();
x100 = (int) (randomNum * 100);
randNSEW = x100 % 4;
}
public int getNextRow(){
return nextrow;
}
public int getNextCol(){
return nextcol;
}
enum Mode {WALKING, CORRECTING};
Mode mode = Mode.WALKING;
public boolean processing(){
for(int i = 1; i < 26; i ++){
if (mode == Mode.WALKING) {
getRand();
if(randNSEW == 0){
nextcol--;
}
if(randNSEW == 1){
nextrow++;
}
if(randNSEW == 2){
nextcol++;
}
if(randNSEW == 3){
nextrow--;
}
}
if(nextrow < 0 || nextrow >= 10 || nextcol < 0 || nextcol >= 10) {
return false;
}
if(randNSEW == 0 && walkgrid[nextrow][nextcol] != '.'){
i--;
nextcol--;
mode = Mode.CORRECTING;
continue;
}
if(randNSEW == 1 && walkgrid[nextrow][nextcol] != '.'){
i--;
nextrow++;
mode = Mode.CORRECTING;
continue;
}
if(randNSEW == 2 && walkgrid[nextrow][nextcol] != '.'){
i--;
nextcol++;
mode = Mode.CORRECTING;
continue;
}
if(randNSEW == 3 && walkgrid[nextrow][nextcol] != '.'){
i--;
nextrow--;
mode = Mode.CORRECTING;
continue;
}
mode = Mode.WALKING;
walkgrid[nextrow][nextcol] = alpha++;
}
return true;
}

Game Of Life loop error

So I'm currently working on a program based on Conway's Game of Life, and this certain method requires me to update the 2d array to define which cells are alive. I've run my JUnit tests, but when the test for the method runs, it says it's infinitely looping. Any ideas why?
public void update() {
boolean temp ;
for (int i = 0; i < numberOfRows(); i++) {
for (int j = 0; j < numberOfColumns(); j++) {
temp = false;
if (cellAt(i, j)) {
temp = true;
}
if (temp=true) {
if (neighborCount(i, j) < 2 || neighborCount(i, j) > 3) {
society[i][j] = false;
}
} else {
if (neighborCount(i, j) == 3) {
society[i][j] = true;
}
}
}
}
}
Here is the other methods that are used in this one
cellAt():
public boolean cellAt(int row, int col) {
if (society[row][col] == true) {
return true;
} else {
return false;
}
}
neighborCount():
public int neighborCount(int row, int col) {
int counter = 0;
for (int i = ((row + numberOfRows() - 1) % numberOfRows()); i == ((row + 1) % numberOfRows())
|| i == row
|| i == (((row + numberOfRows() - 1)) % numberOfRows())
|| i == numberOfRows(); i++) {
i = i % numberOfRows();
for (int j = (((col + numberOfColumns() - 1)) % numberOfColumns()); j == ((col + 1) % numberOfColumns())
|| j == col
|| j == (((col + numberOfColumns() - 1)) % numberOfColumns())
|| j == numberOfColumns(); j++) {
j = j % numberOfColumns();
if (society[i][j] == true) {
counter++;
}
}
}
return counter;
}
You need to use comparison(==) instead of assignment(=) here:
if (temp=true) {
which will always return true
Change it to
if (temp == true) {
or simply use "Jean-François Savard" suggestion
if(temp)
Figured it out. neighborCount() was just horribly written and the for loops were repeating.

Efficient way to find how many neighbouring elements with a specific value there are around a particular element in an array

If I have a 2D int array called myArray that is for example 3x3 size and its elements can only have either 1 or 0 for values, what would be an efficient way to calculate how many 1s there are around a particular element? E.g:
[0][0][0]
[0][1][0]
[1][1][1]
The element myArray[0][0] would have neighbourCount of 1 while myArray[0][1] would have a neighbourCount of 3.
This is my current brute force code. myArray = currentGeneration
public int neighbours(int x, int y) { //x and y are 0 index based coordinates, they are swapped inside to corespond with actual x and y coordinates
int neighbourCounter = 0;
if(x == 0 && y == 0) {
if(currentGeneration[y+1][x] == 1) {
neighbourCounter++;
}
if(currentGeneration[y][x+1] == 1) {
neighbourCounter++;
}
if(currentGeneration[y+1][x+1] == 1) {
neighbourCounter++;
}
} else if(x == 0 && y == currentGeneration.length - 1) {
if(currentGeneration[y-1][x] == 1) {
neighbourCounter++;
}
if(currentGeneration[y][x+1] == 1) {
neighbourCounter++;
}
if(currentGeneration[y-1][x+1] == 1) {
neighbourCounter++;
}
} else if(x == currentGeneration[0].length - 1 && y == currentGeneration.length - 1) {
if(currentGeneration[y-1][x] == 1) {
neighbourCounter++;
}
if(currentGeneration[y][x-1] == 1) {
neighbourCounter++;
}
if(currentGeneration[y-1][x-1] == 1) {
neighbourCounter++;
}
} else if( y == 0 && x == currentGeneration[0].length - 1) {
if(currentGeneration[y][x-1] == 1) {
neighbourCounter++;
}
if(currentGeneration[y+1][x] == 1) {
neighbourCounter++;
}
if(currentGeneration[y+1][x-1] == 1) {
neighbourCounter++;
}
} else if(y == 0) {
for(int i = -1; i <= 1; i+=2) {
if(currentGeneration[y][x+i] == 1) {
neighbourCounter++;
}
}
if(currentGeneration[y+1][x] == 1) {
neighbourCounter++;
}
for(int i = -1; i <= 1; i+=2) {
if(currentGeneration[y+1][x+i] == 1) {
neighbourCounter++;
}
}
} else if(x == 0) {
for(int i = -1; i <= 1; i+=2) {
if(currentGeneration[y+i][x] == 1) {
neighbourCounter++;
}
}
if(currentGeneration[y][x+1] == 1) {
neighbourCounter++;
}
for(int i = -1; i <= 1; i+=2) {
if(currentGeneration[y+i][x+1] == 1) {
neighbourCounter++;
}
}
} else if(y == currentGeneration.length - 1) {
for(int i = -1; i <= 1; i+=2) {
if(currentGeneration[y][x+i] == 1) {
neighbourCounter++;
}
}
if(currentGeneration[y-1][x] == 1) {
neighbourCounter++;
}
for(int i = -1; i <= 1; i+=2) {
if(currentGeneration[y-1][x+i] == 1) {
neighbourCounter++;
}
}
} else if(x == currentGeneration[0].length - 1) {
for(int i = -1; i <= 2; i+=2) {
if(currentGeneration[y+i][x] == 1) {
neighbourCounter++;
}
}
if(currentGeneration[y][x-1] == 1) {
neighbourCounter++;
}
for(int i = -1; i <= 2; i+=2) {
if(currentGeneration[y+i][x-1] == 1) {
neighbourCounter++;
}
}
} else {
for(int i = -1; i <= 1; i+=2) {
if(currentGeneration[y+i][x] == 1) {
neighbourCounter++;
}
if(currentGeneration[y][x+i] == 1) {
neighbourCounter++;
}
if(currentGeneration[y+i][x+i] == 1) {
neighbourCounter++;
}
if(currentGeneration[y+i][x-i] == 1) {
neighbourCounter++;
}
}
}
return neighbourCounter;
}
How about that:
public static int findNeighbors(int x, int y, int[][] a) {
int sum = 0;
for ( int i = (y>0 ? y-1 : 0); i <= (y<a.length-1 ? y+1 : a.length-1); ++i )
for ( int j = (x>0 ? x-1 : 0); j <= (x<a[0].length-1 ? x+1 : a[0].length-1); ++j )
sum += a[i][j];
sum -= a[y][x];
return sum;
}

Java: Array Index Out of Bound Exception

When I compiled I got here error java.lang.ArrayIndexOutOfBoundsException: -1. I checked code 3 times and no error found there, also I am not writing after end of array.
Random nahoda = new Random(); int[][] minPol = new int[5][5];
int[][] cisPol = new int[5][5];
for(int i = 0;i<5;i++)
{
for(int j=0;j<5;j++)
{
minPol[i][j] = nahoda.nextInt(2);
cisPol[i][j] = 0;
}
}
for(int i = 0;i<5;i++)
{
for(int j=0;j<5;j++)
{
if(minPol[i][j]!=0)
{
if(i != 0 || j != 0 || i != 4 || j != 4)
{
cisPol[i+1][j+1]++;
cisPol[i+1][j-1]++;
cisPol[i-1][j+1]++;
cisPol[i-1][j-1]++;
cisPol[i+1][j]++;
cisPol[i-1][j]++;
cisPol[i][j+1]++;
cisPol[i][j-1]++;
}
else
{
if(i == 0)
{
if(j == 0)
{
cisPol[i+1][j+1]++;
cisPol[i][j+1]++;
cisPol[i+1][j]++;
}
else if(j == 4)
{
cisPol[i+1][j]++;
cisPol[i+1][j-1]++;
cisPol[i][j-1]++;
}
else
{
cisPol[i+1][j+1]++;
cisPol[i][j+1]++;
cisPol[i+1][j]++;
cisPol[i+1][j-1]++;
cisPol[i][j-1]++;
}
}
else if(i == 4)
{
if(j == 0)
{
cisPol[i-1][j+1]++;
cisPol[i-1][j]++;
cisPol[i][j+1]++;
}
else if(j == 4)
{
cisPol[i-1][j-1]++;
cisPol[i-1][j]++;
cisPol[i][j-1]++;
}
else
{
cisPol[i][j-1]++;
cisPol[i][j+1]++;
cisPol[i-1][j+1]++;
cisPol[i-1][j]++;
cisPol[i-1][j-1]++;
}
}
}
}
}
}
I am beginner in Java and thanks for tips
Look at this condition:
if(i != 0 || j != 0 || i != 4 || j != 4)
That doesn't do what you want it to. It will always be true, because i can't be simultaneously equal to 0 and 4.
Therefore you'll end up going into here when j is 0:
cisPol[i+1][j-1]++;
Bang.
Try this;
Replace this line;
if(i != 0 || j != 0 || i != 4 || j != 4)
with
if( i>=1 && j>=1 && j<4 && i<4)
That will make sure you don't reference from your array with a negative index or a value greater than 4.

Categories

Resources