Markus Löning

Software Engineering & Machine Learning

Implementing the Uno card game in Rust

Posted at Mar 9, 2024 00:06:13 — Last modified at May 8, 2024 09:13:09

After having implemented the Uno card game in Python, I decided to rewrite it in Rust.

Rewriting Uno in Rust has taught me a lot, as Rust forces you define objects and their interactions more clearly, and encourages you to keep them as simple as possible.

For Uno rules, see Wikipedia.

Main objects

I represent key game concepts in the following objects:

Handling state

State involves the following objects:

Some observations on state:

Thoughts on extensibility

Adding a new player strategy should be straightforward given the Strategy trait. For example, adding a strategy using human-input or machine learning could be added. The strategy interface currently only takes the set of legal cards as input, but could be extended to also take a history of previous plays. It returns a Play, that is, either the card selected to play or None.

Adding new cards will be more involved, especially for action cards. Currently, action cards are simply defined by a special symbol (e.g. “reverse”, “skip” or “draw-2”). They do not define how to execute their actions. Instead, a match expression in the main loop of the game determines which action to execute and defines the corresponding actions for each action symbol. To enhance extensibility, we would have to define an interface for handling actions (e.g. forcing the next player to draw new cards or mutating the player cycle) as well as card state (e.g. resetting state when recycling the pile into the deck) and actions.

Resources

While implementing Uno, I found these resources on Rust particularly useful: