Color Sorting
http://color-sorting.s3-website-us-east-1.amazonaws.com/After playing a mobile game where colored liquids were transferred into different bottles based on topmost color and existing volume. I decided to spend an afternoon to build out a web based version of the game. This gave me a chance to experiment with Ionic's Stencil.js and ended up being a good development excercise.
Game
Premise
The game board consists of a user defined (defaults to 6) bottles arranged in a grid. Each bottle contains four quarter segments of color that can be transferred from one bottle to another by clicking on a bottle and then clicking on another bottle.
Color will only be moved if:
- The receiving bottle is empty.
- The receiving bottle's top most color is the same as the providing bottle.
- The receiving bottle's remaining volume is greater than or equal to the color volume that will be transferred.
The UI should provide:
- As close to an ADA compliant color scheme as possible (difficult in games with 8+ colors).
- Visual indicator that a bottle is selected.
- Visual indicator that a transfer is invalid.
- Visual indicator that the game is complete.
- An optional mechanism to undo any transfer.
- Controls to adjust the game difficulty.
- Number of colors
- Number of undoes
- Controls to create a new game and reset the current game.
- Help control to visually convey how to play the game.
- A count of the number of moves.
Tech Stack
Lerna, the repository is a monorepo with the intent of providing separation of the underlying UI components of the game with the container and business logic of the game.
Stencil.js, Ionic's framework for creating and publishing web components. There are two packages within the monorepo: components and game. Both of these packages were scaffolded with Stencil.js. With the components package using the component base and the game package using the app base.
Structure
Bottle Component
Property | Attribute | Description |
---|---|---|
colors | colors | The list of colors represented as an array |
finished | finished | Indicate a winning state |
selected | selected | Indicate that the bottle is selected |
warning | warning | Indicate that the bottle cannot be targeted |
<a-bottle colors='["#bd93f9", "#ff5555", "#50fa7b", "#ffb86c"]' />
Game Package
The game package contains a Stencil.js application that imports the components package and uses the a-bottle component to create the board, provide instructions, and a set of UI controls.
All of the game logic is housed within the app-board component and a redux slice to handle some of the actions dispatched from the board. This slice is responsible for initializing the board and maintaining the visual state of the game which is then used to render each a-bottle component.
The initial state of the slice. Here selectedIndex and warningIndex are integers that map to which bottle the user has selected and which bottle has an error state due to an incorrect move. The previousStates array contains the previous states of the board. After a move is completed the previous state of the board is pushed onto this array.
{
"board": [],
"selectedIndex": null,
"warningIndex": null,
"previousStates": [],
"undos": Number.POSITIVE_INFINITY,
}