Reputation: 15
I am trying to make a quiz application where the options are shown in buttons.But i want the options to be shown randomly on the buttons.So i used the random class to randomly generate the numbers between 0 and 3 and then add it to an arraylist.The four options are retrieved from the database onto an array.The index of the array will be the elements of the arraylist.
The code is as belows:
public void setoptions(String player_name)
{
//int arr[]=new int[4];
int ran;
Random r=new Random();
ran=r.nextInt(3 - 0 + 1) + 0;
ArrayList<Integer> c=new ArrayList<Integer>();
// c.add(ran);
//Toast.makeText(getApplicationContext(), ran+"",Toast.LENGTH_LONG).show();
for(int i=0;i<c.size();i++)
{
ran=r.nextInt(3 - 0 + 1) + 0;
if(c.contains(ran))
{
i=0;
continue;
}
else
{
c.add(ran);
}
}
c.add(ran);
optarr=dbm.getoptions(player_name);
Toast.makeText(getApplicationContext(),player_name,Toast.LENGTH_LONG).show();
btnopt1.setText(optarr[c.get(0).intValue()]);
btnopt2.setText(optarr[c.get(1).intValue()]);
btnopt3.setText(optarr[c.get(2).intValue()]);
btnopt4.setText(optarr[c.get(3).intValue()]);
// i=(int) Math.random();
//}
}
I am getting the following logcat:
06-04 04:45:03.697: E/AndroidRuntime(30164): FATAL EXCEPTION: main
06-04 04:45:03.697: E/AndroidRuntime(30164): Process: com.example.readfifa, PID: 30164
06-04 04:45:03.697: E/AndroidRuntime(30164): java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
06-04 04:45:03.697: E/AndroidRuntime(30164): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
06-04 04:45:03.697: E/AndroidRuntime(30164): at java.util.ArrayList.get(ArrayList.java:308)
06-04 04:45:03.697: E/AndroidRuntime(30164): at com.example.readfifa.MainActivity.setoptions(MainActivity.java:226)
06-04 04:45:03.697: E/AndroidRuntime(30164): at com.example.readfifa.MainActivity$1.onItemSelected(MainActivity.java:62)
06-04 04:45:03.697: E/AndroidRuntime(30164): at android.widget.AdapterView.fireOnSelected(AdapterView.java:893)
06-04 04:45:03.697: E/AndroidRuntime(30164): at android.widget.AdapterView.access$200(AdapterView.java:48)
06-04 04:45:03.697: E/AndroidRuntime(30164): at android.widget.AdapterView$SelectionNotifier.run(AdapterView.java:861)
06-04 04:45:03.697: E/AndroidRuntime(30164): at android.os.Handler.handleCallback(Handler.java:733)
06-04 04:45:03.697: E/AndroidRuntime(30164): at android.os.Handler.dispatchMessage(Handler.java:95)
06-04 04:45:03.697: E/AndroidRuntime(30164): at android.os.Looper.loop(Looper.java:137)
06-04 04:45:03.697: E/AndroidRuntime(30164): at android.app.ActivityThread.main(ActivityThread.java:4998)
06-04 04:45:03.697: E/AndroidRuntime(30164): at java.lang.reflect.Method.invokeNative(Native Method)
06-04 04:45:03.697: E/AndroidRuntime(30164): at java.lang.reflect.Method.invoke(Method.java:515)
06-04 04:45:03.697: E/AndroidRuntime(30164): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777)
06-04 04:45:03.697: E/AndroidRuntime(30164): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593)
06-04 04:45:03.697: E/AndroidRuntime(30164): at dalvik.system.NativeStart.main(Native Method)
The problem seems to be that the arraylist gets only one value.So how can i get four random numbers between 0 and 3 in the four positions of the arraylist.Please help!!
Upvotes: 0
Views: 1384
Reputation: 852
You can do it like this. Although this is probably not the most efficient algorithm, it is quite easy to comprehend.
public void setoptions(String player_name)
{
ArrayList<Integer> c=new ArrayList<Integer>();
Random random=new Random();
while(c.size() < 4)
{
int randomIndex = random.nextInt(4);
if(false == c.contains(randomIndex))
{
c.add(randomIndex);
}
}
optarr=dbm.getoptions(player_name);
Toast.makeText(getApplicationContext(),player_name,Toast.LENGTH_LONG).show();
btnopt1.setText(optarr[c.get(0).intValue()]);
btnopt2.setText(optarr[c.get(1).intValue()]);
btnopt3.setText(optarr[c.get(2).intValue()]);
btnopt4.setText(optarr[c.get(3).intValue()]);
}
EDIT: This one is more efficient (the loop will always have just 4 iterations)
public void setoptions(String player_name)
{
ArrayList<Integer> options = new ArrayList<Integer>(Arrays.asList(new Integer[]{0,1,2,3}));
ArrayList<Integer> c = new ArrayList<Integer>();
Random random=new Random();
while(options.size() > 0)
{
int randomIndex = random.nextInt(options.size());
c.add(options.remove(randomIndex));
}
optarr=dbm.getoptions(player_name);
Toast.makeText(getApplicationContext(),player_name,Toast.LENGTH_LONG).show();
btnopt1.setText(optarr[c.get(0).intValue()]);
btnopt2.setText(optarr[c.get(1).intValue()]);
btnopt3.setText(optarr[c.get(2).intValue()]);
btnopt4.setText(optarr[c.get(3).intValue()]);
}
Upvotes: 0
Reputation: 714
Like was already said, You have to iterate 4 times in for loop, not the size of empty ArrayList(). Here, I wrote the code simillar to yours:
import java.util.*;
public class Rand {
public static void main(String[] args)
{
Random generator = new Random();
ArrayList<Integer> arr = new ArrayList<Integer>();
for(int i=0; i<4; i++)
{
int r = generator.nextInt(4);
if(!arr.contains(r))
{
arr.add(r);
}
else
{
i--;
}
}
System.out.println(arr);
}
}
Upvotes: 0
Reputation: 355
Your mistake is that you are using c.size() as the variable which limits the size of the loop while as c.size() is modified inside the loop itself.
While using the declaration ArrayList<Integer> c=new ArrayList<Integer>();
the ArrayList c
is created with no element inside it. So c.size() = 0
at this moment. As you add elements to c
using c.add()
method its size is increased.
You should replace c.size
in the loop with 4
or declare c
as ArrayList<Integer> c=new ArrayList<Integer>(4);
Upvotes: 1
Reputation: 3972
You can use a static array and then create a random function to raffle the position of the array.
For example:
your arraylist like this {0, 1, 2, 3} and then you make a get(x); where x = random value between 0 and 3.
Regards
Upvotes: 1
Reputation: 6166
Problem with this line:
i<c.size()
you was't decide the size of array list. means ArrayList
initially having Zero element in it.
therefore you need to add some element in ArrayList
and then iterate it.
for(int counter=0; counter<someSize; counter++){
// Add element logic here
}
Upvotes: 0
Reputation: 366
ArrayList<Integer> c=new ArrayList<Integer>();
and then you call for(int i=0;i<c.size();i++)
The index of the array will be the elements of the arraylist. So that in your function, you should add a parameter to parse it and retrieve it by using list.get()
Upvotes: 0
Reputation: 585
ArrayList c=new ArrayList();
-> c.size() = 0;
-> btnopt1.setText(optarr[c.get(0).intValue()]);
-> error
You need init size of c like that
ArrayList c=new ArrayList(YOUR_SIZE);
Upvotes: 0
Reputation: 81588
If you just want to create a 4-element list with the randomized order of the numbers {0, 1, 2, 3}, you could just create a 4-length array then swap them randomly by specifying the i-th index and a randomized one as per rand.nextInt(4).
Upvotes: 0
Reputation: 45080
If you want to add 4 elements to the list, you need to change your for
loop condition to something like this
for(int i=0; i<4; i++)
Currently, when you give c.size()
, if no element is added or only 1 element is added, the loop stops that time and your list contains no/single element and this gives the IndexOutOfBoundsException
when you try to access the 2nd, 3rd or 4th element in the list.
Upvotes: 1