How to get random textstring from array, "loop-animation" like lottery? - java

I'm building a very simple Android-app without almost any knowledge in java programming.
The application is almost done and what the app does is that when I press a button it shows a value randomly from an string array.
What I would like to achieve is a small "animation" where it quickly scrolls through all the values ​​in the array and then randomly stops. Almost as a "spinning wheel of text".
I have figuered out that maybe a Timer-function is the way to go. Would be great if someone could help me out.
This is the array with all values:
final String[] myNames = {
"Sax12345",
"Tyg12345",
"Djur12345",
"Hund12345",
"Trafik2019",
"Gruvan2019",
"Kaffe2019"
};
And this is what happens when the button is pressed:
genButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Random randGen = new Random();
int rando = randGen.nextInt(7);
textOne.setText(myNames[rando]);
}
});

Simply duplicate (or even multiplicate - depends on the animation length) values inside your array and shuffle this. Then in a loop, iterate over the table, putting with some interval the following values to the view, and stop on the last element - this one will be the random one (thanks to the shuffle method)
Something like
List<String> presentationList = new ArrayList<>();
for(int i = 0; i < HOW_MUCH_SHOULD_IT_BE_MULTIPLICATED; i++) {
presentationList.addAll(Arrays.asList(myNames));
}
Collections.shuffle(presentationList);
String winnerString = presentationList.get(presentationList.size() - 1); //this is basically winner string
// now the time for 'animation'
for(String value : presentationList) {
textOne.setText(value);
// wait for a Xms
}

Related

Iterate through a loop to print arraylist with 1sec delay in a textview Android Studio

I am trying to print the elements of an ArrayList one at the time with a delay in the same TextView, no matter what I try, when executed there is a delay, but the only element printed is the last of the array. Just to extend on the context, the method "iniciate" is executed on an onClick of a button, then a random number is added to the ArrayList and the elements are printed on the textview one at the time with a delay (that´s what I am trying to achieve), the every time the method is executed it adds an extra element to the ArrayList and print it.
public class MainActivity extends AppCompatActivity {
private EditText et1;
private TextView tv2;
private ArrayList<String> numbers=new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et1=findViewById(R.id.et1);
tv2=findViewById(R.id.tv2);
}
public void iniciate(View view){
numbers.add(String.valueOf ((int) (Math.random() * 10)+1));
for (int i = 0; i < numbers.size(); i++){
tv2.setText(numbers.get(i));
tv2.postDelayed(new Runnable() {
#Override
public void run() {
tv2.setText("");
}
},2000);
}
}
}
By reading the code, I can see that there's only one element in the array, so your function printing only one element makes sense. This is because you're only adding to the array once, a random number times 10 plus 1, casted to String.
numbers.add(String.valueOf ((int) (Math.random() * 10)+1));
I checked using an online java compiler. The test is here.
That being said, my guess is that you're dinamically adding elements to the array using that code (Using events, perhaps?). If so, please update your question adding that, since as it is, it seems you just need to add a little loop surrounding the add() method of numbers, like:
int i = 0;
while(i < 10) {
numbers.add(String.valueOf((int)(Math.random() * 10)+1));
i++;
}

Random but each should appear only once

I'm making an app with android studio.
I wanted to make a "Random" function. This is what it looks like in java:
final String[] lesquestions = {"random1", "random2", "random3"};
b_question.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int rando_questions = (int) (Math.random() * 3);
question.setText(lesquestions[rando_questions]);
}
});
It works fine, but I want that when a string appears, it is taken out of the list, so it doesn't appear twice.
Edit: more precisely: the randoms are questions, and i want that the questions only appear once, no repetitions.
final List<String> lesquestions = newArrayList<>();
Collections.addAll(lesquestions, "random1", "random2", "random3");
b_question.setOnClickListener(new View.OnClickListener() {
Random random = new Random();
#Override
public void onClick(View view) {
if (lesquestions.isEmpty()) {
question.setText("Fini");
return;
}
int questionIndex = random.nextInt(lesquestions.size());
question.setText(lesquestions.remove(questionIndex));
}
});
To pick a new, random question, one can remove the randomly picked item, but not from a fixed size array, but a collection, a Set<String> if the questions must be unique,
or a List<String> if you would like the possibility of a repeated question.
Arrays.asList would convert an array / enumeration of strings to a List, backed by that array, so fixed size. So that cannot be used when one wants removal.
Creating a Random is a bit more circumstantial than Math.random but nextInt(int n) is much more clear: a value 0, 1, 2, ..., n-1.
List.remove returns the removed element, so it works as a getter at the same time.
At one time no questions remain.
Bon chance.
First of all, use Java list instead of array, so it's gonna be much more comfortable to manage it, and then do something like this:
final List<String> lesquestions = new ArrayList<>(Arrays.asList("random1", "random2", "random3"));
b_question.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int rando_questions = (int) (Math.random() * lesquestions.size());
question.setText(lesquestions.remove(rando_questions));
}
});

Random Number Occurrence Check

I have an array of Strings and when the user taps the button inside my app I generate a random number and use it to select a random String from my facts[] array. However, I tried improving my code so that the same random number would "never" occur(leading to the same String been shown to the user). Despite my efforts, my "Check" blocks doesn't seem to work since it generates a random fact when I click the button for the first time and then it does nothing. Please help me figure out the correct logic behind this and maybe write a more efficient code-block.
My current logic: check if the random number that has been generated already exists in my int[] factsCheck array and if it does create another one.If it doesn't add it to the array so that the program knows it has already been created once.
int[] factsCheck = new int[facts.length];
boolean isNotNewRandomNumber = true;
int count = 0;
int randomNumberToReturn;
private void initFactsCheck() {
for(int i=0; i<=factsCheck.length;i++) {
factsCheck[i] = -1;
}
}
String getFact() {
// Randomly select a fact
Random randomGenerator = new Random();
while(isNotNewRandomNumber) {
randomNumberToReturn = randomGenerator.nextInt(facts.length);
for(int i = 0; i<factsCheck.length; i++) {
if(factsCheck[i] == randomNumberToReturn) {
break;
} else {
count++;
}
}
if (count == factsCheck.length) {
// Doesn't exist
isNotNewRandomNumber = false;
}
count = 0;
}
return facts[randomNumberToReturn];
}
In the beginning of getFacts(), add this:
isNotNewRandomNumber = true;
The problem is that you isNotNewRandomNumber to false the first time you call getFacts(), then you never set it to true again, so you will never go into the while loop again.
I'm not sure that's all you need to do. There might be other errors too. It seems unnecessary to have a for loop inside the while loop. There must be a better way. And you probably want to set factsCheck[x] to some appropriate value just before the return statement.

Create a random quiz mode where every array part is only called once

I'm a bit new to Android Studio and I want to make small quiz app. On the start screen, there are two buttons. With the first button, you just click through your questions and you can start at a specific question number if you want (this is already working). With the second button, I wand to create a random mode BUT every question should only be asked once. So there should not be the possibility to get the same questions twice.
For that I created an Array:
public ArrayList<Integer> questionsDone = new ArrayList<>();
And got the lenght of the Question Array:
public int maxQuestions = QuestionLibrary.nQuestions.length;
then I have a function for updating the question:
private void updateQuestion(){
//RANDOM MODE
if (startNumber == -1) {
if (questionsDone.size() >= maxQuestions) {
finishQuiz();
} else {
nQuestionNumber = (int) (Math.random() * (maxQuestions));
do {
if (questionsDone.contains(nQuestionNumber)) {
nQuestionNumber = nQuestionNumber - 1;
if (nQuestionNumber == -1) {
nQuestionNumber = maxQuestions-1;
}
} else {
questionsDone.add(nQuestionNumber);
notDone = true;
}
} while (notDone = false);
}
}
nQuestionView.setText(nQuestionLibrary.getQuestion(nQuestionNumber));
nButtonChoice1.setText(nQuestionLibrary.getChoice1(nQuestionNumber));
nButtonChoice2.setText(nQuestionLibrary.getChoice2(nQuestionNumber));
nButtonChoice3.setText(nQuestionLibrary.getChoice3(nQuestionNumber));
So my idea was that when I start random mode, I pass the value "-1". If the size of the array (questions were done) equals the number of the available questions the quiz should stop. If not, I just get a random number and multiply it by the number of questions. Then there is a do-while function which makes sure that if the questionsDone-Array already contains the number it will get a new number and after getting a number which is not in the array it will be stored in the array.
This is what the app does when I click on random mode:
It always shows a random question but sometimes one questions are asked twice and more. And suddenly it stops (the app is loading the result page) but the stop does not come with a pattern. When I have 7 questions, each question is minimum asked once and sometimes it stops after 15, sometimes after 20 questions and so on.
Does someone know why?
Since I wanted to give an update to both of you, I posted an anwser. Thank you guys for the good input. It works now and this is how I got it working:
First I created an array:
public ArrayList<Integer> availableQuestions = new ArrayList<>();
Then i put integers in the array starting by 0 and ending maxQuestions-1 and I shuffled the values:
if (startNumber == -1) {
Integer i = 0;
do {
availableQuestions.add(i);
i++;
}while (i < maxQuestions);
Collections.shuffle(availableQuestions);
}
Then on every button click this function starts to work (j was declared as an integer with the value 0 before):
if (startNumber == -1) {
nQuestionNumber = availableQuestions.get(j);
j++;
}
Instead of keeping QuestionsDone, I suggest to keep QuestionAvailable (i.e. not yet answered), as indices of questions in the library
List<Integer> availableQuestions = null;
...................................................
if (startNumber == -1) {
if (availableQuestions.isEmpty()) {
finishQuiz();
availableQuestions = null;
} else {
if (availableQuestions == null) {
// Starting a new quiz
availableQuestions = new List<Integer>(maxQuestions);
for (int i=0; i<maxQuestons; i++) availableQuestions.Add(i);
}
int nQuestionOrder = (int) (Math.random() * availableQuestions.size());
nQuestionNumber = availableQuestions.get(nQuestionOrder);
availableQuestions.removeAt(nQuestionOrder);
}
}

as compare to the list position with the position of a spinner

It may seem a silly question but I've tried a variety of ways and have no idea how to solve. I am new to android programming and am completing a spinner with a list of objects. When you select the object in need spinner pick up the object ID and the number of animals of the same.
My last attempt was is, but I know he does not enter the IF because the equals can not compare the list with a string, but do not know how to make this comparison.
String posicaoSpinner = String.valueOf(sLote.getSelectedItemPosition());
int idLote =0;
int qtdAnimais;
for (int i = 0; i < loteList.size(); i++) {
for (Lote lotes : loteList) {
if (posicaoSpinner.equals(loteList.get(i))) {
idLote = Integer.valueOf(String.valueOf(lotes.get_id()));
qtdAnimais = lotes.getQtd_animais() - itemPovoamento.getAnimais();
lotes.setQtd_animais(qtdAnimais);
}
}
}
Any help is welcome. Thank you so much
If you need the value of the selected item you can simply use .getSelectedItem() of the spinner. So:
String posicaoSpinner = posicaoSpinner.getSelectedItem().toString();
should do the trick?

Categories

Resources