Mix.install([
{:jason, "~> 1.4"},
{:kino, "~> 0.9", override: true},
{:youtube, github: "brooklinjazz/youtube"},
{:hidden_cell, github: "brooklinjazz/hidden_cell"}
])
Pokemon are creatures which have the ability to evolve into more powerful versions of themselves.
For example, Charmander evolves into Charmeleon, and Charmeleon evolves into Charizard.
flowchart LR
c1[Charmander]
c2[Charmeleon]
c3[Charizard]
c1 --> c2 --> c3
In this exercise, you will create an Evolvable
protocol which returns the evolved
version of a Pokemon.
Evolvable.evolve(%Charmander{})
%Charmeleon{hp: 58, attack: 64: defense: 58}
In the Elixir cell below, Using the stats from Pokemon DB, you're going to create a struct that represents each of the following Pokemon.
Each struct should include the following.
:hp
:attack
:defense
You can use the base values as defaults from Pokemon DB as shown in the following diagram.
classDiagram
class Charmander {
hp: 39
attack: 52
defense: 43
}
class Charmeleon {
hp: 58
attack: 64
defense: 58
}
class Charizard {
hp: 78
attack: 84
defense: 78
}
Example Solution
defmodule Charmander do
defstruct hp: 39, attack: 52, defense: 43
end
defmodule Charmeleon do
defstruct hp: 58, attack: 64, defense: 58
end
defmodule Charizard do
defstruct hp: 78, attack: 84, defense: 78
end
defmodule Charmander do
end
defmodule Charmeleon do
end
defmodule Charizard do
end
In the Elixir cell below, create an Evolvable
protocol with an evolve/1
function.
A Charmander
struct should return a new Charmeleon
struct.
Evolvable.evolve(%Charmander{})
%Charmeleon{hp: 58, attack: 64: defense: 58}
A Charmeleon
struct should return a new Charizard
struct.
Evolvable.evolve(%Charmeleon{})
%Charizard{hp: 78, attack: 84: defense: 78}
Example Solution
defprotocol Evolvable do
def evolve(pokemon)
end
defimpl Evolvable, for: Charmander do
def evolve(_charmander), do: %Charmeleon{}
end
defimpl Evolvable, for: Charmeleon do
def evolve(_charmeleon), do: %Charizard{}
end
defprotocol Evolvable do
end
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
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 pokemon-protocols-exercise
$ git add .
$ git commit -m "finish pokemon protocols exercise"
$ git push origin pokemon-protocols-exercise
Create a pull request from your pokemon-protocols-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.