Game Project for Software Prototyping ID: 20220825 Name: Enrique Jose Delgado Garcia
Go to file
2025-05-11 23:07:19 +09:00
.vscode Created Svelte project 2025-04-24 20:00:16 +09:00
public Created Svelte project 2025-04-24 20:00:16 +09:00
src Comments 2025-05-11 23:04:33 +09:00
.gitignore Created Svelte project 2025-04-24 20:00:16 +09:00
index.html Created Svelte project 2025-04-24 20:00:16 +09:00
jsconfig.json Created Svelte project 2025-04-24 20:00:16 +09:00
package-lock.json Created Svelte project 2025-04-24 20:00:16 +09:00
package.json Created Svelte project 2025-04-24 20:00:16 +09:00
README.md Fixes 2025-05-11 23:07:19 +09:00
svelte.config.js Created Svelte project 2025-04-24 20:00:16 +09:00
vite.config.js Created Svelte project 2025-04-24 20:00:16 +09:00

HiLo - Game Project

Name: Enrique Jose Delgado Garcia
ID: 20220825
Email: enrdel070504@kaist.ac.kr
Repository link: http://git.prototyping.id/20220825/HiLo_GameProject
Video demo: https://youtu.be/LpC3dNiW6G8

Game Description

HiLo is a memory-based luck-based card game, designed by Enrique.

Premise

The game is simple. In the game, you hold the last drawn card from a classic deck of 52 playing cards. When starting the game, you will receive a card from the deck to be your Current Card.

Press "High" if you think the card on the top of the deck is higher than the Current Card, and press "Low" if you think the card on the top of the deck is lower than the Current Card (The card on the top of the deck will be referred to as the top card for the rest of the report).
When either of these buttons are pressed, the card on the top of the deck is revealed. If this top card is higher than (or equal to) the Current Card, then the player will receive points based on the card's value IF they had pressed "High". If the top card is lower than (or equal to) the Current Card, the player will receive points IF they had pressed "Low". Otherwise, the player will LOSE points based on (15 points minus the card's value).

Card values are distributed as follows:

  • Number cards
    • The value of number cards corresponds to the number displayed on the card.
  • Face cards
    • Jacks are worth 11 points, Queens are worth 12 points and Kings are worth 13 points.
  • Aces
    • Aces's value depends on if the player chose "High" or "Low" when the top card is an Ace. If the player chose "High", the Ace is worth 15 points. If the player chose "Low", the Ace is worth 1 point. This means, regardless of what the player chooses, the player will always win points if the top card is an Ace.
    • If the Current Card is an Ace:
      • All number cards are higher than the Ace.
      • All face cards are lower than the Ace.

After the score is distributed and added up, the top card becomes the player's Current Card. The game goes on until all 52 cards are exhausted from the deck.

Those are the basic rules of HiLo.

Powers

The game would be too simple if it was just a guessing game, so the player has a few tools at their disposal to strategize.

  • See The Future
    • This power (usable up to 2 times) lets the player view the top 2 cards on the deck. So, the player is able to know with 100% assurance the next two top cards.
  • Reveal Suit
    • This power (usable up to 10 times) reveals the suit of the top card (Hearts, Diamonds, Spades, Clubs). This can give the player some more information on the top card, and helps if they have good memory on which numbers have passed from which suits.
  • See Remaining
    • This power (usable up to 3 times) lets the player view the three cards that follow the top card of the deck. This gives the player information about future cards while still having them rely on their memory.
  • Double Down
    • This power (usable up to 3 times) doubles the points received from the next "High"/"Low" guess. If the player guesses correctly, they win double the amount of points. However, if the player guesses incorrectly, they lose double the amount of points.

Code Organization

The code is organized between three Svelte files:

  • App.svelte
  • Deck.svelte
  • HiLo.svelte

App.svelte

The main purpose of App.svelte is the visual aspect of the game, what the user sees. App.svelte mainly interacts with HiLo.svelte through "receiving" events, changing the visual elements according to what the user is doing in the game. This is the svelte file that uses p5js, and as such, its main function is the sketch function.
On preload, the game is prepared using the HiLo.svelte file, which loads all the images of the game and prepares all the variables that are used throughout the game. On setup, the canvas is created and a "backImage" variable is declared to setup for the image representing the deck (which can be changed based on the Reveal Suit power, since the backImage changes to correspond to the suit of the top card when that power is used). Finally, in the draw function, depending on the "Screen Mode", a game Screen is drawn.
There are three Screen Modes (which is managed in HiLo.svelte, because it denotes a state in the game): the Main Screen, the Remaining Screen and the Final Screen. The Main Screen is the basic setup. It shows the score, the number of remaining cards in the deck, and two card images: one representing the Current Card and the other representing the deck. The Remaining Screen shows an overview of all the cards that are remaining in the deck (not in the order that they are in the deck, of course). The Remaining Screen is used for the "See Remaining" power. Finally, the Final Screen is used when the number of remaining cards reaches 0. In this case, the final score is displayed.
The other functions in this file are simple visual effects or they interact with the main sketch function (usually, when a power is used).

Deck.svelte

The main purpose of Deck.svelte is to manage the "deck", as the name implies. It only interacts with HiLo.svelte, as the deck should only be used by the file that controls the logic of the game.
This file declares the Card class, which has five attributes (which all have getter functions):

  • Value
    • The value of the card, shown in the number displayed on the card. If the card is an Ace, the value is 1. If the card is a Jack, Queen or King, then the value is 11, 12 and 13, respectively.
  • Suit
    • The suit of the card, which can be either "Hearts", "Diamonds", "Spades" or "Clubs".
  • Type
    • The "type" of the card, which can be either "Ace", "Number" or "Face".
  • Image
    • The p5 preloaded image that corresponds to the card.
  • Id
    • The card's "id", unique to each card. This is mainly used for the "See Remaining" power, to know the exact "position" of the card.

Having a Card class ensures to me that it is impossible for any card element to be structured differently.
The main function of the file is the createDeck function which, as the name implies, initializes all 52 cards and places them in a global array called deck. In a way, this is a factory of the Card class. The function is simple. It simply goes over every possible value that a card can be (from Ace, 2 - 10, Jack, Queen, King), changes the "suit" and repeats the process for every suit. There are some more things involved (such as getting the image of the card), but the main gist is there.

Another important function is the shuffleDeck function which shuffles the deck. This uses the "Fisher-Yates Shuffle". The code is basically extracted from a StackOverflow page (https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array) (see more details in Acknowledgements)

The rest of the functions in Deck.svelte are glorified getters, the most important being the drawCard function, that pops a card from the global deck array.

HiLo.svelte

Finally, HiLo.svelte is the logical component of the game. All background processes not linked to much visual is handled in HiLo.svelte (with a few exceptions being the buttons, which are in the HiLo.svelte instead of App.svelte despite being a visual element). Since the file is all about the logic, HiLo.svelte mainly interacts with Deck.svelte, since that file controls the features of the deck. HiLo.svelte indirectly interacts with App.svelte by sending events to it.
The following are the main functions:

  • initiateGame(p5)
    • initiateGame is a function that initializes all the values and global variables in HiLo.svelte. It takes a parameter, which is the p5js library element, which is needed to load all the necessary card images.
  • nextRound(highChosen)
    • nextRound is a function that is called after the player has pressed the "High" or "Low" buttons. If they pressed "High", highChosen is true and if they pressed "Low", highChosen is false. This function checks if the player's guess is correct or not, adds up the score based on correctness, and replaced the currentCard with the top card of the deck.

The code also manages the functions that are called when a power is used. All powers have a limited number of uses each, so each function checks if the power can be used. All of these also "dispatch" an event for App.svelte to pick up.

  • doubleDown
    • This function changes a multiplier to 2, which is used in scoring in the nextRound function.
  • revealSuit
    • This function passes the corresponding suit's "backImage" to App.svelte through an event to be displayed to the player.
  • seeRemaining
    • This function changes the Screen Mode. If the current Screen Mode is the Main Screen, the function changes the mode to the Remaining Screen; and if the Remaining Screen is the current Screen Mode, then the Screen Mode to the Main Screen.
  • seeTheFuture
    • This function passes the three cards below the top cards to App.svelte through an event, for it to display it the player.

Issues

My main issue had to do with the button placements. I tried my best to think of a way for the "High"/"Low" buttons to be at the top of the p5 canvas, while the Power buttons were to the left, but implementing that was a lot harder than I expected. I tried making a separate "PowerButtons.svelte" file, but I would need the power buttons to interact with both App.svelte and HiLo.svelte, but I could not figure out a way to use functions from PowerButtons.svelte in HiLo.svelte without including the buttons in HiLo.svelte (which would result in them being together with the HiLo buttons). I would need to have the PowerButtons and the High/Low buttons to be in separate files.
I certainly believe it is possible, but, frankly speaking, I don't have much time to make it possible. As such, I will leave the buttons to be like that.

One minor bug is when you press any other button except "Go Back" in the Remaining Screen Mode. It will correctly go to the Main Screen, but the Remaining Screen will still be there until High/Low is pressed.

Another issue was not being able to figure out a way to make the game "more advanced". I find it nice to have such a simple game as a project, but I am sure that other people's projects will be even more amazing. I struggled A LOT, even for something as simple as this, so I'm actually quite glad I went with a simple game.

Acknowledgements

I used many different resources for this project.

For help with p5, I used the documentation: https://p5js.org/reference/

For help with css, I used a small cheat. Recently, through a different course, I learned to use Figma, which is used for making digital prototypes and such; and I learned that I could make an element in Figma and copy it as CSS code. So, to make the buttons, I used Figma: https://www.figma.com
Though, before I learned that, I used the following resource to know how to put the HTML buttons to the left of the p5 canvas: https://stackoverflow.com/questions/4550013/html-element-display-in-horizontal-line

It was very difficult to use Svelte for a game project. It felt very limiting compared to my experience with Unity. The following page helped me understand how to use other Svelte file's functions from outside that Svelte file: https://joyofcode.xyz/using-functions-from-another-svelte-component
Amd the following page helped me understand how to create a custom event (though I have a feeling we learned a different way in class, though I might also be wrong): https://stackoverflow.com/questions/66886318/how-do-i-create-a-custom-event-in-svelte

As said before, I didn't know how to shuffle an array, so I basically almost copy-pasted the Fisher-Yates shuffling algorithm from the following page: https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array (I don't think this shoud be a case for plagirism, as it seems to be a well-known algorithm, and I couldn't find another way that worked quite as nicely).
I had tried using the following resource, using Array.sort and Math.random, but it became obvious to me that it wasn't actually random, and every permutation wasn't equally likely: https://www.geeksforgeeks.org/how-to-shuffle-an-array-using-javascript/

Finally, for the See The Future power, I used the Array.slice() function, which I had to look up really quick: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice