0

I am a beginner in react and I can't get my rock paper scissors to work.

I am trying to update my react useState variable but it doesn't work. The variable I am trying to update is opponentImage every time I update it, it stays the same. Tried searching the web but got a bit desperate of chatgpt and other sources so thought i would give a try to ask a question. Would be glad if you explain how can I avoid this in the future.

here is the code:

import rockImage from '../assets/rock.png'
import paperImage from '../assets/paper.png'
import scissorsImage from '../assets/scissors.png'
import gsap from 'gsap';
import { forwardRef, useEffect, useState } from 'react'


import Snackbar from '@mui/material/Snackbar';

import MuiAlert from '@mui/material/Alert';


const Alert = forwardRef(function Alert(props, ref) {
    return <MuiAlert elevation={6} ref={ref} variant="filled" {...props} />;
});

function RPScissors() {


    const [opponentImage, setOpponentImage] = useState();



    //
    const [openSuccess, setOpenSuccess] = useState(false);
    const [openFailed, setOpenFailed] = useState(false);
    const [openTie, setOpenTie] = useState(false);
    const handleClose = () => {
        setOpenSuccess(false)
        setOpenFailed(false)
        setOpenTie(false)
    };


    const endGame = (user, opponent) => {
        const wonGame =
            (user === 'rock' && opponent === 'scissors') ? 1 :
                (user === 'rock' && opponent === 'paper') ? 0 :
                    (user === 'paper' && opponent === 'rock') ? 1 :
                        (user === 'paper' && opponent === 'scissors') ? 0 :
                            (user === 'scissors' && opponent === 'paper') ? 1 :
                                (user === 'scissors' && opponent === 'rock') ? 0 : 2
            ;
        wonGame === 1 ? setOpenSuccess(true) : wonGame === 0 ? setOpenFailed(true): setOpenTie(true);
        console.log(`won game: ${wonGame} and opponent image: ${opponentImage}`)
        // setTimeout(() => {
        //     handleReset();
        // },4000)
    }

    const handleReset = () =>{
        console.log(`reset`)
        setOpponentImage();
    }

    const handleSelectItem = (selectedItem) => {

        //selectedItem is rock paper or scissors

        const toX = selectedItem === 'rock' ? 300 : selectedItem === 'paper' ? -150 : -600;

        gsap.to(`#${selectedItem}`, {
            x: toX,
            duration: 2,
            ease: 'bounce.out',
        })
        const arr = selectedItem === 'paper' ? ['rock', 'scissors'] : selectedItem === 'scissors' ? ['rock', 'paper'] : ['paper', 'scissors'];

        gsap.to(`#${arr[0]},#${arr[1]}`, {
            duration: 0.5,
            opacity: 0,
            y: -100,
            stagger: 0.1,
            ease: "back.in"
        });

        const num = Math.ceil(Math.random() * 3);
        const opponentElement = num === 1 ? 'rock' : num === 2 ? 'paper' : 'scissors';
        setOpponentImage(opponentElement === 'rock' ? rockImage : opponentElement === 'paper' ? paperImage : scissorsImage)
        console.log(`rnd num: ${num}, opponent element: ${opponentElement}  opponent image: ${opponentImage}`)

        gsap.fromTo('#opponent', { y: 400, },
            {
                y: 0
                , ease: 'bounce.out'
                , duration: 1
            })

        endGame(selectedItem, opponentElement);





    }
    return (
        <>


            <Snackbar
                anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
                open={openSuccess}
                onClick={() => handleClose()}
                autoHideDuration={1000}
            >
                <Alert severity="success" sx={{ width: '100%' }}>
                    Won!
                </Alert>
            </Snackbar>
            <Snackbar
                anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
                open={openTie}
                onClick={() => handleClose()}
                autoHideDuration={1000}
            >
                <Alert severity="warning" sx={{ width: '100%' }}>
                    Tie!
                </Alert>
            </Snackbar>
            <Snackbar
                anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
                open={openFailed}
                onClose={() => handleClose()}
                autoHideDuration={1000}
            >
                <Alert severity="error" sx={{ width: '100%' }}>
                    Lose!!
                </Alert>
            </Snackbar>

            <div className="container mx-auto">
                <div className="row">
                    <div className="col">
                        <div className="mx-auto" id="rock" onClick={() => handleSelectItem('rock')}>
                            <img src={rockImage} />
                        </div>
                    </div>
                    <div className="col ">
                        <div className="mx-auto" id="paper" onClick={() => handleSelectItem('paper')}>
                            <img src={paperImage} />
                        </div>
                    </div>
                    <div className="col">
                        <div className="mx-auto" id="scissors" onClick={() => handleSelectItem('scissors')}>
                            <img src={scissorsImage} />
                        </div>
                    </div>
                    <div className={`col d-none ${opponentImage ? 'visible' : 'invisible'}`}>
                        <div id='opponent'>
                            <img src={opponentImage} />
                        </div>
                    </div>
                </div>
            </div>
        </>
    )
}
export default RPScissors;
  • What specific debugging observation is leading you to conclude that the state update itself is failing? Have you confirmed that you're attempting to update it to a correct value in the first place? Can you provide a runnable [mcve] which demonstrates a failing state update and indicate specifically what you are observing in that example? – David Jun 05 '23 at 19:29

0 Answers0