I want to create simple 2048 game application. My initial board is composed of 16 array elements. The generate() function generates a value of '2' in a random empty element
It works just fine and creates one random '2' for me, but the problem starts when I want to call it twice in a handler like this:
const handleNewGame = () => {
generate()
generate()
}
I've read about prevState but have no idea how to implement it in this batch of code to work properly.
Here is my game component:
const width = 4;
const Game = () => {
const [Board, setBoard] = useState([]);
const createBoard = () => {
let initialBoard = [];
for (let i = 0; i < width * width; i++) {
initialBoard.push("");
}
return initialBoard;
};
const generate = () => {
let board = [...Board];
let randomNumber = Math.floor(Math.random() * Board.length);
console.log(randomNumber);
if (board[randomNumber] === "") {
board[randomNumber] = 2;
setBoard(board);
} else generate()
};
const handleNewGame = () => {
generate()
generate()
}
useEffect(() => {
setBoard(createBoard);
console.log(`Board Created!`);
}, []);
return (
<div className="game-container">
<button onClick={handleNewGame}>NewGame</button>
<div className="game">
{Board.map((value, index) => (
<div className="tile" key={index}>
{value}
</div>
))}
</div>
</div>
);
};
export default Game;
I'll be glad for the answer.
setState(), named setBoard() in your code is asynchronous, whatch this great video on the Event Loop for you to understand more: https://www.youtube.com/watch?v=8aGhZQkoFbQ.
See if this will suit your needs:
import { useEffect, useState } from 'react';
const width = 4;
const Game = () => {
const [Board, setBoard] = useState([]);
const createBoard = () => {
let initialBoard = [];
for (let i = 0; i < width * width; i++) {
initialBoard.push('');
}
return initialBoard;
};
const randomBoardPosition = () => {
return Math.floor(Math.random() * Board.length);
};
const generate = () => {
let board = createBoard();
let randomNumber = randomBoardPosition();
let positionsFilled = 0;
while (positionsFilled < 2) {
if (board[randomNumber] === '') {
board[randomNumber] = 2;
positionsFilled++;
} else {
randomNumber = randomBoardPosition();
}
}
setBoard(board);
};
const handleNewGame = () => {
generate();
};
useEffect(() => {
setBoard(createBoard);
console.log(`Board Created!`);
}, []);
return (
<div className="game-container">
<button onClick={handleNewGame}>NewGame</button>
<div className="game">
{Board.map((value, index) => (
<div className="tile" key={index}>
{value}
</div>
))}
</div>
</div>
);
};
export default Game;