Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/diegoojeda/wordle-compose


https://github.com/diegoojeda/wordle-compose

Last synced: 9 days ago
JSON representation

Awesome Lists containing this project

README

        

# Wordle implementation with Jetpack Compose

This repository contains a custom implementation of the world famous game Wordle, made with Jetpack
Compose for the UI layer and providing a Ktor embedded server that will provide a different word
every time the user wants to play the game.

## Jetpack Compose

On the UI layer, I've decided to use Jetpack Compose along with the new Material Design 3 library.
Most of the code related to this can be found in the `MainActivity` class.

Regarding how I've handled recomposition, I've gone with the

```
interface State {
  val value: T
}
```

approach, but any other approach such as LiveData and Flow can be used in similar ways.

To trigger recomposition, you'll find that I had to recreate the states inside each of the domain
entities by `copy`ing each of the lists that were modified, as if you just modify the items inside
of them the recomposition doesn't trigger.

Other than that, it's interesting to take a look at the `LetterBox` component, as it holds both the
animation and the logic to decide which color should the box be painted.

## Domain Layer

At first sight, the game's logic seems quite simple but once we get into it we find out it has some
cases we need to handle.

The representation of the board is made through three different entities:

- `BoardState`
- `BoardRow`
- `BoardLetter`

Each one of those have the proper methods to modify its contents in the way the rules of the game
allow, and have convenience methods to perform the needed assertions, such as what's the state of a
letter, if the row has been completed or if the word has been guessed.

## Ktor server

Last but not least, in order to provide the words that the user will have to guess, I added a server
implemented with Ktor that runs along with the application on your device when it's launched.

This server has only one endpoint `/next_word` that returns a random word from a list of 700+ most
used words.

This list is duplicated on both the server and the client, as the client needs to check if a word is
correct before checking if its letters match.

This duplication could be removed by adding an endpoint to check if the word is valid, but I didn't
find it necessary at this stage of the development, as it's not a trivial decision because it would
make us impossible to go for an offline mode.

## CI - Bitrise

A Bitrise CI has been created for this project. Even if the `bitrise.yml` file provided is the one
that is created out of the box, it's interesting to always have a pipeline running with every push
so that you get notified as soon as possible in case you break some tests.

The app also gets published to the bitrise distribution servers so that you can share it easily.

## Improvements

- Implement navigation with any given number of different libraries to benchmark which one fits your
needs better.
- Remove the duplication of the words list on the server and client applications.
- The animation of the cells when the user clicks `Send` on the keyboard can be improved. Right now
the cells are painted at the same time as the animation is started, and they should be when the
rotated box starts to show. This can be done by duplicating the box component and making them
trigger different recompositions.
- An offline mode would be great, there's already a `LocalWordsRepository` in place that would make
its implementation trivial.

### Side notes

There are two dictionaries on the app.

The one on the client is a list of every single 5 letter word that exists in spanish.

This one has been created out of a full spanish dictionary (`es.txt` file), by removing the words
that don't have exactly 5 letters with

```grep -o -w '\w\{5,5\}' es.txt```

After that, we take the output of the above command and convert it to a valid JSON format with `jq`
such as

```jq --raw-input . | jq --slurp . ```

This way we have a Json Array with every single 5 letter word in spanish.

The second one that is on the server is a list of the most used words in spanish with 5 letters.

We need two dictionaries because we want the users to be able to type any valid word they want in
the application, but we want the words to be guessed to not be rare ones, such as many of the ones
we can find on `dictionary-es.json`.