Evorlor
Evorlor

Reputation: 7568

2D Array Index Out of Bounds Exception

I am new to 2D Arrays, and while I think I understand it, I am unsure why I am getting this Index Out of Bounds Exception. I tried making the map size 70x100, and I still received the same error. It seems to think I am searching for the index -1156638823, which I do not understand why. Any help would be appreciated!

public int rand(int i) {
    return new Random(i).nextInt();
}

public void createMap() {
    map = new Grid[7][10];
    for (int i = 0; i < 7; i++) {
        for (int j = 0; j < 10; j++) {
            map[i][j] = new Grid(false, false, false, false, false, false,
                    false, false, false, false, false, false, false, false,
                    false, false);
        }
    }
    map[rand(7)][0] = new Grid(true, false, true, true, false, true, false,
            false, false, false, false, false, false, false, false, true);
    map[rand(7)][rand(10)] = new Grid(true, false, false, false, false,
            false, true, false, false, false, false, false, false, false,
            false, false);
}

LOGCAT

05-07 19:29:00.183: E/AndroidRuntime(1532): FATAL EXCEPTION: main
05-07 19:29:00.183: E/AndroidRuntime(1532): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.evorlor.dungeonmaster/com.evorlor.dungeonmaster.DM}: java.lang.ArrayIndexOutOfBoundsException: length=7; index=-1156638823
05-07 19:29:00.183: E/AndroidRuntime(1532):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at android.app.ActivityThread.access$600(ActivityThread.java:123)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at android.os.Looper.loop(Looper.java:137)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at android.app.ActivityThread.main(ActivityThread.java:4424)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at java.lang.reflect.Method.invokeNative(Native Method)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at java.lang.reflect.Method.invoke(Method.java:511)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at dalvik.system.NativeStart.main(Native Method)
05-07 19:29:00.183: E/AndroidRuntime(1532): Caused by: java.lang.ArrayIndexOutOfBoundsException: length=7; index=-1156638823
05-07 19:29:00.183: E/AndroidRuntime(1532):     at com.evorlor.dungeonmaster.DM.createMap(DM.java:101)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at com.evorlor.dungeonmaster.DM.initialize(DM.java:19)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at java.lang.reflect.Method.invokeNative(Native Method)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at java.lang.reflect.Method.invoke(Method.java:511)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at sofia.internal.events.EventDispatcher$MethodTransformer.invoke(EventDispatcher.java:474)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at sofia.internal.events.EventDispatcher.invokeTransformer(EventDispatcher.java:136)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at sofia.internal.events.EventDispatcher.dispatch(EventDispatcher.java:109)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at sofia.app.internal.ScreenMixin.invokeInitialize(ScreenMixin.java:561)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at sofia.app.Screen.onCreate(Screen.java:186)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at android.app.Activity.performCreate(Activity.java:4465)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
05-07 19:29:00.183: E/AndroidRuntime(1532):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
05-07 19:29:00.183: E/AndroidRuntime(1532):     ... 11 more

Upvotes: 1

Views: 650

Answers (4)

zbr
zbr

Reputation: 7037

You are using the Random constructor wrong. The parameter in it is a seed. Not a maximum number it will generate.

You can read about what a seed is for example here: http://en.wikipedia.org/wiki/Random_seed

If you need it to generate numbers from 0 to X, you need to provide the X to the nextInt method.

new Random().nextInt(X);

Upvotes: 0

rgettman
rgettman

Reputation: 178353

You are misusing Random. You have invoked the Random constructor that sets the initial seed to a specific value: i. But it does not restrict the random values that come back.

The nextInt() method returns a random, unrestricted int.

You need the following code:

public int rand(int i) {
    return new Random().nextInt(i);
}

The nextInt(int) method restricts the random integers returned to the range 0 to i - 1. Also, the parameterless Random constructor uses the system time to generate a different random seeding (and thus different random numbers) each time.

Random numbers in Java using Random are pseudo-random - they are deterministic but they require a seed to get started. Using the same seed will get you the same random number back. That's why it's important to use different seeds each time, and the parameterless Random constructor handles that for you.

In addition, you don't need to be creating another Random object each time your rand object is called. You could create it as an instance variable in your class and just refer to it in your rand method.

Upvotes: 4

Jack
Jack

Reputation: 133669

new Random(i).nextInt() doesn't do what you think it does.

You should use:

new Random(seed).nextInt(i)

Your version just initialises the seed but nextInt() return an integer in the whole range, if you want a smaller range you need to specify it, by specifying nextInt(i) you will get a value in [0,1)

Upvotes: 4

skuntsel
skuntsel

Reputation: 11742

You used the wrong method: Random#nextInt(). You thought you used Random#nextInt(bound) instead, which yields the random integer within the range 0 (incl.) - bound (excl.). The integer in Random constructor is just a random seed.

Upvotes: 0

Related Questions