1

i followed a YouTube tutorial about programming a quiz app using java android studio in the tutorial you put the question in array list then you get randomly question from it this can cause a problem of getting the same question many time. How can i fix that? i thought about instead of using random i use a function to get the next item in the list but it didn't work for me. Yhis is my code

package com.example.quiz20;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.google.android.material.bottomsheet.BottomSheetDialog;

import java.util.ArrayList;
import java.util.Random;

public class MainActivity extends AppCompatActivity {
    private TextView questionTV,questionNumberTV;
    private Button option1Btn,option2Btn,option3Btn,option4Btn;
    private ArrayList<QuizModel> quizModelArrayList;
    Random random;
    int currentScore = 0 , questionAttempted = 0, currentPos;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        questionTV= findViewById(R.id.idTVQuestion);
        questionNumberTV=findViewById(R.id.idTVQuestionAttempted);
        option1Btn=findViewById(R.id.idBtnOption1);
        option2Btn=findViewById(R.id.idBtnOption2);
        option3Btn=findViewById(R.id.idBtnOption3);
        option4Btn=findViewById(R.id.idBtnOption4);
        quizModelArrayList = new ArrayList<>();
        random = new Random();
        getQuizQuestion(quizModelArrayList);
        currentPos = random.nextInt(quizModelArrayList.size());
        setDataToViews(currentPos);
        option1Btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(quizModelArrayList.get(currentPos).getAnswer().trim().toLowerCase().equals(option1Btn.getText().toString().trim().toLowerCase())){
                    currentScore++;
                }
                questionAttempted++;
                currentPos = random.nextInt(quizModelArrayList.size());
                setDataToViews(currentPos);

            }
        });

        option2Btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(quizModelArrayList.get(currentPos).getAnswer().trim().toLowerCase().equals(option2Btn.getText().toString().trim().toLowerCase())){
                    currentScore++;
                }
                questionAttempted++;
                currentPos = random.nextInt(quizModelArrayList.size());
                setDataToViews(currentPos);
            }
        });

        option3Btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(quizModelArrayList.get(currentPos).getAnswer().trim().toLowerCase().equals(option3Btn.getText().toString().trim().toLowerCase())){
                    currentScore++;
                }
                questionAttempted++;
                currentPos = random.nextInt(quizModelArrayList.size());
                setDataToViews(currentPos);
            }
        });

        option4Btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(quizModelArrayList.get(currentPos).getAnswer().trim().toLowerCase().equals(option4Btn.getText().toString().trim().toLowerCase())){
                    currentScore++;
                }
                questionAttempted++;
                currentPos = random.nextInt(quizModelArrayList.size());
                setDataToViews(currentPos);
            }
        });

    }

    private void showBottomSheet(){
        BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(MainActivity.this);
        View bottomSheetView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.score_bottom_sheet,(LinearLayout)findViewById(R.id.idLLScore));
        TextView scoreTV = bottomSheetView.findViewById(R.id.idTVScore);
        Button restartQuizBtn = bottomSheetView.findViewById(R.id.idBtnRestart);
        scoreTV.setText("you score is \n"+currentScore + "/4");
        restartQuizBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                currentPos = random.nextInt(quizModelArrayList.size());
                setDataToViews(currentPos);
                questionAttempted = 0;
                currentScore = 0;
                bottomSheetDialog.dismiss();
            }
        });
        bottomSheetDialog.setCancelable(false);
        bottomSheetDialog.setContentView(bottomSheetView);
        bottomSheetDialog.show();
    }

    private void setDataToViews(int currentPos){
        questionNumberTV.setText("Question Attempted : "+questionAttempted + "/4");
        if(questionAttempted == 4){
            showBottomSheet();
        }else {
            questionTV.setText(quizModelArrayList.get(currentPos).getQuestion());
            option1Btn.setText(quizModelArrayList.get(currentPos).getOption1());
            option2Btn.setText(quizModelArrayList.get(currentPos).getOption2());
            option3Btn.setText(quizModelArrayList.get(currentPos).getOption3());
            option4Btn.setText(quizModelArrayList.get(currentPos).getOption4());
        }


    }
    private void getQuizQuestion(ArrayList<QuizModel> quizModelArrayList) {
        quizModelArrayList.add(new QuizModel("in which year google released?","1998","2000","2004","1995","1998"));
        quizModelArrayList.add(new QuizModel("What does CPU stand for?","Core Processing Unit","Central Processing Unit","Command Processing Unit","Custom Processing Unit","Central Processing Unit"));
        quizModelArrayList.add(new QuizModel("what is the name of the first internet search engine?","Google","Yahoo","AOL","Archie","Archie"));
        quizModelArrayList.add(new QuizModel("Which Programming language is the most widely used?","JavaScript","JAVA","Python","PHP","JavaScript"));

    }
}
ADM
  • 20,406
  • 11
  • 52
  • 83

4 Answers4

5

To avoid getting the same selection multiple times, you may want to remove it from the list after it was chosen. The syntax could look something like this:

    Random rand = new Random();
    ArrayList <Type> list = new ArrayList<>();
    int selection = rand.nextInt(list.size() + 1);

    switch(selection)
    {
        case X:
            do the X stuff;
            list.remove(X);
            break;
    }

The ArrayList knows what index X is at, so calling it by name will remove the entry. Using the size of the ArrayList to create the bounds for Random numbers also helps keep it dynamic

NOTE this is NOT complete code

Information/examples about preserving contents of the ArrayList using list.clone()

https://www.tutorialspoint.com/clone-an-arraylist-in-java -- An ArrayList can be cloned using the java.util.ArrayList.clone() method. This method does not take any parameters but returns a shallow copy of the specified ArrayList instance. This means that the new ArrayList created using the ArrayList.clone() method refers to the same elements as the original ArrayList but it does not duplicate the elements.

Kemper Lee
  • 276
  • 4
  • 10
  • this solution worked perfectly thanks, but there is still a small problem, when i delete every item i used from the list i cant use the quiz again because the list is now empty so i have to close the app and open it again, you know any solution for that please? – ayoub touti Apr 08 '22 at 00:21
  • 1
    I am not sure I understand what you are asking here. Could you phrase it a different way? – Kemper Lee Apr 08 '22 at 01:46
  • 2
    To preserve the contents of an ArrayList, I'd recommend passing a copy of the data instead of the raw ArrayList. The duplication syntax is so: **ArrayList listCopy = listName.clone()**. As stated in this included article, it only creates a copy and does not completely duplicate the list. https://www.tutorialspoint.com/clone-an-arraylist-in-java – Kemper Lee Apr 08 '22 at 16:41
2

there are two ways to get the next item in the list:

  • Using the index:
  list.get(list.indexOf(item)+1);  

list - your list of questions item - current question

  • use LinkedList and its methods
WOSAJ
  • 21
  • 5
  • i tried to use ` list.get(list.indexOf(item)); ` but it didnt work, the app close after i chose one answer in the first question! – ayoub touti Apr 08 '22 at 01:00
  • It's still better to use `Linkedlist`, its main purpose is to work with the order of elements – WOSAJ Apr 09 '22 at 03:25
2

If you want to maintain a list of questions, and then some method of identifying if those have been asked, there are multiple ways to do this.

You could add a boolean value inside QuizModel which holds whether the question has been asked or not in this round, and part of the process to starting a new round of the quiz would be to ensure they are all set to false. The value can be set to true when that question has been asked, and you'd check that value before deciding to use this question or getting another.

Alternatively, you could make the problem less specific to your usecase and more generalised. - for example, all you're really asking is how to get a random number, from a set of numbers, minimising the possibility of duplicates. This is a common software problem that has been solved many many times before.

see Creating random numbers with no duplicates for example. Then you could work this solution into your question selection code.

Chris
  • 4,662
  • 2
  • 19
  • 27
1

You can drop the question from the array list and make the random number 1 smaller each time. You have to make sure the list can be reset and is automatically reset when it gets to 0 if you do this.

Drivers Sea
  • 446
  • 2
  • 10
  • can you explain this more with a an example of code ? this will be more helpful because im still beginner with java, thank you ! – ayoub touti Apr 08 '22 at 00:22