Hello Folks! It's always fun to build any game (even if it's not something unique and new) with the technology that you are starting off with or already know. The agenda is to have some fun and to improve your coding skills or maybe to get comfortable with the Tech.
Okay, so in this post, we will build a not-so-difficult, Tic-Tac-Toe game using Lightning Web Component OSS. I am sure most of you must have played this game in your childhood, and you may know what it is, if not, then check out this wiki - Tic-tac-toe.
Features/Requirements
Before we jump into the design and code let us fix the bare minimum requirements. This is the initial and crucial thing for any project that you need to take and consider the most important and limited number features to be implemented first. Later we can scale it as needed.
- This will be a Two-Player Game.
- Users can enter their names, one gets X, and the other get O.
- There will be a 10-second timer for each player to make a move, if one fails to do the move other wins.
- After a player makes a move turn will be changed so the other player can play.
- We need to visualize the timer so users can see how much time they have.
- We also need a START/RESTART.
High-Level Design
UI Design
We will draw nine clickable boxes which can be changed to X's or O's on click based on the current player. Like this:
Player input form to enter the player names.
Pop-up modal to display the messages to users.
Component Composition
We will follow the single responsibility principle from the SOLID principles of Object-Oriented Programming to create the component composition.
- "Box" component: As shown in the UI design image we need to draw nine boxes that are clickable and stateful, so we can store the states of the boxes, like empty, X, O.
- "PlayerForm" component: This component will show the form to enter player names.
- "Popup" Component: This component will display the messages/alerts on a popup screen.
- "ProgressBar" Component: Displays the timer for each move.
- "Styles" component: Shared CSS styles for all components.
- "Board" component: This is the parent component of all other components.
- This component is responsible to handle the click events from the box components.
- This will show the game status. It will check the winner on each move and announce the winner.
- Changes the turn of the player.
- Starts/Stops the timer for each move.
- Shows the player form and collects the player names.
- Handles the core logic of the game.
Low-Level Design
Logic to check the winner
So let's talk about how do we decide the winner. Every time a player makes a move we need to check if that player is won. The player wins if they have filled the 3 boxes with their X/O char in:
- In any row
- In any column
- In the diagonal
- In the reverse diagonal
- Game ties if all boxes are filled and none of the above conditions is satisfied.
So the logic is simple after the player makes a move we check all those rows, cols, and diagonals if any of them are occupied by the current user. As the last move decides the winner we don't need to check only the current row, current column, and current diagonal (if the current move is made on any of the diagonals).
If we take a look at the time complexity, it is linear and we need to make 4N
comparisons in the worst case (move is made on the center box). So time
complexity is O(n)
. Space complexity is
O(n2)
because we need to create 9 boxes.
But there is a better way we can do this in O(1)
, how? Let's see.
If we maintain the count of boxes in each row, cols and two of the diagonal.
As we only have two players we will increase that count by +1
for
player A and decrease it by -1
for player B.
So if the count is +3
for any particular row/col/diagonal it
means that player A has won. If it's -3
means that player B has
won. You can see this code in the checkWin
function from the
board component i.e
board.js.
Logic to check tie
As we know that game is tied when all boxes are filled, and none of the players won, we will maintain a count of boxes occupied, when it is equal to 9 and no player wins, we flag it as a Tie.
Draw the boxes
Boxes are just simple divs with fixed spacing and dimentions. The values
X/O
determine the background color. It fires an event to the
parent component when it is clicked by the player to make a move. Check the
code here.
Timer
The timer is created with setInterval
method from JS. The timer
is started when the game is started. The player has 10 seconds to make a move,
if not done then the other player wins. The timer resets after every move and
when the game is restarted.
Every tick of the timer the progress bar is updated to visualize the remaining time of the user to make move. The progress bar is shown in the reverse way to reduce the value on each tick.
See the startTimer
and
stopTimer
methods here.
Try it yourself/See full code
Thank you for reading, please do let me know your feedback in the comments. You can check out all code in the below give GitHub repo.
- Go to the git repo: rahulgawale/lwc-tic-tac-toe
-
Clone the repo using the command:
git clone https://github.com/rahulgawale/lwc-tic-tac-toe
-
Move to the root directory of the project using the command:
cd lwc-tic-tac-toe
- Run cmd to install all dependencies :
npm install
- Start the project using cmd:
npm run watch
No comments :
Post a Comment
Hi there, comments on this site are moderated, you might need to wait until your comment is published. Spam and promotions will be deleted. Sorry for the inconvenience but we have moderated the comments for the safety of this website users. If you have any concern, or if you are not able to comment for some reason, email us at rahul@forcetrails.com