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.
Related
There's a game file that runs my class and then calculates my average. It calculates the gameboard and gives me an array with the gameboard changes. It starts as a 10x10 of "." which get replaced by X if I hit or O if I miss. If I sink a ship it replaces all the X's(hits) with a number so if it was a destroyer with XXXXX it would become 55555.
When I run the game file and it gives me my average there is a ton of lines before the average saying out of guesses(max 100). I can't find out what is causing it to stop giving answers or bug up. Only thing I've noticed is if there's a hit on A1 and a miss on A2 leaving the only option as B2 it will sometimes give me A1. Any help is greatly appreciated!
public class stug_Bot
{
public static String makeGuess(char[][] guesses)
{
int row = 0;
int col = 0;
int squareValue = squareType(guesses);
int atkRow = -1;
int atkCol = -1;
int direction = 0;
if (guessNumber(guesses) == 0)
{
row = ( 4 + (int)(Math.random() * 2));
col = (4 + (int)(Math.random() * 2));
}
else if (hits(guesses))
{
for ( int i = 0; i < guesses.length; i++)
{
for ( int j = 0; j < guesses[i].length; j++)
if (guesses[i][j] == 'X')
{
atkRow = i;
atkCol = j;
break;
}
if (atkRow != -1)
break;
}
while(true)
{
direction = (int)(Math.random() * 4);
if (direction == 0 && atkRow != 0)
{
if (targetUp(atkRow, atkCol, guesses) == -1)
break;
col = atkCol;
row = targetUp(atkRow, atkCol, guesses);
break;
}
else if (direction == 1 && atkCol < 9)
{
if (targetRight(atkRow, atkCol, guesses) == -1)
break;
row = atkRow;
col = targetRight(atkRow, atkCol, guesses);
break;
}
else if (direction == 2 && atkRow < 9)
{
if (targetDown(atkRow, atkCol, guesses) == -1)
break;
col = atkCol;
row = targetDown(atkRow, atkCol, guesses);
break;
}
else if (direction == 3 && atkCol != 0)
{
if (targetLeft(atkRow, atkCol, guesses) == -1)
break;
row = atkRow;
col = targetLeft(atkRow, atkCol, guesses);
break;
}
}
}
else if (guessNumber(guesses) == 1)
{
do
{
row = ( 4 + (int)(Math.random() * 2));
col = (4 + (int)(Math.random() * 2));
} while (!isCorrectSquare(row, col, squareValue) || guesses[row][col] == 'X' || guesses[row][col] == 'O' || guesses[row][col] == '1' || guesses[row][col] == '2' || guesses[row][col] == '3' || guesses[row][col] == '4' || guesses[row][col] == '5');
}
else if (guessNumber(guesses) == 2)
{
do
{
row = (3 + (int)(Math.random() * 4));
col = (3 + (int)(Math.random() * 4));
} while (!isCorrectSquare(row, col, squareValue) || guesses[row][col] == 'X' || guesses[row][col] == 'O' || guesses[row][col] == '1' || guesses[row][col] == '2' || guesses[row][col] == '3' || guesses[row][col] == '4' || guesses[row][col] == '5');
}
else if (guessNumber(guesses) == 3)
{
do
{
row = (3 + (int)(Math.random() * 4));
col = (3 + (int)(Math.random() * 4));
} while (!isCorrectSquare(row, col, squareValue) || guesses[row][col] == 'X' || guesses[row][col] == 'O' || guesses[row][col] == '1' || guesses[row][col] == '2' || guesses[row][col] == '3' || guesses[row][col] == '4' || guesses[row][col] == '5');
}
else if (guessNumber(guesses) == 4)
{
do
{
row = (1 + (int)(Math.random() * 8));
col = (1 + (int)(Math.random() * 8));
} while (!isCorrectSquare(row, col, squareValue) || guesses[row][col] == 'X' || guesses[row][col] == 'O' || guesses[row][col] == '1' || guesses[row][col] == '2' || guesses[row][col] == '3' || guesses[row][col] == '4' || guesses[row][col] == '5');
}
else
{
do
{
row = ((int)(Math.random() * 10));
col = ((int)(Math.random() * 10));
} while (!isCorrectSquare(row, col, squareValue) || guesses[row][col] == 'X' || guesses[row][col] == 'O' || guesses[row][col] == '1' || guesses[row][col] == '2' || guesses[row][col] == '3' || guesses[row][col] == '4' || guesses[row][col] == '5');
}
char a = (char)((int)'A' + row);
String guess = a + Integer.toString(col+1);
return guess;
}
public static int guessNumber(char[][] arr)
{
int count = 0;
for ( int i = 0; i < arr.length; i++)
{
for ( int j = 0; j < arr[i].length; j++)
{
if (arr[i][j] != '.')
count++;
}
}
return count;
}
public static int squareType(char[][] arr)
{
int square = 0;
if (arr[4][4] != '.')
{
square = 0;
}
else if (arr[5][4] != '.')
{
square = 1;
}
else if (arr[4][5] != '.')
{
square = 1;
}
else if (arr[5][5] != '.')
{
square = 0;
}
else
{
square = 0;
}
return square;
}
public static boolean isCorrectSquare(int x, int y, int z)
{
if (( z == 0 ) && ((x + y) % 2 != 0) || (( z == 1 ) && ((x + y) % 2 == 0)))
{
return false;
}
else
{
return true;
}
}
public static boolean hits(char[][] arr)
{
for ( int i = 0; i < arr.length; i++)
{
for ( int j = 0; j < arr[i].length; j++)
{
if (arr[i][j] == 'X')
return true;
}
}
return false;
}
public static int targetUp(int row, int col, char[][] map)
{
int target = 0;
int count = 1;
while(true)
{
if (row != 0 && map[row - count][col] == '.')
{
target = row - count;
return target;
}
else if ( row!= 0 && map[row - count][col] == 'X')
{
count++;
}
else
{
return -1;
}
}
}
public static int targetRight(int row, int col, char[][] map)
{
int target = 0;
int count = 1;
while(true)
{
if (col+count < 10 && map[row][col + count] == '.')
{
target = col + count;
return target;
}
else if ( col+count < 10 && map[row][col + count] == 'X')
{
count++;
}
else
{
return -1;
}
}
}
public static int targetDown(int row, int col, char[][] map)
{
int target = 0;
int count = 1;
while(true)
{
if (row + count < 10 && map[row + count][col] == '.')
{
target = row + count;
return target;
}
else if ( row + count < 10 && map[row + count][col] == 'X')
{
count++;
}
else
return -1;
}
}
public static int targetLeft(int row, int col, char[][] map)
{
int target = 0;
int count = 1;
while(true)
{
if (col != 0 && map[row][col - count] == '.')
{
target = col - count;
return target;
}
else if ( col != 0 && map[row][col - count] == 'X')
{
count++;
}
else
return -1;
}
}
}
It turned out it was the break statements I was using in the else if (hits) section. If it picked a direction that had something blocking the way like a previous miss it would break the loop and return no value which led to the out of moves in a lot of the games. Replacing them with continue fixed it.
This question already has answers here:
Ludo game board in java [closed]
(2 answers)
Closed 2 years ago.
How do I write code to this board without using an array? I tried, but I did not get the right result. It should be with functions, loops and conditional structures. Row=11, column=11.
public static void board(int size) {
for (int i=1; i<=size;i++){
for (int j=1; j<=size; j++){
if (i==6 && j==6){
System.out.print(" ");
}
else if ( i==5 || i==7 || j==5 || j==7 || i==6 && j==1 || i==6 && j==11 ||
i==1 && j==6 || i==11 && j==6){
if (i==6 && j==7 || i==5 && j==6 || i==6 && j==5 || i==7 && j==6 ){
break;
}else{
System.out.print("o");
}
}
else if (i==6 || j==6 ) {
System.out.print(".");
}
else{
System.out.print(" ");
}
}
System.out.println();
}
}
public static void main(String[] args) {
board(11);
}
Do it as follows:
public class Main {
public static void main(String[] args) {
board(11);
}
public static void board(int size) {
for (int i = 1; i <= size; i++) {
for (int j = 1; j <= size; j++) {
if ((i == 6 && j == 6)) {
System.out.print(" ");
} else if (i == 5 || i == 7 || j == 5 || j == 7 || i == 6 && j == 1 || i == 6 && j == 11
|| i == 1 && j == 6 || i == 11 && j == 6) {
if (i == 6 && j == 5 || i == 6 && j == 7 || i == 5 && j == 6 || i == 7 && j == 6) {
System.out.print(".");
} else {
System.out.print("o");
}
} else if (i == 6 || j == 6) {
System.out.print(".");
} else {
System.out.print(" ");
}
}
System.out.println();
}
}
}
Output:
ooo
o.o
o.o
o.o
ooooo.ooooo
o.... ....o
ooooo.ooooo
o.o
o.o
o.o
ooo
You can write a general routine for any board size by detecting if the cell lies in one of the 4 corner blocks, in which case you print a space, on a center row or column, in which case you print a "." or a space if you're at the board center, otherwise you print a wall (O).
public static void board(int size)
{
if(size % 2 == 0 || size <= 3)
throw new IllegalArgumentException("Board size must be odd and bigger than 3: " + size);
int center = (size+1)/2;
int corner = (size-1)/2;
for (int i = 1; i <= size; i++)
{
for (int j = 1; j <= size; j++)
{
if(Math.max(i, j) < corner ||
Math.max(Math.min(i, 1+size-i), j) < corner ||
Math.max(i, Math.min(j, 1+size-j)) < corner ||
Math.max(Math.min(i, 1+size-i), Math.min(j, 1+size-j)) < corner)
{
System.out.print(" ");
}
else if((i > 1 && i < size && j == center) || (j > 1 && j < size && i == center))
{
if(i == center && j == center)
System.out.print(" ");
else
System.out.print(".");
}
else
{
System.out.print("O");
}
}
System.out.println();
}
}
board(7);
OOO
O.O
OOO.OOO
O.. ..O
OOO.OOO
O.O
OOO
board(11);
OOO
O.O
O.O
O.O
OOOOO.OOOOO
O.... ....O
OOOOO.OOOOO
O.O
O.O
O.O
OOO
This is the kata: https://www.codewars.com/kata/snail/train/java
I came up with this code.
import java.util.ArrayList;
import java.util.Arrays;
public class Snail {
public static int[] snail(int[][] array) {
ArrayList<Integer> snailArrayList = new ArrayList<>();
int direction = 3;
int x = 0;
int y = 0;
if (array.length != 0) {
while (snailArrayList.size() < array.length * array.length) {
if (direction == 3) {
while (y <= array.length - 1 && array[x][y] != -1) {
snailArrayList.add(array[x][y]);
array[x][y] = -1;
y++;
}
y--;
x++;
direction = 6;
} else if (direction == 6) {
while (x <= array.length - 1 && array[x][y] != -1) {
snailArrayList.add(array[x][y]);
array[x][y] = -1;
x++;
}
x--;
y--;
direction = 9;
} else if (direction == 9) {
while (y >= 0 && array[x][y] != -1) {
snailArrayList.add(array[x][y]);
array[x][y] = -1;
y--;
}
y++;
x--;
direction = 12;
} else if (direction == 12) {
while (x > 0 && array[x][y] != -1) {
snailArrayList.add(array[x][y]);
array[x][y] = -1;
x--;
}
x++;
y++;
direction = 3;
}
}
}
int[] snailArray = new int[snailArrayList.size()];
if (snailArray.length != 0) {
for (int i = 0; i < snailArrayList.size(); i++) {
snailArray[i] = snailArrayList.get(i);
}
}
return snailArray;
}
}
It works fine on my phone, but for some reason it fails to pass the test when an empty array is given. The error I get is:
[[]] should be sorted to [].
and
java.lang.ArrayIndexOutOfBoundsException: 0
at Snail.snail(Snail.java:15)
at SnailTest.test(SnailTest.java:35)
at SnailTest.SnailTest2Empty(SnailTest.java:62)
What's confusing for me is that with an empty array, the program doesn't even enter the if(array.length != 0) statement. I'm sure the solution is simple, but I just can't see it. Any help would be appreciated, thank you.
if (array[0].Length == 0)
{
return new int[0];
}
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;
}
}
A. how do i write this simpler?
if (fclass[0] == 0 && fclass[1] == 0 && fclass[2] == 0 && fclass[3] == 0 && fclass[4] == 0 && fclass[5] == 0 && fclass[6] == 0 && fclass[7] == 0 && fclass[8] == 0 && fclass[9] == 0 && fclass[10] == 0){
}else{
}
B. Solved! How would i scan an array (atm all values in it are at 0), when i change some of the element are set to one and show only the ones that have a 0 still.
example:
if fclass[1], fclass[2], fclass[4], fclass[5], fclass[6], fclass[10],
were all set to 1. How would i get my program to show me fclass[3], fclass[7],
fclass[8], and fclass[9]?
Thanks for the help...
for (int f = 0; f <= fclass.length; f++){
if (fclass[f] == 0){
System.out.println(fclass[f]);
}
C. My teacher requires us to learn GUI but doesn't know it herself, any good websites to start learning that?
A. You can set a boolean and loop through them to check if all are zero. I'm assuming that your fclass variable is int[].
boolean flag = true;
for (int i : fclass)
{
flag &= (i == 0);
}
if (flag)
{
// if all are zero...
}
else
{
// if one of them is not zero...
}
B. Similarly you can loop through the array and scan what is not equal to zero.
for (int i : fclass)
{
if (i != 0)
System.out.println(i); // these are array not equals to zero.
}
A.
boolean allZero = true;
for(int i=0; i<fclass.length; i++){
if(fclass[i] !=0) allZero = false;
}
if(allZero){
}
else{
}
B.
for(int i=0; i<fclass.length; i++){
if(fclass[i] ==0) System.out.println(i + "is 0");
}
C. Google
A:
boolean checkFClass(int[] flcass) {
for(int i =0 ; i < 11; i++) {
if(fclass[i] !=0) {
return false;}
}
return true;
}
B:
for(int i = 0 ; i < fclass.lenght ; i++) {
if(fclass[i] != 1) { System.out.println(fclass[i]);}
}