This repository has been archived on 2024-06-24. You can view files and clone it, but cannot push or open issues or pull requests.
wopr/README.md

76 lines
3.1 KiB
Markdown
Raw Normal View History

2020-07-10 17:29:11 +12:00
# WOPR
2020-07-12 16:24:59 +12:00
Welcome to War Operation Plan Response, a United States military supercomputer
programmed to predict possible outcomes of nuclear war.
![WOPR](https://media.giphy.com/media/jjYGVvxgQSTsc/giphy.gif)
2020-07-10 17:29:11 +12:00
## Installation
2020-07-12 16:24:59 +12:00
1. Install Elixir of a version greater than 1.10.
2. Run `mix local.hex`
3. Clone [this repo](https://gitlab.com/jimsy/wopr): `git clone https://gitlab.com/jimsy/wopr`
4. Install the dependencies: `mix deps.get`
5. Compile the application: `mix compile`.
WOPR can be installed by [cloning this repo](https://gitlab.com/jimsy/wopr).
You need to have a recent version of Elixir installed.
## Usage
Run the `wopr` shell script in the repository directory. A heck of a lot easier
than war-dialing your way through all of Seattle.
You need to have at two instances of WOPR running either on the same machine or
local network to be able to play the game.
When you start WOPR you'll be greeted, asked for your name and then when another
player is found, the game will start. Luckily, we're not playing global
thermonuclear war.
## Technical information
The game uses [libcluster's gossip strategy][1] to locate other WOPR nodes on
the local network and [Syn][2] to distribute state across the cluster. Syn may
not be the best choice for this job, but it was very simple, requiring no setup
whatsoever.
The game is played by orchestrating three kinds of processes; `Game`, `Player` and `Shell`.
### The `Game` process
The game process holds the keys to the game board and is the only one allowed to
update the state of the board whenever a player takes a turn.
### The `Player` process
Simply used to allow players to register themselves in the cluster's registry and keep track of the player's name and score.
### The `Shell` process
I started off just writing the shell in a procedural style, but quickly realised
that it needed to behave more like a REPL - sometimes returning immediately,
sometimes waiting for something else to happen. It uses a process to keep track of the game and player state, and loops printing the appropriate message or requesting input.
## Known issues
1. I don't like that there's a process for the game. It was the fastest way to
make it work, but I think I would prefer that there was just a message
protocol for sending game states between players.
2. I don't like Syn's eventually-consistent nature for this use case - I would
prefer to use `gproc`, but couldn't immediately figure out how to enable
`gproc_dist` so gave up given the time constraints.
3. The various GenServer's know too much about their state. This should be
moved to the individual state modules - then the fact that the servers aren't
tested would be much less surprising.
4. There's a bug when you have an uneven number of players where they sometimes
try to start games with each other in a ring formation and fail. I ran out
of time to fix this, and it's a side effect of 1.
2020-07-10 17:29:11 +12:00
2020-07-12 16:24:59 +12:00
1: https://hexdocs.pm/libcluster/Cluster.Strategy.Gossip.html
2: https://hex.pm/packages/syn
2020-07-10 17:29:11 +12:00
2020-07-12 16:24:59 +12:00
## Documentation
2020-07-10 17:29:11 +12:00
The generated documentation for the main branch is available [here](https://jimsy.gitlab.io/wopr/)