My React Native Journey - 7 - Implementing the Wordle Game Logic
Defining the Logic
When a key is pressed, the following actions should be implemented:
1. The first entry should be on the leftmost tile of the first row. Subsequent keys should be on the next column of the same row until you run out of columns. At this time, the user should be able to press only CLEAR and ENTER. Pressing any other key will have no effect.
2. Pressing the CLEAR key should clear the last entered key.
3. Pressing the ENTER key should match the entered word against the selected word, to check for correct letters and positions.
a. If the entire word matches, the game should end with a "You have won" message.
b. If there is a partial match, find out the locations of correct and incorrect matches and color code accordingly.
c. If the number of tries are completed with no match, the game should end with "Better luck next time"
Implementing the Logic
1. We need to be able to update the rows array as the user presses keys. To make the rows updateable, use state hooks, like so..
const [rows,setRows] = useState(
new Array(NUMBER_OF_TRIES).fill(new Array(letters.length).fill(""))
);
Default it to empty rows and columns of a 5 * 6 grid as before.
2. To keep track of current row and column, define current row and current column. Use the 'useState' hook imported from "react" to make them update-able values. Like so.
import {useState} from "react";
const [curRow, setcurRow] = useState(0)
const [curCol, setcurCol] = useState(0)
Set the initial default value to 0 for both.
2. To know which tile we are currently on, in the view, use the conditional style to highlight the borders of the current cell. like so.
<ScrollView style={styles.map}>
{rows.map((row, i) => (
<View
key = {`row-${i}`}
style = {styles.row}>
{row.map((cell, j) => (
<View
key = {`cell-${i}-${j}`}
style = {[styles.cell,
{borderColor: isCellActive(i, j) ? colors.lightgrey : colors.darkgrey}
]}>
<Text style = {styles.cellText}>{cell.toUpperCase()}</Text>
</View>
))}
</View>
))}
</ScrollView>
The `key` value is required for the renderer to identify the individual view to render.
The map function's first return value is the value of the array element. The second return value is the index of the element. Thus, i and j provide us with the row and column locations in the grid, identifying the tile.
The isCellActive(i, j) refers to a function that will return true/false depending on whether the i (the current row) and j(the current column) are the same as the current row and current column respectively.
const isCellActive = (row, col) => {
return row === curRow && col === curCol;
}
3. When a key is pressed, the key should get displayed in the current tile, and the array should get updated with the value in the current slot. Since you cannot directly update an array in react, the first thing to do is to copy the entire grid array into a variable array.
Define the function to copy the array
const copyArray = (arr) => {
return [...arr.map((rows) => [...rows])]
}
Execute the function and get the array in the updatedRows variable.
const onKeyPressed = (key) => {
const updatedRows = copyArray(rows);
}
Anytime a key is pressed, the value should appear on the current tile and the next tile should be come the current tile. The rows array should also get updated in the current row/column element. Confirm that the current column is not exceeding the last column for that row.
const onKeyPressed = (key) => {
const updatedRows = copyArray(rows);
if (curCol < rows[0].length) {
updatedRows[curRow][curCol] = key;
setRows(updatedRows);
setcurCol(curCol + 1) ;
}
}
}
Once the last column for that row is reached, only the CLEAR and ENTER keys will function. Other key presses would not have any effect.
3. Pressing the CLEAR key should clear the last entered key.
Go back one column on the same row, replace the column value with "". Also replace the entire row with the new values in the variable array, update the row, and set the previous column as the current column. Like so..
const onKeyPressed = (key) => {
const updatedRows = copyArray(rows);
if (key === CLEAR) {
const prevCol = curCol - 1;
if (prevCol >= 0) {
updatedRows[curRow][prevCol] = "";
setRows(updatedRows);
setcurCol(prevCol) ;
}
return;
}
if (curCol < rows[0].length) {
updatedRows[curRow][curCol] = key;
setRows(updatedRows);
setcurCol(curCol + 1) ;
}
}
4. Pressing the ENTER key should:
Check if it is the last column of a row, it should move to the first cell of the next row.
const onKeyPressed = (key) => {
const updatedRows = copyArray(rows);
if (key === CLEAR) {
const prevCol = curCol - 1;
if (prevCol >= 0) {
updatedRows[curRow][prevCol] = "";
setRows(updatedRows);
setcurCol(prevCol) ;
}
return;
}
if (key === ENTER) {
if (curCol === rows[0].length) {
setcurRow(curRow + 1);
setcurCol(0);
}
return;
}
if (curCol < rows[0].length) {
updatedRows[curRow][curCol] = key;
setRows(updatedRows);
setcurCol(curCol + 1) ;
}
}
Next, we will look at adding background colors.
Comments
Post a Comment