Solidify knowledge of HTML, CSS and React by using it to build a standalone React app
How to deploy a React app to the internet
Introduction
High Card is a turn-based game between 2 or more players where each player draws a card and the player with the highest card wins that round. The overall winner is the player that has won the most rounds when the deck runs out of cards. We will implement High Card with React.
Starter Code
Clone starter code
Fork and clone Rocket's High Card repo (Rocket-themed Create React App) and understand the following starter code before creating High Card. Run npm install to install default packages our app needs to run, and run npm run dev to start the app next open your browser and navigate to http://localhost:5173.
Understand starter code
Notice a file utils.jsx (short for "utilities") in the src folder that contains helper functions for creating and shuffling a card deck. This is the same code we use in Coding Fundamentals.
utils.jsx
// Get a random index ranging from 0 (inclusive) to max (exclusive).constgetRandomIndex= (max) =>Math.floor(Math.random() * max);// Shuffle an array of cardsconstshuffleCards= (cards) => {// Loop over the card deck array oncefor (let currentIndex =0; currentIndex <cards.length; currentIndex +=1) {// Select a random index in the deckconstrandomIndex=getRandomIndex(cards.length);// Select the card that corresponds to randomIndexconstrandomCard= cards[randomIndex];// Select the card that corresponds to currentIndexconstcurrentCard= cards[currentIndex];// Swap positions of randomCard and currentCard in the deck cards[currentIndex] = randomCard; cards[randomIndex] = currentCard; }// Return the shuffled deckreturn cards;};constmakeDeck= () => {// Initialise an empty deck arrayconstnewDeck= [];// Initialise an array of the 4 suits in our deck. We will loop over this array.constsuits= ["Hearts","Diamonds","Clubs","Spades"];// Loop over the suits arrayfor (let suitIndex =0; suitIndex <suits.length; suitIndex +=1) {// Store the current suit in a variableconstcurrentSuit= suits[suitIndex];// Loop from 1 to 13 to create all cards for a given suit// Notice rankCounter starts at 1 and not 0, and ends at 13 and not 12.// This is an example of a loop without an array.for (let rankCounter =1; rankCounter <=13; rankCounter +=1) {// By default, card name and card rank are the same as rankCounterlet cardName =`${rankCounter}`;let cardRank = rankCounter;// If rank is 1, 11, 12, or 13, set cardName to the ace or face card's nameif (cardName ==="1") { cardName ="Ace";// Ace has higher rank than all other cards cardRank =14; } elseif (cardName ==="11") { cardName ="Jack"; } elseif (cardName ==="12") { cardName ="Queen"; } elseif (cardName ==="13") { cardName ="King"; }// Create a new card with the current name, suit, and rankconstcard= { name: cardName, suit: currentSuit, rank: cardRank, };// Add the new card to the decknewDeck.push(card); } }// Return the completed card deckreturn newDeck;};// Export functionality to create a shuffled 52-card deckexportconstmakeShuffledDeck= () =>shuffleCards(makeDeck());
Understand App.jsx's logic to deal 2 cards at a time from the card deck. Understand what each line of code does before moving on, and ask your batch mates if you're not sure what the code is doing.
App.jsx
import React from"react";import"./App.css";import { makeShuffledDeck } from"./utils.jsx";import { useState } from"react";functionApp(props) {// Set default value of card deck to new shuffled deckconst [cardDeck] =useState(makeShuffledDeck());// currCards holds the cards from the current roundconst [currCards,setCurrCards] =useState([]);constdealCards= () => {constnewCurrCards= [cardDeck.pop(),cardDeck.pop()];setCurrCards(newCurrCards); };// You can write JavaScript here, just don't try and set your state!// You can access your current components state here, as indicated belowconstcurrCardElems=currCards.map(({ name, suit }) => (// Give each list element a unique key <divkey={`${name}${suit}`}> {name} of {suit} </div> ));return ( <divclassName="App"> <headerclassName="App-header"> <h2>React High Card 🚀</h2> {currCardElems} <br /> <buttononClick={dealCards}>Deal</button> </header> </div> );}exportdefault App;
Base
Complete High Card with the following features.
Determine who has won each round (Player 1 or Player 2)
Keep score during each game (how many rounds has each player won)
Declare a winner at the end of each game when the deck has run out of cards, and give the players the option to restart the game.
Comfortable
Add nice-to-have features.
Style the app to clarify what each UI component is for. Clarify which card belongs to which player. Consider using React Bootstrap or MUI components as default styles.
Create a re-usable PlayingCard component to render cards nicely. This component can use playing card images or create a custom playing card UI.
More Comfortable
If you have time and want to practise more.
Allow players to keep track of scores across games, not just across rounds within a single game.
Submission
Submit a pull request to the main branch of Rocket's High Card repo and share your PR link in your section Slack channel.