Showing check warning
Overview
In the previous section we improved the player's experience by adding highlighting of candidate cells in order to show a player their valid moves options.
In this section we will be improving the player's experiece further by giving them a hint whenever they are in check by highlighting the cell holding their king in a red color. In chess, when a player is in check, it means that their King is in danger of being captured by their opponent's next move. This player should make a valid move to get out of check by moving their king to a safe cell/square, blocking the attacking piece from capturing their king, or capturing the attacking piece.
Chess.js offers a method we can use to check if the next side to move is in check.
chess.in_check()
returns true
if the side to move is in check otherwise false
.
Approach
In the Game
component we can check if the next player is in check after every move made. We will then dispatch an action to the reducer which updates a property in the GameContext
state called check
. We can then use this property in the Cell
component to see if the current player is in check in order to change some styling in the cell to give the player a hint.
Let's get started on this steps. Inside the Game
component in src/Pages/Game/index.jsx
add the following useEffect
. The rest of the code remains unchanged.
useEffect dependencies
Be sure to add this useEffect
call inside the Game
component body. useEffect
here runs everytime the values in our dependencies array changes. We have three values in our dependencies array provided to useEffect
. These are [fen, dispatch, chess]
. The first value fen
makes sure that this effect runs everytime our fen
changes, which happens to be after every move, because we update the fen
in the makeMove
function by calling setFen(...)
. Our other 2 values in the array are dispatch
and chess
. These will not actually change in the component's lifecyle but it is recommended to include any externally declared variables used in useEffect
as part of the dependencies array.
Inside the useEffect
, we dispatch
an action of type types.SET_TURN
and also provide two values as part of the action. These are player
and check
. Actions (Objects passed to dispatch
) must have a type property, this is required, and we can also pass in any other properties we might need in the reducer to update the state (this is optional). We use chess.turn()
to get the player who is in turn, this can either be b
(black) or w
(white). It is very crucial that we keep track of the turns in order to know whose turn it is when chess.in_check()
is true, and give them a hint.
That's all for the Game
component. View the current code snippet for the Game
component here
Updating the reducer
Next, we need to update the reducer function GameReducer
to update the state for this new action types.SET_TURN
.
In src/context/GameReducer.js
add the following case in the switch statement. The rest of the code remains the same :)
We return a new state by copying/spreading the previous state ...state
and setting the turn
and check
properties to what we received from the action.
Updating the actions
Let's also make sure we define the SET_TURN
action in our actions src/context/actions.js
.
In GameContext.js
at src/context/GameContext.js
where we defined the initial state we used to create the context, let's add two properties, turn
and check
.
turn
will hold either b
or w
depending on who is playing next and check
which will be either true
or false
depending on whether the player in turn is in check. This are the properties we update in our GameReducer
when the action of type SET_TURN
is dispatched.
Cell
Finally let's use add the following to the Cell
component in src/components/cell/index.jsx
to complete this feature
In Cell
component we get the turn
and check
properties from our context through
useContext()
We determine the color of the Piece held by this cell and then use this color in the inCheck
function to determine if we need to highlight this cell. We only need to highlight the cell holding the king of the player in turn turn === color && king && check
. If that condition is true, we apply a className check
in the div that wraps the Piece
. That className applies a linear gradient to the Cell.
Now we can see a helpful warning color on White's king who is in check.
In the next section, we will be handling the Game over case
Get the code for this lesson here