Shall we play a game?
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.
Find a file
2021-12-08 18:01:20 +13:00
config Implement the tic-tac-toe game 2020-07-12 16:24:59 +12:00
lib Implement the tic-tac-toe game 2020-07-12 16:24:59 +12:00
test Implement the tic-tac-toe game 2020-07-12 16:24:59 +12:00
.formatter.exs Initial commit from mix new. 2020-07-10 17:29:11 +12:00
.gitignore Initial commit from mix new. 2020-07-10 17:29:11 +12:00
.gitlab-ci.yml chore: change default branch to main. 2021-12-08 18:00:52 +13:00
LICENSE Implement the tic-tac-toe game 2020-07-12 16:24:59 +12:00
mix.exs Implement the tic-tac-toe game 2020-07-12 16:24:59 +12:00
mix.lock Implement the tic-tac-toe game 2020-07-12 16:24:59 +12:00
README.md chore: change default branch to main. 2021-12-08 18:00:52 +13:00
renovate.json chore: update renovate.json 2021-12-08 18:01:20 +13:00
wopr Implement the tic-tac-toe game 2020-07-12 16:24:59 +12:00

WOPR

Welcome to War Operation Plan Response, a United States military supercomputer programmed to predict possible outcomes of nuclear war.

WOPR

Installation

  1. Install Elixir of a version greater than 1.10.
  2. Run mix local.hex
  3. Clone this repo: 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. 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.

1: https://hexdocs.pm/libcluster/Cluster.Strategy.Gossip.html 2: https://hex.pm/packages/syn

Documentation

The generated documentation for the main branch is available here