Skip to content

jessedhillon/hues

Repository files navigation

Hues

This is a 2025 holiday break exploration in vibe-coding.

Description

This is a party game whose rules are as follows:

  1. Each game has one leader, and everyone else is a guesser. The leader selects how many rounds of guessing the game will involve (1-3).
  2. At the start of the game, the leader is assigned and shown a color swatch chosen from the 4096-color RGB space defined by 4-bits per channel (16^3 = 4096), i.e. the range #000 to #fff
  3. Each guesser is shown a palette of swatches, covering the full color space.
  4. The leader provides hints (verbally, out of band).
  5. Each guesser, after hearing the hints, selects the swatch which they feel is best indicated by the given hints.
  6. Once all the guesses are in, the round of guessing is completed.
  7. If the round is not the final round, guessing resumes. The leader reviews the guesses and gives more refined hints to move guessers closer to the target.
  8. If the round is the final round, the game is completed. The guesser whose match is nearest to the target color is the winner.

Application Structure

Types

  • color an int in the range [0, 4096)
  • game a compound object whose fields are:
    • game_id: uuid the game's ID, used to construct backend endpoints
    • open: bool the game is open to invitees
    • current_round: int | null the current round, if the game has begun already
    • total_rounds: int the number of rounds total
    • finished: bool the game is either finished, or still pending guesses
    • players: list[str] a list of player names, representing those who have joined
    • guessed_players: list[str] players who have submitted guesses in the current round
    • winner: str | null the player who won, if the game has completed
    • winning_guess: color | null the winner's guess, if the game has completed
    • winning_distance: float | null the Euclidean distance from the winning guess and the target, if the game has completed
    • target: color | null the target color to guess

Backend

The project is implemented as a FastAPI web application. The structure of the application is given here:

  • GET /game/new begins a new game. It is expected that the first leader player is the one who requests the new game.
  • GET /game/{game_id}/join once the game is begun, this URL should be provided to the leader to share with each guesser, who should use this URL to join the game.
  • POST /game/{game_id}/join accepts the player's registration and joins the player to the game.
    • name: str the player's name
  • POST /game/{game_id}/start the leader POSTs to this endpoint when they are ready to start the game
    • target color the color in #000 - #fff to guess
  • POST /game/{game_id}/guess when a player is ready to submit a guess, this endpoint accepts it
    • color: str a 3-digit hex-code in the space #000 - #fff
  • GET /game/{game_id}/status used for various UI functions to determine the state of the game
    • game: a JSON object of type game (see Types section above)

Frontend

The frontend is a React application with a two modes, leader and guesser, each comprising a number of screens. The screens are all designed with a phone user in mind.

Leader

The leader mode has the following screens, whose components are listed below each screen:

  • inviting
    • a link to share (out of band) with invitees
    • the list of users who have joined
    • a button to close invitation and begin, which triggers the transition to guessing, and causes open = false
  • guessing
    • the target swatch
    • the list of users who have submitted guesses
    • once all guessers have submitted entries,
      • if there is another round, show each player's guess to the leader, present a button to start the next round, which restarts the guessing state
      • if this was the final round, transition to result
  • result
    • the person whose guess is the nearest (using Euclidean distance) to the target wins, and their name is shown
    • the winning guess and the target swatches are shown side by side and labeled appropriately

Guesser

The guesser mode has the following screens and components:

  • waiting
    • the list of users who have joined
    • once the game's status becomes open = false then transitions to guessing
  • guessing
    • a scrollable grid of sorted swatches representing each color in the color space, each swatch being selectable, and the entire grid having the property that only one swatch can be selected at a time
    • a button anchored to the bottom of the screen (so superimposed above the grid of swatches) whose color changes to the color selected, bearing the label "Submit Guess"
    • when that button is pressed, POSTs to /game/{game_id}/guess and transitions to waiting
  • waiting
    • if this was not the final round, waits for the next round to start (current_round incremented by 1), then returns to guessing
    • if this was the final round, waits for finished = true i.e. for all guesses to be submitted
  • result
    • this screen is the same for the leader, see the leader's result screen
    • if the user has the winning guess, they will see a button to start a new game, which when pressed, transitions them to the leader's inviting screen

Ops

  • This game is expected to be hosted in uvicorn
  • This game uses redis as a data store
  • Any services on which this project depends should be defined in process-compose.yaml and run with process-compose up
  • The developer environment is provided through a devshell defined in a Nix flake

About

Vibe-coding some board games

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published