1

My idea was to make a question and answer card game where when you click on a button you get a random question in a modal, all this works. My question is: How can I do so that the question that already came out does not appear again? for example if I get the question3, that it does not appear again in the whole game.

const Arrayorange = [
    {
        question: "question 1",
        reply: "Reply 1",

    },
    {
        question: "question 2",
        reply: "Reply 2",
    },
    {
        question: "question 3",
        reply: "Reply 3",
    }
  ];

export function Orange() {
    const [stateModal, changeStateModal] = useState(false)
    const [index, setIndex] = useState(0);

  function openandchange(){
    changeOrange();
    openModal();
  }

  function changeOrange() {
    let newIndex = Math.floor(Math.random() * (Arrayorange.length - 0) + 0);
    setIndex(newIndex);
  }
  function openModal(){
    changeStateModal(!stateModal)
  }

  const audio = new Audio(cardsound)


  function openwithsound(){
    openandchange();
    audio.play()
  }

    return (
        <div>
        <button className="btn" onClick={openwithsound}><IoIosBody/></button>

        <ModalOrange
        state={stateModal}
        changeState={changeStateModal}
        titulo="Question"
        
      >
        <Content>
          <h1>{Arrayorange.[index].question}</h1>
          <p>{Arrayorange.[index].reply}</p>
        </Content>
      </ModalOrange>
        </div>
    )
}

Thank you very much for your answers in advance

  • 1
    might you can use this https://stackoverflow.com/questions/2380019/generate-unique-random-numbers-between-1-and-100 – rnewed_user Nov 03 '22 at 16:06

1 Answers1

1

Great question!

What I would do, is every time a question gets used, it will get removed from the array, so even if changeOrange() picks the same number again, it can't return the same question.

The method you'll likely want to use is splice

Arrayrange = arrayOrange.splice(newIndex, 1)

More details here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice

And then instead of driving the data on screen with a chosen index of orangeArray, you can just use the sliced question.

Something like this:

function changeOrange() {
let newIndex = Math.floor(Math.random() * (Arrayorange.length - 0) + 0);
setQuestion(Arrayorange.slice(newIndex, 1)) //this gets the question and puts it in state
Arrayorange = Arrayorange.slice(newIndex, 1) // this ensures the same question can't be chosen ever again
}

edit: Changed splice to slice

C.T. Bell
  • 353
  • 3
  • 12
  • you mean `Arrayorange` here ? – KcH Nov 03 '22 at 16:12
  • Yes, my bad. Fixed – C.T. Bell Nov 03 '22 at 16:38
  • you would not use `splice` method until its a copy of state otherwise it mutates the original array and react doesn't know it is changed and won't re-render ... – KcH Nov 03 '22 at 16:39
  • @KcH, The react rendering isn't driven by the array, it would be driven by a useState that contained a single question. ```const [question, setQuestion] = useState()``` So I'm not sure what issue you're raising here. – C.T. Bell Nov 03 '22 at 17:20
  • my bad thought Arrayorange is in state, anyways `splice` would change the original array too ... – KcH Nov 03 '22 at 17:28
  • 1
    Ah, you're right. I'll update to use slice – C.T. Bell Nov 03 '22 at 17:32
  • So I would have to add a `const [question, setQuestion] = useState()` to my code? – Lucas Caballero Nov 03 '22 at 18:21
  • Yes, for my example to work. Then instead of ```

    {Arrayorange.[index].question}

    {Arrayorange.[index].reply}

    ```, You'd do something like ```

    {question.question}

    {question.reply}

    ``` etc
    – C.T. Bell Nov 03 '22 at 18:38