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)
}