This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 7 years ago.
So, I've been doing this java class for several months now, and I've been assigned a project before the end of the year. I'm trying to rewrite some old code to use vectors and arrays, but... I get the topic title error. Here is the relevant code:
public static double VectorX(int len, double angle) {
return Math.cos(angle)*len;
}
public static double VectorY(int len, double angle) {
return Math.sin(angle)*len;
}
public static class Projectile {
public int x;
public int y;
public double angle;
public int speed;
public boolean Player;
}
...
public static Projectile[] Shoot = new Projectile[0];
public static double RadianAngle(int x1, int y1, int x2, int y2) {
return Math.atan2(x2-x1, y2-y1);
}
...
for (int i = 1; i <= Shoot.length; i++)
{
Shoot[i].x += VectorX(Shoot[i].speed, Shoot[i].angle);
Shoot[i].y += VectorY(Shoot[i].speed, Shoot[i].angle);
}
...
if (Cooldown == 75 || Cooldown == 25)
{
Projectile Hey = new Projectile();
Hey.x = EX;
Hey.y = EY;
Hey.Player = false;
Hey.speed = 2;
Hey.angle = RadianAngle(Hey.x, Hey.y, X, Y);
Projectile[] Shoot2 = new Projectile[Shoot.length + 1];
for (int l = 0; l <= Shoot.length - 1; l++)
{
Shoot2[l] = Shoot[l];
}
Shoot2[Shoot2.length - 1] = Hey;
Shoot = Shoot2;
}
I've no idea what is going on. I imported these Vector functions from a C#-based language that I am well versed in, but translated them to java. I am getting the error at
Shoot[i].x += VectorX(Shoot[i].speed, Shoot[i].angle);
Shoot[i].y += VectorY(Shoot[i].speed, Shoot[i].angle);
Could you guys give me a hand?
You're getting an ArrayIndexOutOfBoundsException because you are initializing the Shoot array with a size of 0 :
public static Projectile[] Shoot = new Projectile[0];
so the call to
Shoot[0].x += VectorX(Shoot[0].speed, Shoot[0].angle);
in your loop is invalid.
for (int i = 1; i <= Shoot.length; i++)
should be
for (int i = 0; i < Shoot.length; i++)
the reason why
int[] arr = new int[]{ 0, 1, 2 };
arr.length will now equal 3, my array does not have an index at 3, instead, it has indexes at 0, 1, and 2.
Your definition for the shoot array creates an array of length 0: Shoot = new Projectile[0];
Yet when you iterate over the array, you are setting the bounds of your loop variable incorrectly:
for (int i = 1; i <= Shoot.length; i++)
Arrays are zero-indexed (meaning an array of length 1 will have index [0] and no more). So starting your loop index at 1 (int i = 1) is bad to begin with.
Then you are looping too far. Say you have 3 elements in your array, the indexes will be 0, 1 & 2. And your array.length will be 3, but you never want to index 3. So your loop condition needs to be < array.length, not <= array.length.
Related
I am a beginner(first year uni student) programmer trying to solve this problem which i'm finding somewhat difficult. If you are to answer this question, don't provide me with a complex daunting algorithm that will leave me scratching my head. I'll really appreciate it if you explain it step my step (both logically/conceptually then through code)
The problem is as follows:image
I have tried to attempt it and my code only works for a certain case that i tested.
package com.company;
import java.lang.Math;
public class Main {
public static int[][] binary_partition(int array[], int k){
int x = (int) Math.pow(2,k);
int[][] partition = new int[((array.length/x)*2)][array.length/x];
int divisor = array.length/x;
if ((array.length % 2) != 0){
return partition;
}
if (divisor >= array.length-1){
return partition;
}
if (k==1){
return partition;
}
int p = 0;
for(int i=0;i<((array.length/x)*2);i++)
{
for (int j = 0; j<array.length/x;j++)
{
partition[i][j] = array[p];
p += 1;
}
}
return partition;
}
public static void main(String[] args){
int[] array = {3, 2, 4, 7, 8, 9, 2, 3};
int[][] result = binary_partition(array,2);
for (int[] x : result){
for (int y : x)
{
System.out.print(y + " ");
}
System.out.println();
}
}
}
Your question is unclear, but this solution creates a function that partitions an array with the right length into 2^k sets.
First, an interesting fact: using the bitshift operator << on an integer increases its value by a power of two. So to find out the size of your partition, you could write
int numPartitions = 1 << k; // Equivalent to getting the integer value of 2^k
With this fact, the function becomes
public static int[][] partition(int[] set, int k) {
if (set == null)
return null; // Don't try to partition a null reference
// If k = 0, the partition of the set is just the set
if (k == 0) {
int[][] partition = new int[1][set.length];
// Copy the original set into the partition
System.arraycopy(set, 0, partition[0], 0, set.length);
return partition;
}
int numPartitions = 1 << k; // The number of sets to partition the array into
int numElements = set.length / numPartitions; // The number of elements per partition
/* Check if the set has enough elements to create a partition and make sure
that the partitions are even */
if (numElements == 0 || set.length % numElements != 0)
return null; // Replace with an error/exception of your choice
int[][] partition = new int[numPartitions][numElements];
int index = 0;
for (int r = 0; r < numPartitions; r++) {
for (int c = 0; c < numElements; c++) {
partition[r][c] = set[index++]; // Assign an element to the partition
}
}
return partition;
}
There are a few lines of your code where the intention is not clear. For example, it is not clear why you are validating divisor >= array.length-1. Checking k==1 is also incorrect because k=1 is a valid input to the method. In fact, all your validation checks are not needed. All you need to validate is that array.length is divisible by x.
The main problem that you have seems to be that you mixed up the lengths of the resulting array.
The resulting array should have a length of array.length / x, and each of the subarrays should have a length of x, hence:
int[][] partition = new int[array.length/x][x];
If you also fix your bounds on the for loops, your code should work.
Your nested for loop can be rewritten as a single for loop:
for(int i = 0 ; i < array.length ; i++)
{
int index = i / x;
int subArrayIndex = i % x;
partition[index][subArrayIndex] = array[i];
}
You just need to figure out which indices a an element array[i] belongs by dividing and getting the remainder.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I currently have a problem with creating objects using two-dimensional arrays in Java.
I'ld like to display bricks on a playing board (like in the classic "BreakOut games), therefore I created a class "Stone" for the stone-objects, the constructor of the class is:
public Stone (Position pos, int value){
this.pos = pos;
this.type = type;
}
I also created a 2D-array (int) called "stoneTypes" for the pattern of the Stones, in which I saved a matrix from a JSON file.
I ld' now like to create Stone-objects in my class "Level" by using the values of the stoneTypes-matrix, which currently looks like this (I included an if-condition, so Stone-objects are only created for stoneTypes value >= 1):
private Stone[][] stones = new Stone[25][20];
private int[][] stoneTypes;
JSONReader reader = new JSONReader("res/Level" + levelnr +".json");
stoneTypes = reader.getStones2DArray();
for (int w = 0; w < stoneTypes.length; w++) {
for (int h = 0; h < stoneTypes[w].length; h++) {
if (stoneTypes [w][h] >= 1) {
Position pos = new Position(width * w, height * h);
this.stones[w][h] = new Stone(pos, stoneTypes[w][h]);
}
}
}
I also included a get-Method for the Stone-array, so I could use it to draw the Stones in my "Field" class:
public Stone[][] getStones(){
return this.stones;
}
The method for drawing the Stones in my "Field" class currently looks like this:
private void drawStones(Graphics2D g2) {
stones = view.getGame().getLevel().getStones();
for (int i = 0; i < stones.length; i++) {
for (int j = 0; j < stones[i].length; j++) {
*** int x_position = (int) stones[i][j].getPosition().getX(); ***
int y_position = (int) stones[i][j].getPosition().getY();
g2.fillRoundRect(x_position, y_position,
(int) ((double)Constants.SCREEN_WIDTH/Constants.SQUARES_X)-2,
(int) ((double)Constants.SCREEN_HEIGHT/Constants.SQUARES_Y)-2 ,1,1);
System.out.println(x_position);
}
}
}
Eclipse doesn't show any syntax errors but I do receive a NullPointerException at the spot I marked with the ***, as soon as I start the programm. I am not sure if my get-Method isn't implemented correctly or if the process of creating new Stone-objects is simply wrong. I tried hundreds of things but couldn't find a solution, I hope you guys can help me.
Thx in advance, Scoopa!
Here:
if (stoneTypes [w][h] >= 1) {
Position pos = new Position(width * w, height * h);
this.stones[w][h] = new Stone(pos, stoneTypes[w][h]);
}
You are only creating new stones when that condition is met. All other fields will stay with their default initial value. And that would be: null.
When you do that, you can't just go in (unconditionally) and do:
int x_position = (int) stones[i][j].getPosition().getX()
You would need a
if (stones[i][j] != null)
to guard such accesses!
I'm getting an error on line 4 saying "forgot a .class, probably at the end." Can somebody please tell me what the solution is?
Side note - Java.util has been imported.
public double median(int[] arr)
{
int[] sortedArr = Arrays.sort(arr[]);
int arrayIndex = 0;
int halfArrayIndex = 0;
for(int i = 0; i < sortedArr.length; i++)
{
arrayIndex = i;
}
if(arrayIndex % 2 == 0)
{
halfArrayIndex = arrayIndex / 2;
return sortedArr[half];
}
else
{
halfArrayIndex = arrayIndex / 2;
return ((double)sortedArr[half + 1] + sortedArr[half]) / 2;
}
}
This line is incorrect:
int[] sortedArr = Arrays.sort(arr[]);
It should be:
Arrays.sort(arr);
Notice that:
Arrays.sort() doesn't return a value
You must not write [] when passing an array as parameter
When you sort an array, it'll be modified in-place, bear that in mind, because the original array passed as parameter to this method will be changed after this method returns, unless you make a copy of it
I'm writing a deck with 52 cards. Everything is perfect but I can't figure out how to shuffle it without using any library from java and using the sort method built into java. Here is my code. I been trying to figure something out for a while and so far I'm unable to.
String [] deck2=new String [52];
String[] deck=new String [52];
String suits[]={"Spades","Hearts","Diamonds","Clubs"};
String rank[]={"2","3","4","5","6","7","8","9","10","Jack","King","Queen","Ace"};
for(int i=0;i<deck.length;i++){
deck[i]=rank[i%13]+" "+"of "+suits[i/13];
deck2[i]=deck[i];
System.out.println(deck[i]);
}}}
Of course it's possible. After all, a library is nothing more than some code you could as well write yourself. You'll have to write your own random number generator. This is one simple example:
private static long x = System.currentTimeMillis();
public static long rndNumber() {
x ^= (x << 21);
x ^= (x >>> 35);
x ^= (x << 4);
return x < 0 ? -x : x;
}
public static void shuffle(int a[]) {
for (int i = a.length - 1; i > 0; i--) {
int pos = (int) (rndNumber() % a.length);
int temp = a[i];
a[i] = a[pos];
a[pos] = temp;
}
}
public static void main(String[] args) {
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
System.out.println(Arrays.toString(a));
shuffle(a);
System.out.println(Arrays.toString(a));
}
for (int i = 0; i < 500; i++) {
int from = (int) (Math.random() * array.length); //The place to get the first from
int to = (int) (Math.random() * array.length); // The place to get the second from
String perm = array[from]; // Store the "from" value
array[from] = array[to]; // Set the first value to the second
array[to] = perm; // Set the second value to the first
}
I don't know, why you don't want to use a java built-in library, they are there for a reason.
To create a random number without any built in methods is hard. I found a way long time ago, using float, and making it overflow
float random = 1 << 32 + 1256224; //Have a random number here, it doesn't matter
I didn't tested it, this may not work.
float random = 1 << 32 + 1256224;
String [] deck2=new String [52];
String[] deck=new String [52];
String suits[]={"Spades","Hearts","Diamonds","Clubs"};
String rank[]={"2","3","4","5","6","7","8","9","10","Jack","King","Queen","Ace"};
for(int i=0;i<deck.length;i++){
deck[i]=rank[i%13]+" "+"of "+suits[i/13];
deck2[i]=deck[i];
System.out.println(deck[i]);
}
for (int i = 0; i < 500; i++) {
int from = (int) (Math.random() * array.length); //The place to get the first from
int to = (int) (Math.random() * array.length); // The place to get the second from
String perm = array[from]; // Store the "from" value
array[from] = array[to]; // Set the first value to the second
array[to] = perm; // Set the second value to the first
}
}}
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 7 years ago.
I am developing a Java game, and am currently writing a map maker. I can make the map and draw tiles, but i need to be able to change the position of those tiles so the character can see different locations of the map. When I try to change it, in the moveMap() method, It gives me this error:
Exception in thread "Thread-2" java.lang.ArrayIndexOutOfBoundsException: 570
at Base.moveMap(Base.java:88)
at Base.run(Base.java:55)
at java.lang.Thread.run(Unknown Source)
I have no idea why this is happening - could someone please help me understand the problem. Is there any alternate way to move the tiles?
Here is my code...
public class Base extends JPanel implements Runnable {
private static String[] line = {
"wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww",
"wwwwwwwwwwwwwwwwfffffffffffwwwwwwwwwww",
"wwwwwwffwwwwwwwwfwwwwwwwwwwwwwwwwwwwww",
"wwwwwwfffffffwwwfwwwwwwwwwwwwwwwwwwwww",
"wwwwwwffwwwffffffwwwwwwwwwwwwwwwwwwwww",
"wwwwwwffwwwffffffwwwwwwwwwwwwwwwwwwwww",
"wwwwwwfffffffwwwwwwwwwwwwwwwwwwwwwwwww",
"wwwwwwffwwwwwwwwwwwwwwwwwwwwwwwwwwwwww",
"wwwwwwffwwwwwwwwwwwwwwffffffffwwwwwwww",
"wwwwwwffwwwwwwwwwwwwwwwwwwwwffwwwwwwww",
"wwwwffffffwwwwwwwwwwwwwwwwwwffwwwwwwww",
"wwwwffffffffffffffffffffffffffwwwwwwww",
"wwwwffffffwwwwwwwwwwwwwwwwwwwwwwwwwwww",
"wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww",
"wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww",};
private Rectangle[] colRect;
private int tileWidth = 30;
private int tileHeight = 30;
public Base() {
colRect = new Rectangle[line.length * line[0].length()];
for (int i = 0; i < line.length; i++) {
for (int f = 0; f < line[i].length(); f++) {
colRect[counter] = new Rectangle(f * tileWidth, i * tileHeight,tileWidth, tileHeight);
if (counter != colRect.length) {
counter += 1;
}
}
}
}
public void moveMap(){
for(int i = 0; i <= colRect.length; i++){
colRect[i].setLocation(colRect[i].x+1, colRect[i].y+1);
}
}
}
You almost certainly mean this:
for (int i = 0; i < colRect.length; i++) {
Instead of this:
for(int i = 0; i <= colRect.length; i++){
Remember that if an array has length n, the indexes go from 0 to n - 1.
I would suggest you just to modify the accessor to your geometry, than the map itself. Because it looks like, the function moveMap could have some kind of "loop" behaviour
getLocation (int index, offset = 0){
int accIndex = (index + offset) % colRect.length;
// ... probably better to modify your data-structure to simplify the handling
}