Issue
I am tring to do a quiz app, there is a random flag and random 4 answers, one of them should be a correct answer and random 3.
For now I have only been able to random answers, but sometimes I have the same answer several times. Fails to random 3 different answers that will not repeat themselves and add to that the correct answer.
package com.example.guesstheflag;
import androidx.appcompat.app.AppCompatActivity;
ListView listView;
ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start_game);
listView = findViewById(R.id.myList);
imageView = findViewById(R.id.imagernd);
MyAdapter myAdapter = new MyAdapter();
listView.setAdapter(myAdapter);
//rnd image
Random rndImg = new Random();
int img = rndImg.nextInt(flags.length);
imageView.setImageResource(flags[img]);
}
// functions for answers list
class MyAdapter extends BaseAdapter{
@Override
public int getCount() {
return 4;
}
@Override
public Object getItem(int i) {
return answers[i];
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
LayoutInflater layoutInflater = getLayoutInflater();
View row = layoutInflater.inflate(R.layout.custom, null);
TextView textView = row.findViewById(R.id.myText);
Random rnd = new Random();
int name = rnd.nextInt(answers.length);
textView.setText(answers[name]);
return row;
}
}
}
Solution
Assumptions
- The correct answer for a
flags
array is equal to the same index in theanswers
array. - The random options (for an answer) also comes from the
answers
array.
Requirement
- For a given question, show 4 options. Out of which one has to be a correct answer and the other 3 has to be random options from the
answers
array. - The random options should not repeat
- The random options should not include the correct answer
Solution
You need to change your MyAdapter
class to be as follows
class MyAdapter extends BaseAdapter {
// Internal variable to hold the options
ArrayList<String> options = new ArrayList<>();
// Function to call which generates the random options
public void generateOptions(int correctAnswerIndex) {
// Clear the internal options variable
this.options = new ArrayList<>();
// Start a random generator
Random rnd = new Random();
// Keep generating options till we have 4 random selected options
while(this.options.size()<4) {
// Get a random number
int name = rnd.nextInt(answers.length);
// Check if random number is equal to correctAnswerIndex, if so, skip this round
if(name==correctAnswerIndex)
continue;
// Get the text for the random option
String optionText = answers[name];
// A flag to indicate if the correct answer should be used for this option position
int chanceToAddCorrectAnswer = 0;
// Generate a random number from 0 to 100
chanceToAddCorrectAnswer = rnd.nextInt(100);
// Check if the random number is an odd number (divisible by 3) and
// the correct answer is not already added to the options
if(chanceToAddCorrectAnswer%3==0 && this.options.indexOf(answers[correctAnswerIndex])==-1) {
// Add the correct answer
this.options.add(answers[correctAnswerIndex]);
}
else {
// Check if we already have 3 random options selected and the correct answer has not be added, then add it
if(this.options.size()==3 && this.options.indexOf(answers[correctAnswerIndex])==-1) {
// Add the correct answer as the last option
this.options.add(answers[correctAnswerIndex]);
}
else {
// Check if the current selected random option is already added or not
if (this.options.indexOf(optionText) == -1) {
// Add this random option
this.options.add(optionText);
}
}
}
}
}
@Override
public int getCount() {
return 4;
}
@Override
public Object getItem(int i) {
return this.options.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
LayoutInflater layoutInflater = getLayoutInflater();
View row = layoutInflater.inflate(R.layout.custom, null);
TextView textView = row.findViewById(R.id.myText);
textView.setText(this.options.get(i));
return row;
}
}
Than change the onCreate
method to do the following
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.myList);
imageView = findViewById(R.id.imagernd);
MyAdapter myAdapter = new MyAdapter();
listView.setAdapter(myAdapter);
//rnd image
Random rndImg = new Random();
int img = rndImg.nextInt(flags.length);
myAdapter.generateOptions(img); // Tell your adapter to generate random options
imageView.setImageResource(flags[img]);
}
Explanation
Basically you need to ensure the following conditions
- The correct answer is ignored while trying to pick random options from the
answers
array. - The options which are already picked are also ignored for consecutive random option.
In the above MyAdapter
we create a function to generate the random options called generateOptions
whenever this function is called it will generate the random number while ensuring the above conditions are met.
I have extensively commented the code but if you need more clarity, feel free to comment.
Suggestions
- Always include the list inside the Adapter class to ensure your dependency is internal and not external, since usually these are to be declared in their own files. (try to stay with one class per file)
- For a game, performance is key and I would suggest to generate all the list of questions and it's associated random options before the game starts. Allowing the user to go from question to question quickly. This is to be done in the
startGame
class with a function likeSetupGame
which is called in theonCreate
or whenever the user taps "Start" or "Restart"
Answered By - Eagnir
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.