Exception in thread \"main\" java.lang.ArrayIndexOutOfBoundsException: 4 at java
ID: 3678001 • Letter: E
Question
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
at javaapplication19.Board.checkRow(JavaApplication19.java:297)
at javaapplication19.Board.canMove(JavaApplication19.java:280)
at javaapplication19.Board.move(JavaApplication19.java:257)
at javaapplication19.Game.play(JavaApplication19.java:416)
at javaapplication19.JavaApplication19.main(JavaApplication19.java:27)
I need help, everytime I run my code I get this error. How can I fix it?
this is the code:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package javaapplication19;
/**
*
* @author Raghad Marta
* @pid: A92090716
*/
import java.util.Random;
import java.util.Scanner;
public class JavaApplication19 {
public static void main(String[] args) {
Board b = new Board(5);
int x[][] = new int[5][5];
b.setBoard( x);
b.getRow(Direction.UP, 2);
Game g = new Game();
g.play();
// TODO code application logic here
}
}
enum Direction {UP,DOWN,LEFT,RIGHT};
/**
* @author ajundt
* Board maintains all values stored in the 2048 board.
* You can use this class to get access to individual rows or
* the whole shebang.
*/
class Board {
private static void swapNumbers(int[] row, int i, int i0) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
private int[][] board = null;
private int boardSize =0;
private Random rand;
/**
* Creates a default board of size [4][4]
*/
public Board() {
this(4);
}
/**
* Creates the board of size [size][size]
*
* @param size - the size of the board
*/
public Board(int size) {
boardSize = size;
board = new int[boardSize][boardSize];
rand = new Random();
for (int i = 0; i < boardSize; i++) {
for (int j = 0; j < boardSize; j++) {
board[i][j] = 0;
}
}
}
/**
* initialize board for testing purposes
*
* @param board 2D array representing the 2048 board
*/
public void setBoard(int[][] board) {
this.board = board;
}
/**
* return an individual row translated based on direction, e.g.
* [1, 2, 3
* 4, 5, 6
* 7, 8, 9]
* getRow(LEFT, 0) => [1,2,3]
* getRow(UP, 0) => [1,4,7]
* getRow(RIGHT,0) => [3,2,1]
* getRow(DOWN, 1) => [8,5,2]
*
* @param dir - the direction the row will be translated to
* @param rowNumber - the row number
*/
public int[] getRow(Direction dir, int rowNumber) {
int[] row = new int[board.length];
int i = 0;
switch (dir) {
case LEFT:
for (i = 0; i row[i] = board[rowNumber][i];
}
break;
case RIGHT:
for (i = boardSize; i >0; i--) {
row[i] = board[rowNumber][boardSize];
}
break;
case UP:
for (i = 0; i row[i] = board[rowNumber][i];
}
break;
case DOWN:
for (i = boardSize; i>0; i--) {
row[i] = board[rowNumber][i];
}
break;
default:
System.out.println("Invalid direction provided");
break;
}
return row;
}
/**
* put an individual row translated based on direction into the board, e.g.
* [1, 2, 3
* 4, 5, 6 q
* 7, 8, 9]
* putRow(LEFT, [3,4,5], 0) => board = [3,4,5
* 4,5,6
* 7,8,9]
* putRow(Right, [3,4,5], 0)=> board = [5,4,3
* 4,5,6
* 7,8,9]
* putRow(UP, [3,4,5], 1) => board = [1,3,3
* 4,4,6
* 7,5,9]
* putRow(DOWN, [3,4,5], 1) => board = [1,5,3
* 4,4,6
* 7,3,9]
* getRow(UP, 0) => [1,4,7]
* getRow(RIGHT,0) => [3,2,1]
* getRow(DOWN, 1) => [8,5,2]
*
* @param dir - the direction the row will be translated to
* @param row - the row to be inserted into the board (untranslated)
* @param rowNumber - the row number
* @return
*/
public void putRow(Direction dir, int[] row, int rowNumber) {
int i;
switch (dir) {
case LEFT:
for (i = 0; i board[rowNumber][i] = row[i];
}
break;
case RIGHT:
for (i = 0; i board[rowNumber][boardSize - 1 - i] = row[i];
}
break;
case UP:
for (i = 0; i < boardSize; i++) {
board[i][rowNumber] = row[i];
}
break;
case DOWN:
for (i = 0; i board[boardSize - 1 - i][rowNumber] = row[i];
}
break;
default:
System.out.println("Invalid direction provided");
break;
}
return;
}
public int[][] getBoard() {
return board;
}
/**
* inserts a 2 into a random open space on the board
*
* @return false if no open slots, true otherwise
*/
public boolean insertNumber() {
int numSlots = getNumSlots();
int nextSlot = 0;
int slots = 0;
if (numSlots != 0) {
nextSlot = rand.nextInt(numSlots);
for (int i = 0; i for (int j = 0; j if (board[i][j] == 0 && nextSlot == slots) {
board[i][j] = 2;
return true;
} else if (board[i][j] == 0) {
slots++;
}
}
}
}
return false; //unable to fill a slot
}
/**
*
* @return Number of slots with no number
*/
private int getNumSlots() {
int slots = 0;
for (int i = 0; i for (int j = 0; j if (board[i][j] == 0)
slots++;
}
}
return slots;
}
/**
* Move the board in the given direction
*
* @param dir Direction to move
*/
public boolean move(Direction dir) {
int[] row;
boolean canMove = canMove(dir);
if (canMove) {
for (int i = 0; i row = getRow(dir, i);
transform(row);
putRow(dir, row, i);
}
}
return canMove;
}
/**
* Can anything on the board move in the specified direction?
* @param dir Direction to check
* @return
*/
public boolean canMove(Direction dir) {
boolean rowCanMove = false;
int[] row;
for (int i = 0; i row = getRow(dir, i);
rowCanMove = checkRow(row);
if (rowCanMove)
return true;
}
return false;
}
/**
* Test that this row can be moved to the left
* @param row Row/column already translated by getRow
*/
public static boolean checkRow(int[] row) {
boolean nonEmpty = false;
//if row is empty, return false... we cant move this row
for (int i = 0; i <=row.length; i++) {
if (row[i] != 0) nonEmpty = true;
}
if (!nonEmpty)
return false;
//Row isn't empty
for (int i = 1; i < row.length; i++) {
if (row[i - 1] == 0) {
return true; //previous slot is empty, we can go left
} else if (row[i - 1] == row[i] && row[i] != 0) {
return true; //2 numbers are the same, can go left and merge
}
}
return false;
}
/**
* Operate on a single row, always shifting to left if possible
* this is where the magic actually happens and is the hardest
* part of the problem
*
* @param row One row or column, already translated by getRow
*/
public static void transform(int[] row) {
boolean nonEmpty = false;
int index = 1;
//if row is empty, return, nothing to do
for (int i = 0; i <=row.length; i++) {
if (row[i] != 0)
nonEmpty = true;
}
if (!nonEmpty)
return;
//There is at least one entry in the board
for (int i = 0; i < row.length ; i++) {
if (row[index - 1] == 0) {
shift(row, index); //previous spot is blank, move everything left
} else if (row[index] == 0 && ((index + 1) < row.length)) {
shift(row, index + 1); //current is blank, shift toward current
} else if (row[index - 1] == row[index]) {
row[index - 1] *= 2; //Merge 2 numbers
shift(row, index);
index++;
} else {
index++;
}
}
}
/**
* Shift everything in a row left, starting at a given index
* The element at index-1 will be destroyed
*
* e.g.
* 2 0 0 2, index=1
* -->
* 0 0 2 0
*
*
*
* @param row row to shift
* @param index Shift all elements starting from here onwards to the
* left by 1 spot
* Must have index > 0
*/
public static void shift(int[] row, int index) {
int i=index;
for ( i = index;i {
// swapNumbers1(row,index--,i);
row[i--] = row[i];
}
}
public static void swapNumbers1(int [] row, int pos1, int pos2){
int temp = row[pos2];
row[pos2] = row[pos1];
row[pos1] = temp;
}
}
class Game {
private Board board;
/**
* Creates a new board
*/
public Game() {
this(new Board());
}
/**
*
* @param b already initialized board to use
*/
public Game(Board b) {
this.board = b;
}
/**
* Start the game
* Take input and dish out the moves
*/
public void play() {
char input;
boolean move_result = false;
printControls();
board.insertNumber();
board.insertNumber();
printBoard();
while ((input = takeInput()) != 'q') {
move_result = false;
if (input == 'w') { //UP
move_result = board.move(Direction.UP);
} else if (input == 's') { //DOWN
move_result = board.move(Direction.DOWN);
} else if (input == 'a') { // LEFT
move_result = board.move(Direction.LEFT);
} else if (input == 'd') { // RIGHT
move_result = board.move(Direction.RIGHT);
} else { //invalid char
printControls();
}
if (move_result) {
board.insertNumber();
} else {
System.out.println("nothing's changed");
}
printBoard();
}
}
private char takeInput() {
Scanner scnr = new Scanner(System.in);
System.out.print(">");
return scnr.next().charAt(0);
}
/**
* print the current state of the board
*/
private void printBoard() {
int[][] a = board.getBoard();
String current;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
if (a[i][j] == 0)
current = " -";
else
current = String.format("%5d", a[i][j]);
System.out.print(current);
}
System.out.println();
}
}
/**
* Print out the control menu for the game
* What keys map to what
*/
private void printControls() {
System.out.println("Controls:");
System.out.println(" w - Move UP");
System.out.println(" s - Move Down:");
System.out.println(" a - Move Left");
System.out.println(" d - Move Right");
System.out.println(" q - Quit");
}
}
Explanation / Answer
Java programming language provides implicit bound checks on Array, which means an invalid array index access is not allowed in Java and it will result in java.lang.ArrayIndexOutOfBoundsException
The reason the exception happens is that you row.length not define so going to go out of bounds.Keep in mind that arrays are 0 indexed,so if you have an array of length 10, it has available indices of 0 through 9 inclusive. With the = you had in your for loops, you were going 1 past the available indices.
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.