1.E.4: High Card

Learning Objectives

  1. Solidify knowledge of HTML, CSS and React by using it to build a standalone React app

  2. How to deploy a React app to the internet


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 i to install default packages our app needs to run, and run npm start to start our app and see it in our browser.

For Windows:

If your React Application does not reflect saved changes in the browser please refer back to this section to enable a refresh cycle.

Understand starter code

Notice a file utils.js (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 Basics.

// Get a random index ranging from 0 (inclusive) to max (exclusive).
const getRandomIndex = (max) => Math.floor(Math.random() * max);

// Shuffle an array of cards
const shuffleCards = (cards) => {
  // Loop over the card deck array once
  for (let currentIndex = 0; currentIndex < cards.length; currentIndex += 1) {
    // Select a random index in the deck
    const randomIndex = getRandomIndex(cards.length);
    // Select the card that corresponds to randomIndex
    const randomCard = cards[randomIndex];
    // Select the card that corresponds to currentIndex
    const currentCard = cards[currentIndex];
    // Swap positions of randomCard and currentCard in the deck
    cards[currentIndex] = randomCard;
    cards[randomIndex] = currentCard;
  // Return the shuffled deck
  return cards;

const makeDeck = () => {
  // Initialise an empty deck array
  const newDeck = [];
  // Initialise an array of the 4 suits in our deck. We will loop over this array.
  const suits = ["Hearts", "Diamonds", "Clubs", "Spades"];

  // Loop over the suits array
  for (let suitIndex = 0; suitIndex < suits.length; suitIndex += 1) {
    // Store the current suit in a variable
    const currentSuit = 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 rankCounter
      let cardName = `${rankCounter}`;
      let cardRank = rankCounter;

      // If rank is 1, 11, 12, or 13, set cardName to the ace or face card's name
      if (cardName === "1") {
        cardName = "Ace";
        // Ace has higher rank than all other cards
        cardRank = 14;
      } else if (cardName === "11") {
        cardName = "Jack";
      } else if (cardName === "12") {
        cardName = "Queen";
      } else if (cardName === "13") {
        cardName = "King";

      // Create a new card with the current name, suit, and rank
      const card = {
        name: cardName,
        suit: currentSuit,
        rank: cardRank,

      // Add the new card to the deck

  // Return the completed card deck
  return newDeck;

// Export functionality to create a shuffled 52-card deck
export const makeShuffledDeck = () => shuffleCards(makeDeck());

Understand App.js'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 section if not sure.

import React from "react";
import "./App.css";
import { makeShuffledDeck } from "./utils.js";

class App extends React.Component {
  constructor(props) {
    // Always call super with props in constructor to initialise parent class
    this.state = {
      // Set default value of card deck to new shuffled deck
      cardDeck: makeShuffledDeck(),
      // currCards holds the cards from the current round
      currCards: [],

  dealCards = () => {
    // this.state.cardDeck.pop() modifies this.state.cardDeck array
    const newCurrCards = [this.state.cardDeck.pop(), this.state.cardDeck.pop()];
      currCards: newCurrCards,

  render() {
  // You can write JavaScript here, just don't try and set your state!
  // You can access your current components state here, as indicated below
    const currCardElems = this.state.currCards.map(({ name, suit }) => (
      // Give each list element a unique key
      <div key={`${name}${suit}`}>
        {name} of {suit}

    return (
      <div className="App">
        <header className="App-header">
          <h3>High Card šŸš€</h3>
          <br />
          <button onClick={this.dealCards}>Deal</button>

export default App;


Complete High Card with the following features.

  1. Determine who has won each round (Player 1 or Player 2)

  2. Keep score during each game (how many rounds has each player won)

  3. 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.


Add nice-to-have features.

  1. 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.

  2. 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.

  1. Allow players to keep track of scores across games, not just across rounds within a single game.


Submit a pull request to the main branch of Rocket's High Card repo and share your PR link in your section Slack channel.

If you would like to deploy your app to the internet, follow Create React App GitHub Pages deployment instructions here.

Reference Solution

Here is reference code and a reference deployment for this exercise. You can do better!

Last updated