I recently completed the code for a Four in a Row Game with 7 columns (represented by i below) and 6 rows (represented by j below), however, I keep getting out of bounds errors and I'm not sure why. If anyone can help spot and fix the errors, that would be awesome. Below is the code I have (the issues lie in the play, isGameOver and winner functions):
package hw4;
public class CFGame {
//state[i][j]= 0 means the i,j slot is empty
//state[i][j]= 1 means the i,j slot has red
//state[i][j]=-1 means the i,j slot has black
private final int[][] state;
private boolean isRedTurn;
{
state = new int[7][6];
for (int i=0; i<7; i++)
for (int j=0; j<6; j++)
state[i][j] = 0;
isRedTurn = true; //red goes first
}
public int[][] getState() {
int[][] ret_arr = new int[7][6];
for (int i=0; i<7; i++)
for (int j=0; j<6; j++)
ret_arr[i][j] = state[i][j];
return ret_arr;
}
public boolean isRedTurn() {
return isRedTurn;
}
public boolean play(int column) {
for(int j = 0; j < state[column].length; j++) {
if(state[column][j] != 0 || state[column][j] < 0 || state[column][j] > 6 ) {
return false;
}
}
return true;
}
public boolean isGameOver() {
for(int j = 0; j < state.length; j++) {
for(int i = 0; i < state[j].length; i++) {
if (state[i][j] != 0) {
return true;
}
}
}
return false;
}
public int winner() {
//Checking horizontal win
for(int j = 0; j < state.length; j++) {
for(int i = 0; i < state[j].length-3; i++) {
if(state[i][j] == state[i+1][j] && state[i][j] == state[i+2][j] &&
state[i][j] == state[i+3][j]) {
return state[i][j];
}
}
}
//Checking vertical win
for(int j = 0; j < state.length-3; j++) {
for(int i = 0; i < state[0].length; i++) {
if(state[i][j] == state[i][j+1] && state[i][j] == state[i][j+2] &&
state[i][j] == state[i][j+3]) {
return state[i][j];
}
}
}
//Checking diagonal(s) win
for(int j = 0; j < state.length - 3; j++) {
for(int i = 0; i < state[j].length - 3; i++) {
if(state[i][j] == state[i+1][j+1] && state[i][j] == state[i+2][j+2] &&
state[i][j] == state[i+3][j+3]) {
return state[i][j];
}
}
}
for(int j = 0; j < state.length - 3; j++) {
for(int i = 3; i <= state[j].length; i++) {
if(state[j][i] == state[j+1][i-1] && state[j][i] == state[j+2][i-2] &&
state[j][i] == state[j-3][i+3]) {
return state[i][j];
}
}
}
return 0;
}
}
To me, the code seems fine but when I run it, it brings up the error.
If you spot any other mistakes, kindly let me know too.
Any help is much appreciated.
You use index j and i differently in different loops. It looks like j should be the index for the first dimension and i is for the second, but you have state[i][j] in some places. That will definitely cause outofbound error because j can go as high as 6 but i is capped at 5 based on your code.
Related
I have a 2D array (a matrix of 10x10) with values ranging from 0 to -5.
I want a method to be triggered when there is a sequence of a value found within the array.
For example, there is a sequence of two negative 2. I want it to trigger an event/method that will give a bonus score of 4. This should happen only when there are two -2's and not if there is just one -2.
I tried achieving something like that but I cant figure out how to tell the program to only trigger when 'n' number of a value is found within the matrix.
public class Test {
static int board[][] = new int[10][10];
public static void Test() {
int i, j;
board[0][0] = -1;
board[0][1] = -1;
board[1][1] = -2;
board[1][2] = -2;
board[1][3] = -2;
board[1][4] = -2;
for (i = 0; i < board.length; i++) {
System.out.println("");
for (j = 0; j < board.length; j++) {
//board[i][j] = 0;
System.out.print(board[i][j]);
}
}
System.out.println();
}
public static void scanBoard() {
int i, j;
for (i = 0; i < board.length; i++) {
for (j = 0; j < board.length; j++) {
if (board[i][j] == -1) {
System.out.println("Hello");
}
}
}
}
public static void main(String[] args) {
Test(); //prints out whole array
scanBoard(); //scans for
}
}
public class Main {
static final int size = 10;
static int[][] matrix = new int[size][size];
public static void main(String[] args) {
System.out.println("The first matrix.\n");
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (i == 3 && j > 3) {
matrix[i][j] = -2; //-2
} else {
matrix[i][j] = 1;
}
System.out.print(matrix[i][j]);
}
System.out.println();
}
scanBoard();
System.out.println("\nThe second matrix.\n");
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (i == 9 && j > 5) {
matrix[i][j] = 2; //changed it from -2 to 2
} else {
matrix[i][j] = 1;
}
System.out.print(matrix[i][j]);
}
System.out.println();
}
scanBoard();
}
static void scanBoard() {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (matrix[i][j] == -2 && (j + 3 < size)) {
if (matrix[i][j + 1] == -2 && matrix[i][j + 2] == -2 && matrix[i][j + 3] == -2) {
System.out.println("\nThere you go, a special effect!".toUpperCase());
}
}
}
}
}
}
I am not sure if this is the result you wished to see according to your request. I hope this helps you. And I did some changes in your code so it will be easier to read (In my opinion lol).
public class Main {
static final int size = 10;
static int[][] matrix = new int[size][size];
public static void main(String[] args) {
System.out.println("The first matrix.\n");
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (i == 9 && (j == 0 || j == 1)) {
matrix[i][j] = -2; //-2
} else {
matrix[i][j] = 1;
}
System.out.print(matrix[i][j]);
}
System.out.println();
}
scanBoard();
System.out.println("\nThe second matrix.\n");
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (i == 8 && (j == 5 || j == 6)) {
matrix[i][j] = 2; //changed it from -2 to 2
} else {
matrix[i][j] = 1;
}
System.out.print(matrix[i][j]);
}
System.out.println();
}
scanBoard();
}
static void scanBoard() {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (matrix[i][j] == -2 && (j + 1 < size)) {
if (matrix[i][j + 1] == -2) {
//You can remove the '.toUpperCase()', it's just my personal preference
System.out.println("\nThere you go, a special effect!".toUpperCase());
}
}
}
}
}
}
From what I understood from the problem statement and comments, you want your scanBoard to behave like this:
public static void scanBoard(int value, int frequency) {
int i, j;
if (value <= 0 && value >= -5 && frequency >= 2 && frequency <= 10) {
for (i = 0; i < board.length; i++) {
int rowFrequency = 0;
for (j = 1; j < board.length; j++) {
if (board[i][j] == value && board[i][j - 1] == value) {
rowFrequency++;
} else {
rowFrequency = 0;
}
if (rowFrequency + 1 >= frequency) {
System.out.println("Hello");
}
}
}
}
}
public static void main(String[] args) {
Test(); //prints out whole array
scanBoard(-2, 4); //prints Hello once
scanBoard(-2, 3); //prints Hello twice
scanBoard(-2, 3); //prints Hello thrice
}
This is an N Queens problem where the board has been given and you must use methods to check where the rows, the columns and diagonally. My method for checking the row is here:It works if you were counting the Queens as a whole but I only want to check row by row, resetting the count and rowcount.
private boolean oneQueenPerRow() //ensures that there is only 1 queen in each row
{
int count = 0;
int rowcount = 0;
for (int i = 0; i < board.length; i++)
{
//count = 0;
for (int j = 0; j < board.length; j++)
{
//rowcount = 0;
while (rowcount <= size-1)
{
if (board[i][j] == QUEEN)
{
count++;
rowcount++;
}
if (board[i][j] == BLANK)
{
rowcount++;
}
}
if (count != 1) // if size replaces 1 then it works, but counts Q's as a whole
{
return false;
}
}
}
return true;
}
The idea is that all the methods return true or false and then are called by final boolean method. If all are true than the board is a valid solution. If one is false, the board is not a valid solution. Here is a text file example I was given:
4
BQBB
BBBQ
QBBB
BBQB
(They should be stacked..)
I don't have enough knowledge about arrays and for loops to tell if this is going all the way through the whole file or just a row at a time, although trust me when I say I have exhausted all resources.
I have been working on this for days and I can't figure it out and connection with my Prof is spotty because of this virus! I desperately need help!
private boolean noDiagonalAttacks() //makes sure that Queens cannot attack diagonally
{
for (int i = 0; i < board.length; i++)
{
int count = 0;
for (int j = 0; j < board.length; j++)
{
if (board[i][j] == QUEEN)
{
if(this.toRight() == false || this.toLeft() == false)
{
return false;
}
count++;
}
}
}
return true;
}
private boolean toRight()
{
for (int i = 0; i < board.length; i++)
{
for (int j = 0; j < board.length; j++)
{
while (board[i][j] != board[i][size-1] || board[i][j] != board[size-1][j]) //add a count to this?
{
if (board[i][j] == QUEEN)
{
return false;
}
}
}
}
return true;
}
private boolean toLeft()
{
for (int i = 0; i < board.length; i++)
{
for (int j = 0; j < board.length; j++)
{
while (board[i][j] != board[i][0] || board[i][j] != board[size-1][j])
{
if (board[i][j] == QUEEN)
{
return false;
}
}
}
}
return true;
}
I tried it once ago and it worked, Hope it help you.
private boolean oneQueenPerRow() {
int foundQueens;
for (int i = 0; i < board.length; i++) {
foundQueens = 0;//each loop is a checked row
for (int j = 0; j < board.length; j++) {
if (board[i][j] == QUEEN)
foundQueens++;
}
if (foundQueens > 1) return false;
}
return true;
}
private boolean oneQueenPerDiagonal() {
int inLeftRight = 0;
int inRightLeft = 0;
for (int i = 0; i < board.length; i++) {
if (board[i][i] == QUEEN)
inLeftRight++;
if (board[i][board.length-i-1] == QUEEN)
inRightLeft++;
}
return inLeftRight < 1 && inRightLeft < 1;
}
I seem to not be able to solve this java.lang.ArrayIndexOutOfBoundsException: 5
I understand the error, but the table is 5x5 and I think I have everything right for printing it.
public static int tulosta_matriisi(int[][] matriisi) {
int i=0, j=0;
for(i = 0; i <= 4; i++) {
for(j = 0; j <= 4; j++) {
if(j == 4 && i <= 4)
System.out.println(matriisi[i][j]);
else if(i <= 4 && j <= 4)
System.out.print(matriisi[i][j] +"\t");
}
}
return matriisi[i][j];
}
To avoid all this problem you have to use :
for(i = 0; i < matriisi.length; i++) {
for(j = 0; j < matriisi[i].length; j++) {
...
When you get out your loop, the i and j will be incremented so you should not return matriisi[i][j] this make this error java.lang.ArrayIndexOutOfBoundsException: 5, so instead you should to return matriisi[i-1][j-1] so in the end your program should look like this :
public static int tulosta_matriisi(int[][] matriisi) {
int i = 0, j = 0;
for (i = 0; i < matriisi.length; i++) {
for (j = 0; j < matriisi[i].length; j++) {
if (j == matriisi[i].length - 1 && i <= matriisi.length) {
System.out.println(matriisi[i][j]);
} else if (i <= matriisi.length && j <= matriisi[i].length) {
System.out.print(matriisi[i][j] + "\t");
}
}
}
return matriisi[i - 1][j - 1];
}
Good luck
I am not sure where logically I am wrong. It returns true for both diagonal and non diagonal matrix. I am still new to 2d array and have watched video and read online. I do understand on how 2d array work but I am unable get the correct answer.
..
else{
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix.length; j++) {
if((i != j) && (matrix[i][j] != 0)){
isDyg = false;
}
}
//System.out.print("");
}
isDyg = true;
}
return isDyg;
Because after your loop ends, isDyg is set to true everytime.
Change isDyg = false; to return false;
Or change your code to -
isDyg = true;
outerloop:
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix.length; j++) {
if((i != j) && (matrix[i][j] != 0)){
isDyg = false;
break outerloop;
}
}
//System.out.print("");
}
return isDyg;
I'm new to this forum so I hope I'm posting this question in the right way - otherwise, please let me know.
I'm trying to write the code for a simple Game of Life animation in Java, and most of it seems to work as intended.
However, there is a problem with one of the neighbour 'rules' that is supposed to "kill" a cell if it has less than 2 neighbours, meaning that cells can have one or no neighbours and still survive - can be seen here: http://peecee.dk/upload/view/435109. All other rules seem to work fine.
Can anyone help me figure out why it ignores the rule (Live cells are equal to '1', dead to '0'.):
if (this.state[i][j] == 1 &&
liveNeighbours(i, j) > 3 || liveNeighbours(i, j) < 2) {
this.tempState[i][j] = 0;
Thanks a ton in advance!
The code is as follows:
import java.util.*;
public class GameOfLife {
private int[][] state;
private int[][] tempState;
//Constructor that creates n x n grid of randomly placed live cells
public GameOfLife(int n) {
this.state = new int[n+2][n+2];
this.tempState = new int[n+2][n+2];
createRandomBoard(n);
}
//Sets up the initial state
public void createRandomBoard(int n) {
//Creates (n+2) x (n+2) grid of dead cells
for (int i = 0; i < n+2; i++) {
for (int j = 0; j < n+2; j++) {
this.state[i][j] = 0;
}
}
//Creates n x n grid of randomly placed live cells. Live cells are equal to '1', dead to '0'.
for (int i = 1; i < n + 1; i++) {
for (int j = 1; j < n + 1; j++) {
int a = (int)Math.round(Math.random());
this.state[i][j] = a;
}
}
drawBoard();
}
//Draws the live cells as dots based on current state
public void drawBoard() {
StdDraw.show(50);
StdDraw.clear();
for (int i = 1; i < this.state.length-2; i++) {
for (int j = 1; j < this.state.length-2; j++) {
StdDraw.setXscale(1,this.state.length-3);
StdDraw.setYscale(1,this.state.length-3);
StdDraw.setPenRadius((double)1/this.state.length);
if (this.state[i][j] == 1) {
StdDraw.point(i, j);
}
}
}
StdDraw.show(50);
}
//Determines which cells live or die in the next state
public void nextState() {
//Copies the state array to a temporary state(array) during killing/reviving
for (int i = 1; i < this.state.length-2; i++) {
for (int j = 1; j < this.state.length-2; j++) {
this.tempState[i][j] = this.state[i][j];
}
}
//Kills cells with more than 3 or less than 2 neighbours and revives dead cells with 3 neighbours
for (int i = 1; i < this.state.length-2; i++) {
for (int j = 1; j < this.state.length-2; j++) {
if (this.state[i][j] == 1 && liveNeighbours(i, j) > 3 || liveNeighbours(i, j) < 2) {
this.tempState[i][j] = 0;
}
else if (this.state[i][j] == 0 && liveNeighbours(i, j) == 3) {
this.tempState[i][j] = 1;
}
}
}
//Copies the modified temporary state array to the original state(array) again
for (int i = 1; i < this.state.length-2; i++) {
for (int j = 1; j < this.state.length-2; j++) {
this.state[i][j] = this.tempState[i][j];
}
}
drawBoard();
}
//Counts the number of live neighbours to a cell
private int liveNeighbours(int x, int y) {
int numLiveNeighbours = 0;
for (int i = x-1; i < x+2; i++) {
for (int j = y-1; j < y+2; j++) {
if (this.state[i][j] == 1) {
numLiveNeighbours++;
}
}
}
numLiveNeighbours --;
return numLiveNeighbours;
}
public String toString() {
return Arrays.deepToString(this.state);
}
public int[][] getState() {
return this.state;
}
}
Your condition doesn't seem to express what you want. You need to change it to:
if (this.state[i][j] == 1 && (liveNeighbours(i, j) > 3 || liveNeighbours(i, j) < 2))
Check operators precedence rules in Java. You were killing those cells being alive and having more than 3 neighbours or those cells with less than two of them.
With this change you will be killing those cells alive and with more than 3 or less than 2 neighbours.
I think your liveNeighbours has a little flaw too: Your are counting (x,y) neighbours and (x,y) itself. You should change it for:
private int liveNeighbours(int x, int y) {
int numLiveNeighbours = 0;
for (int i = x-1; i < x+2; i++) {
for (int j = y-1; j < y+2; j++) {
if (this.state[i][j] == 1 && (x != i || j != y)) {
numLiveNeighbours++;
}
}
}
return numLiveNeighbours;
}