My program is a quiz which asks questions for US States
I create three instances of a class say State
State st1 = new State();
State st2 = new State();
State st3 = new State();
like it asks a question about a state what is capital of st1.name
and line below that it gives 3 option
String Builder sb;
sb.append("What is Capital of "+st1.name+"\n");
sb.append("\n"+st1.capital);
sb.append("\n"+st2.capital);
sb.append("\n"+st3.capital);
mainText.setText(sb.toString);
now the problem is every time it comes up with correct answer in first line...
how do i avoid that ?
Put the correct answer in a random spot using Java's Random class
Random.nextInt(3) will give you a random number between 0 and 2. Put your correct answer into an array of size 3 at location and put the two wrong answers in the remaining locations. Then loop through that array and sb.append(array[i]); (i between 0 and 2) to get your random ordering of state capitals.
Create an ArrayList the pull the objects out randomly.
This code is totally untested, but I don't think it's too far off...
This will (theoretically) list the answers in totally random order.
ArrayList<State> states = new ArrayList<State>();
Random rand;
states.add(new State());
states.add(new State());
states.add(new State());
sb.append("What is Capital of "+states.get(0).name+"\n");
int randomNum = 0;
while (states.size() > 0) {
randomNum = rand.nextInt(1 - states.size() + 1);
sb.append("\n"+states.get(randomNum).capital);
states.remove(randomNum)
}
mainText.setText(sb.toString);
Related
I am making an app with Xamarin Android. It has 4 turns, and I want a random picture+sound to display in every turn. So far so good, but now I want to make it in a way that it won't show the same picture+sound(the same random number) twice. I have tried some codes from other treads, but unfortunately that did not work.
Following is what I tried from the other treads:
if (ActivityGame.playing == false)
{
List<int> alreadyGuessed = new List<int>();
Random randomSound = new Random();
int theSound = randomSound.Next(1, 5);
while (alreadyGuessed.Contains(theSound))
theSound = randomSound.Next(1, 5);
alreadyGuessed.Add(theSound);
return theSound;
}
You declare the alreadyGuessed list inside the if-branch. So, every time you get in that if branch, the program creates a new, empty list named alreadyGuessed.
You should make alreadyGuessed a member variable of your ActivityGame class, so it will retain the values already used.
I am trying to randomly call methods to make it use a different animation every time to display a textview. I trie using an array but not sure how to implement it. My array looks like this (obviously I know it shouldn't be strings but not sure what data type or if even possible this way).
String [] mAnimations = {"Hinge","RollIn", "Landing",
"BounceIn", "BounceInDown", "BounceInLeft", "BounceInRight",
"BounceInUp", "FadeIn", "FadeInUp", "FadeInDown", "FadeInLeft",
"FadeInRight","FlipInX", "RotateIn", "RotateInDownLeft", "RotateInDownRight",
"RotateInUpLeft", "RotateInUpRight", "SlideInLeft", "SlideInRight",
"SlideInUp", "SlideInDown", "ZoomIn", "ZoomInDown", "ZoomInLeft",
"ZoomInRight", "ZoomInUp"};
Putting any of the correct animations by themselves it works fine (Note BounceInLeft):
YoYo.with(Techniques.BounceInLeft)
.duration(1000)
.playOn(textView);
But what I am trying to do is randomly pick an animation from the array something like this:
Random rand = new Random();
int n = rand.nextInt(mAnimations.length) + 1;
YoYo.with(Techniques.(mAnimations[n]))
.duration(1000)
.playOn(textView);
Thanks for your help
Nicholas
Best Directly Assign method based on Random numbers.Because (mAnimations[n]) value consider as String.
String [] mAnimations = {"Hinge","RollIn", "Landing",
"BounceIn", "BounceInDown", "BounceInLeft", "BounceInRight",
"BounceInUp", "FadeIn", "FadeInUp", "FadeInDown", "FadeInLeft",
"FadeInRight","FlipInX", "RotateIn", "RotateInDownLeft", "RotateInDownRight",
"RotateInUpLeft", "RotateInUpRight", "SlideInLeft", "SlideInRight",
"SlideInUp", "SlideInDown", "ZoomIn", "ZoomInDown", "ZoomInLeft",
"ZoomInRight", "ZoomInUp"};
Random rand = new Random();
int n = rand.nextInt(mAnimations.length);
if(n==0)
{
YoYo.with(Techniques.Hinge).duration(1000).playOn(textView);
}
if(n==1)
{
YoYo.with(Techniques.RollIn).duration(1000).playOn(textView);
}
When I do
ArrayList<Integer> arr = new ArrayList<Integer>(10);
arr.set(0, 1);
Java gives me
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.set(Unknown Source)
at HelloWorld.main(HelloWorld.java:13)
Is there an easy way I can pre-reserve the size of ArrayList and then use the indices immediately, just like arrays?
How about this:
ArrayList<Integer> arr = new ArrayList<Integer>(Collections.nCopies(10, 0));
This will initialize arr with 10 zero's. Then you can feel free to use the indexes immediately.
Here's the source from ArrayList:
The constructor:
public ArrayList(int initialCapacity)
{
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
this.elementData = new Object[initialCapacity];
}
You called set(int, E):
public E set(int index, E element)
{
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
Set calls rangeCheck(int):
private void rangeCheck(int index)
{
if (index >= size) {
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
}
It may be subtle, but when you called the constructor, despite initializing an Object[], you did not initialize size. Hence, from rangeCheck, you get the IndexOutOfBoundsException, since size is 0. Instead of using set(int, E), you can use add(E e) (adds e of type E to the end of the list, in your case: add(1)) and this won't occur. Or, if it suits you, you could initialize all elements to 0 as suggested in another answer.
I believe the issue here is that although you have suggested the allocated space of entries in the Array, you have not actually created entries.
What does arr.size() return?
I think you need to use the add(T) method instead.
Programming aside, what you are trying to do here is illogical.
Imagine an empty egg carton with space for ten eggs. That is more or less what you have created. Then you tell a super-precise-and-annoying-which-does-exactly-what-you-tell-him robot to replace the 0th egg with another egg. The robot reports an error. Why? He can't replace the 0th egg, because there is no egg there! There is a space reserved for 10 eggs, but there are really no eggs inside!
You could use arr.add(1), which will add 1 in the first empty cell, i.e. the 0-indexed one.
Or you could create your own list:
public static class PresetArrayList<E> extends ArrayList<E> {
private static final long serialVersionUID = 1L;
public PresetArrayList(int initialCapacity) {
super(initialCapacity);
addAll(Collections.nCopies(initialCapacity, (E) null));
}
}
Then:
List<Integer> list = new PresetArrayList<Integer>(5);
list.set(3, 1);
System.out.println(list);
Prints:
[null, null, null, 1, null]
This is not an Java-specific answer but an data structure answer.
You are confusing the Capacity concept with the Count (or Size) one.
Capacity is when you tell the list to reserve/preallocate a number of slots in advance (in this ArrayList case, you are saying to it create an array of 10 positions) in its' internal storage. When this happens, the list still does not have any items.
Size (or Count) is the quantity of items the list really have. In your code, you really doesn't added any item - so the IndexOutOfBoundException is deserved.
While you can't do what you want with arraylist, there is another option: Arrays.asList()
Capacity is used to prepare ArrayLists for expansion. Take the loop
List<Integer> list = new ArrayList<>();
for(final int i = 0; i < 1024; ++i) {
list.add(i);
}
list starts off with a capacity of 10. Therefore it holds a new Integer[10] inside. As the loop adds to the list, the integers are added to that array. When the array is filled and another number is added, a new array is allocated twice the size of the old one, and the old values are copied to the new ones. Adding an item is O(1) at best, and O(N) at worst. But adding N items will take about 2*1024 individual assignments: amortized linear time.
Capacity isn't size. If you haven't added to the array list yet, the size will be zero, and attempting to write into the 3rd element will fail.
BigInteger q = new BigInteger(8, 10, new Random()); is giving me random numbers as expected every time while running from my Desktop but not in Android.
in Android I am always getting only same output instead of random number. Please help me to get random BigIntegr.
for your info:
int randQ = (int) (Math.random() * 9);
for (int r = 0; r < randQ; r++) {
q = q.nextProbablePrime();
}
is the quick fix that I did and I am not happy with this fix since it is consuming extra time.
your suggestions are highly appreciated
This is a very common problem, independent of language or platform.
You must reuse the instance of Random() to get random numbers each time. The default constructor will seed the pseudo-random number generator with the current time. The current time doesn't change very quickly with respect to your program, so you keep getting the same number until the clock ticks up.
If you don't re-seed, it will give you different numbers each time you ask for another value. You can avoid re-seeding by reusing the instance, and calling:
Random random = new Random(); // reuse this instance...
int value = random.nextInt(); // use these values instead of new Random()
See: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Random.html
EDITED
Instead use:
// creates random object with current instant as seed
Random generator = new Random((new Date()).getTime());
BigInteger q = new BigInteger(8, 10, generator);
I want to work dynamically therefore I want to bind text views dynamically I think an example would explain me the best
assuming I want to bind 7 image views i can do it like this :
Country = (EditText)findViewById(R.id.CountryEditText);
City = (EditText)findViewById(R.id.CityEditText);
LivinigCreture = (EditText)findViewById(R.id.LivingCretureE);
Nature =(EditText)findViewById(R.id.NatureEditText);
Inanimate = (EditText)findViewById(R.id.InanimateEditText);
KnowenPersonality = (EditText)findViewById(R.id.KnowenPersonalityEditText);
Occupation = (EditText)findViewById(R.id.OccupationEditText);
but lets change 7 with NUMOFFILEDS as a final where i want to do the previous ?
myImages = new ImageView [7];
for (int i = 0; i<7;i++,????)
myImages[i] = (ImageView)findViewById(R.id.initialImageView01);
notice : in my R file the R.id.initialImageView01 - R.id.initialImageView07 are not generate in a cont gap between them therefore I don't know how to make this architecture possible .
and if there's a way can someone show me an example how to work dynmiclly (like using jsp on android combined way or something ?)
id its possiable to do so constant times is it possible to build an the same xml constant num of times like jsp does
thank u pep:)
You can store the IDs themselves in an array at the beginning of your Activity; that way you'll only need to write them once and you can index them afterwards.
Something like:
int[] initialImageViewIds = {
R.id.CountryEditText,
R.id.CityEditText,
R.id.LivingCretureE,
R.id.NatureEditText,
R.id.InanimateEditText,
R.id.KnowenPersonalityEditText,
R.id.OccupationEditText
};
Then you can access them with:
myImages = new ImageView [7];
for (int i = 0; i<7;i++) {
myImages[i] = (ImageView)findViewById(initialImageViewIds[i]);
}
If that's not enough and you really want to get the IDs dynamically, I suppose you can use reflection on the R.id class, possibly with something like R.id.getClass().getFields() and iterate on the fields to check if their names interest you. Check reference for the Class class, too.