React-native , The instructions are not executed in the same order as described in the program

Viewed 32

So i made a TicTacToe Game in react with minmax algorithm for AI. App uses 2 differents React components : 1 grid (Grid.js) and 9 Square (Case.js). When a square is pressed, player_move() is executed, it put a cross on the square and call play() from the Grid. play() call model to choose() the next move for AI and call ia_move() to the Square that algo choose. Finally, ia_move() put a circle on the squere chosen by AI. This app work well but there is some UX issue : Cross for player and Circle for AI appear almost in same, Circle even a little before Cross, so after AI has calculated the next move. So there is a delay between the moment when the user press a square and the moment his cross appear.

I need help to execute instructions 1(the cross appear) before AI calculate move for AI (minmax()) so before the instruction 2 (the circle appear).

Case.js

    player_move = () => {
        //Instruction 1
        this.setState({caseState: <CrossState/>, disabled:true})
        this.props.grid.play(this.props.id)
        console.log('Player Move :', this.props.id)
    }

    ia_move = ()=>{
        this.setState({caseState: <CircleState/>, disabled:true})
        console.log('IA Move :', this.props.id)
    }

Grid.js

play = (square) => {
        this.childs.current.forEach(c => {
            c.disable()            
        });
        this.state.game.play(square, this.state.game.player)
        
        if(this.state.game.eval(this.state.game.grid) == -1){
            this.setState({text: 'You Win'})
            return
        }
        if(this.state.game.getPossibleMoves(this.state.game.grid).length == 0){
            this.setState({text: 'Equality'})
            return
        }

        let ia_choice = this.state.game.minmax(0, 6, this.state.game.grid)
        //instruction 2
        this.childs.current[ia_choice-1].ia_move()
        this.state.game.play(ia_choice, this.state.game.ia)

        if(this.state.game.eval(this.state.game.grid) == 1){
            this.setState({text: 'You Lose'})
            return
        }

        this.childs.current.forEach(c => {
            c.enable()            
        });
    }

Update

I Manage to do it with setTimeout with 0 delay, but i still dont understand why it works

    play = (square) => {
        this.childs.current.forEach(c => {
            c.disable()            
        });
        this.state.game.play(square, this.state.game.player)
        
        if(this.state.game.eval(this.state.game.grid) == -1){
            this.setState({text: 'You Win'})
            return
        }
        if(this.state.game.getPossibleMoves(this.state.game.grid).length == 0){
            this.setState({text: 'Equality'})
            return
        }

        setTimeout(()=>{
            let ia_choice = this.state.game.minmax(0, 6, this.state.game.grid)

                    this.childs.current[ia_choice-1].ia_move()
                    this.state.game.play(ia_choice, this.state.game.ia)

                    if(this.state.game.eval(this.state.game.grid) == 1){
                        this.setState({text: 'You Lose'})
                        return
                    }

                    this.childs.current.forEach(c => {
                        c.enable()            
                    });
        }, 0)
        
    }
0 Answers
Related