Card Guessing game with React part 8
Game loop
The basic functionality of our game is almost complete. We just need a game loop.
We can already guess the correct number on the third select. But it doesn't show the number to the user nor reset the cards to the beginning position. We should also ask the user if they wants to play again.
First of all, let's refactor colToRows
function. We shouldn't add the loop logic inside the colToRows
function as it's not relevant. Besides, we should separate the guessing logic, possibleNums
, from the it as well.
Write a new function call execute
and call colToRows
inside it. Don't forget the colNum
parameter.
execute = (colNumber) => {
this.colToRows(colNumber);
};
Inside our div
buttons, we need to change the onClick
callback function to execute
as well.
<div className="button" onClick={() => this.execute(1)}>
Select
</div>
<div className="button" onClick={() => this.execute(2)}>
Select
</div>
<div className="button" onClick={() => this.execute(3)}>
Select
</div>
Next, let's create a function called updatePossibleNums
and move the guessing logic to there. We will pass the numbers for selected column as selectedNums
. Now we can get rid of curPosNums
and use selectedNums
directly. Don't forget to remove setState
for `numbers_.
updatePossibleNums = (selectedNums) => {
let prvPosNums = this.state.possibleNums;
// let curPosNums = newNumbers.slice(CARDS_PER_COL * 1, CARDS_PER_COL * 2);
let newPosNums = [];
if (prvPosNums.length === 0) {
newPosNums = selectedNums;
} else {
prvPosNums.forEach((n) => {
if (selectedNums.includes(n)) newPosNums.push(n);
});
}
this.setState(
{
// numbers: newNumbers,
possibleNums: newPosNums,
},
() => {
console.log(this.state.possibleNums);
}
);
};
We need to remove the setState
for possibleNums
from colToRows
function. We can remove the callback as well.
this.setState(
{
numbers: newNumbers,
// possibleNums: newPosNums
}
// () => {
// console.log(this.state.possibleNums);
// }
);
Since we need the selected numbers for updatePossibleNums
, we should return the newNumbers
from colToRows
function.
this.setState({
numbers: newNumbers,
});
return newNumbers;
In the execute
function we need to temporarily hold the newNumbers
variable returned from colToRows
. And also extract the middle column of the numbers and pass them to updatePossibleNums()
.
execute = (colNumber) => {
let tmp_nums = this.colToRows(colNumber);
this.updatePossibleNums(tmp_nums.slice(CARDS_PER_COL * 1, CARDS_PER_COL * 2));
};
The refactoring is complete. Do test again to make sure the card guessing logic is still intact.
Now we can add the stage
. We will start the stage
at 0 and increment every time execute
is called.
constructor(props) {
super(props);
this.state = {
numbers: this.getRandNumArray(),
possibleNums: [],
stage: 0 };
}
execute = (colNumber) => {
let tmp_nums = this.colToRows(colNumber);
this.updatePossibleNums(tmp_nums.slice(CARDS_PER_COL * 1, CARDS_PER_COL * 2));
this.setState({ stage: this.state.stage + 1 });};
We don't need to do anything for the 1st and 2nd stage. For the third and last stage, we need to show the card the user picked, and ask the user if they want to play again using a Pop Up. Let's make a function called showPopup
and add it as the callback to setting stage
.
execute = (colNumber) => {
let tmp_nums = this.colToRows(colNumber);
this.updatePossibleNums(tmp_nums.slice(CARDS_PER_COL * 1, CARDS_PER_COL * 2));
this.setState({ stage: this.state.stage + 1 }, this.showPopup);};
showPopup = () => {
if (this.state.stage === 3) {
console.log("The number picked is " + this.state.possibleNums[0]);
console.log("Show Popup");
}
};
That's all for this part. We will create a good looking Popup in the next part.
Title Photo by Clifford Photography`on Unsplash.