0

I was asked to make a quick Stone, paper, scissor game in an interview. Any help regarding the queries mentioned at the end of this post would be really helpful for me.

I came up with this code - Sandbox - https://stackblitz.com/edit/react-j3bqgq?file=src%2Fcomponents%2FCard.js

Briefly - I've used hooks like

 let [currentResult, setCurrentResult] = React.useState('Start!');  // for printing who won at every round

 // User states
 let [userChoice, setUserChoice] = React.useState('');
 let [playerWins, setPlayerWins] = React.useState(0);
 let [userCurrentImg, setUserCurrentImage] = React.useState(stoneUrl);

 // Computer states
 let [pcChoice, setpcChoice] = React.useState('');
 let [pcWins, setPcWins] = React.useState(0);
 let [pcCurrentImg, setPcCurrentImage] = React.useState(stoneUrl);
 // The url states are for having an url of image of hand acc to the current choice of user and computer.

The logic for randomly generating the computer's choice -

let pcChoiceOption;
function randomPc() {
   pcChoiceOption = choices[Math.floor(Math.random() * 3)];
   setpcChoice(pcChoiceOption);
}

This is the function to decide the win -

function decideWin() {
 if (userChoice == 'stone' && pcChoice == 'scissor') {
   setPlayerWins(playerWins + 1);
   setCurrentResult('Player wins');
 } else if (userChoice == 'scissor' && pcChoice == 'paper') {
   setPlayerWins(playerWins + 1);
   setCurrentResult('Player wins');
 } else if (userChoice == 'papere' && pcChoice == 'stone') {
   setPlayerWins(playerWins + 1);
   setCurrentResult('Player wins');
 } else if (userChoice == 'papere' && pcChoice == 'stone') {
   setCurrentResult('Draw');
 } else {
   setPcWins(pcWins + 1);
 }
 // console.log(playerWins, pcWins);
}

These are the onClick Handlers from the jsx -

  function stoneHandler() {
    setUserChoice('stone');
    randomPc();
    setUserCurrentImage(stoneUrl);
    decideWin();
    setPcImage();
  }

  function paperHandler() {
    setUserChoice('paper');
    randomPc();
    setUserCurrentImage(paperUrl);
    decideWin();
    setPcImage();
  }

  function scissorHandler() {
    setUserChoice('scissor');
    randomPc();
    setUserCurrentImage(scissorUrl);
    decideWin();
    setPcImage();
  }

And, this is the jsx I'm returning

return (
<div className="container">
  <h2>Result: {currentResult}</h2>
  <div className="row">
    <div className="col-3" />

    <div className="col-3">
      <p>Wins: {playerWins} </p>
      <div className="card">
        <img src={userCurrentImg} />
        <div>
          <p className="card-text">
            <button className="button" onClick={stoneHandler}>
              Stone
            </button>
            <button className="button" onClick={paperHandler}>
              Paper
            </button>
            <button className="button" onClick={scissorHandler}>
              Scissor
            </button>
          </p>
        </div>
      </div>
    </div>

    <div className="col-3">
      <p> Wins: {pcWins} </p>
      <div className="card">
        <img src={pcCurrentImg} />
        <div class="card-body">
          <h3> Computer got {pcChoice} </h3>
        </div>
      </div>
    </div>
    <div className="col-3" />
  </div>
</div>
);
};

Now, the things are rendered on the app, the images change when any of the buttons is clicked.

Problem/issues ->

  1. Incorrect wins are being shown and it seems like every time mostly there are more wins on the computer side. When the user is also winning, then also win is being registered on the computer side. Maybe there's some bug in changing the states.

  2. The current round result is absurd, sometimes not changing, sometimes giving wrong output.

  3. In the case of a 'draw', it still registers the win to the user or the computer.

  4. I have a feeling that this code can be optimized and made a lot shorter like onclickhandlers can be clubbed somehow and maybe there is no need for having these many states. Can someone please provide some suggestions to optimize it also?

  5. Since I am new to React, so any general suggestions/conventions/changes that I should do to this code will be helpful. The full working sandbox is at - https://stackblitz.com/edit/react-j3bqgq?

Nitish
  • 13
  • 4
  • `useState` is **asynchronous** There are plenty of subject about it https://stackoverflow.com/questions/54069253/usestate-set-method-not-reflecting-change-immediately – dbuchet May 10 '21 at 15:35
  • Thanks for the info, I saw about it on other posts, but still couldn't find any way by which I can use multiple states syncronously which are connected to one other by some logic. – Nitish May 11 '21 at 16:57
  • Don't think your need a state here. Maybe look at useRef – dbuchet May 11 '21 at 17:09

0 Answers0