Skip to content

Latest commit

 

History

History
141 lines (93 loc) · 5.09 KB

deprecated_bomb_defusal.livemd

File metadata and controls

141 lines (93 loc) · 5.09 KB

Bomb Defusal

Mix.install([
  {:jason, "~> 1.4"},
  {:kino, "~> 0.9", override: true},
  {:youtube, github: "brooklinjazz/youtube"},
  {:hidden_cell, github: "brooklinjazz/hidden_cell"}
])

Navigation

Return Home Report An Issue

Setup

Ensure you type the ea keyboard shortcut to evaluate all Elixir cells before starting. Alternatively you can evaluate the Elixir cells as you read.

Bomb Defusal

We're going to create a bomb defusal game.

There will be multiple bombs that need to be defused. If any of the bombs go off the entire game will be reset.

A BombSupervisor will supervise three Bombs. If any of the bombs detonate, every bomb detonates.

flowchart
  S[BombSupervisor]
  C1[Bomb]
  C2[Bomb]
  C3[Bomb]

  S --> C1
  S --> C2
  S --> C3
Loading

That means when a Bomb process dies, the BombSupervisor will restart every Bomb process.

Create A New Mix Project

Using the command line, create a new supervised project in the projects folder called bomb_defusal.

mix new bomb_defusal --sup

Dialyzer, Credo, and ExDoc are optional for this project.

Create The Bomb GenServer

Create a Bomb GenServer. It should start as a minimal GenServer with no functionality.

Configure The BombSupervisor

Configure the BombSupervisor to start in application.ex. It should start with 3 Bomb GenServers as children.

:explode

Send a Bomb an :explode message. It should handle the message by terminating. The BombSupervisor should automatically restart all of the Bomb processes.

(Bonus) :cut

We will defuse bombs by sending them a :cut message with a :red, :white, or :black wire.

When a Bomb is initialized, it should store a randomized wire of either :red, :white, or :black in it's state as the correct wire to defuse the bomb.

If the wire from the :cut message is correct, defuse the bomb.

A defused bomb will no longer terminal when sent the :explode message.

(Bonus) Timer

Add a Timer GenServer under the BombSupervisor tree.

The Timer should store a 5 minute timer which decrements every second.

Every time a :cut message is sent to a bomb with an incorrect value, the Timer should decrement by 30 seconds.

When the Timer reaches 0 it should terminate the BombSupervisor which should automatically restart under the application supervisor.

Mark As Completed

file_name = Path.basename(Regex.replace(~r/#.+/, __ENV__.file, ""), ".livemd")

progress_path = __DIR__ <> "/../progress.json"
existing_progress = File.read!(progress_path) |> Jason.decode!()

default = Map.get(existing_progress, file_name, false)

form =
  Kino.Control.form(
    [
      completed: input = Kino.Input.checkbox("Mark As Completed", default: default)
    ],
    report_changes: true
  )

Task.async(fn ->
  for %{data: %{completed: completed}} <- Kino.Control.stream(form) do
    File.write!(progress_path, Jason.encode!(Map.put(existing_progress, file_name, completed)))
  end
end)

form

Commit Your Progress

Run the following in your command line from the curriculum folder to track and save your progress in a Git commit. Ensure that you do not already have undesired or unrelated changes by running git status or by checking the source control tab in Visual Studio Code.

$ git checkout solutions
$ git checkout -b bomb-defusal-exercise
$ git add .
$ git commit -m "finish bomb defusal exercise"
$ git push origin bomb-defusal-exercise

Create a pull request from your bomb-defusal-exercise branch to your solutions branch. Please do not create a pull request to the DockYard Academy repository as this will spam our PR tracker.

DockYard Academy Students Only:

Notify your instructor by including @BrooklinJazz in your PR description to get feedback. You (or your instructor) may merge your PR into your solutions branch after review.

If you are interested in joining the next academy cohort, sign up here to receive more news when it is available.