Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Pokemon Server

pokemon_server.livemd

Pokemon Server

Mix.install([
  {:kino, github: "livebook-dev/kino", override: true},
  {:kino_lab, "~> 0.1.0-dev", github: "jonatanklosko/kino_lab"},
  {:vega_lite, "~> 0.1.4"},
  {:kino_vega_lite, "~> 0.1.1"},
  {:benchee, "~> 0.1"},
  {:ecto, "~> 3.7"},
  {:math, "~> 0.7.0"},
  {:faker, "~> 0.17.0"},
  {:utils, path: "#{__DIR__}/../utils"},
  {:tested_cell, git: "https://github.com/BrooklinJazz/tested_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.

Overview

You’re going to create a pokemon battle game with persistence.

Pokemon will each be their own process storing the stats of a pokemon.

flowchart
PK[Pokemon]
PS[PokemonServer]
PS --> PK
PK --> name[name: charmander]
PK --> type[type: fire]
PK --> hp[health: 20]
PK --> at[attack: 5]

Pokemon can attack each other. An attack should update the Pokemon‘s health in the PokemonServer‘s state.

flowchart
PK1[Pokemon]
PK2[Pokemon]
PS1[PokemonServer]
PS2[PokemonServer]

PS1 --> PK1
PS2 --> PK2
PS1 --attack--> PS2
PK2 --> hp[health: 10]

Define A Pokemon Struct

In the Elixir cell below, define a Pokemon struct. Use Ecto.Changeset to validate the struct fields and ensure that:

  • :name will be a string.
  • :type will be an atom of either :grass, :water, or :fire
  • :health will be an integer 0 or greater with a default value of 20
  • :attack will be an integer 1 or greater with a default value of 5

We should be able to create a new pokemon like so:

# Using default values
{:ok, %Pokemon{name: "charmander", type: "fire", health: 20, attack: 20}} =
Pokemon.new(%{name: "charmander", type: "fire"})

# Or manually setting all values
{:ok, bulbasaur} = Pokemon.new(%{name: "bulbasaur", type: "water", health: 30, attack: 2})

And we should get an error if we enter invalid input.

Pokemon.new(%{name: 1, type: "fire"})
{:error, changeset} = Pokemon.new(%{name: "bulbasaur", type: "water", health: 30, attack: 2})

Pokemon should be able to attack/2 other pokemon. Take type advantage into consideration. see Pokemon Battle for a reminder on type advantages.

{:ok, charmander} = Pokemon.new(%{name: "charmander", type: "fire", damage: 20})
{:ok, bulbasaur} = Pokemon.new(%{name: "bulbasaur", type: "water", health: 100})

Pokemon.attack(charmander, bulbasaur)
%Pokemon{name: "bulbasaur", type: "water", damage: 5, health: 90}

Pokemon health should not fall below 0.

{:ok, charmander} = Pokemon.new(%{name: "charmander", type: "fire", damage: 110})
{:ok, bulbasaur} = Pokemon.new(%{name: "charmander", type: "fire", health: 100})

Pokemon.attack(charmander, bulbasaur)
%Pokemon{name: "charmader", type: "fire", damage: 5, health: 0}

Your Solution

Enter your solution in the Elixir cell below.

defmodule Pokemon do
end

Create A Pokemon Genserver

In the Elixir cell below, create a PokemonServer Genserver which should store a Pokemon struct in it’s state.

We should be able to start/1 a new pokemon server.

{:ok, charmander} = Pokemon.new(%{name: "charmander", type: "fire"})

charmander_server = PokemonServer.start(charmander)

We should be able to retrieve current stats of the Pokemon.

PokemonServer.stats(charmander_server)
%Pokemon{name: "charmander", type: "fire", health: 20, damage: 5}

We should be able to attack another pokemon.

{:ok, charmander} = Pokemon.new(%{name: "charmander", type: "fire", damage: 20})
{:ok, bulbasaur} = Pokemon.new(%{name: "bulbasaur", type: "water", health: 100})

charmander_server = PokemonServer.start(charmander)
bulbasaur_server = PokemonServer.start(charmander)
PokemonServer.attack(charmander, bulbasaur)

PokemonServer.stats(bulbasaur_server)
%Pokemon{name: "bulbasaur", type: "water", damage: 5, health: 90}

Your Solution

Enter your answer in the Elixir cell below.

defmodule PokemonServer do
end

Commit Your Progress

Run the following in your command line from the project folder to track and save your progress in a Git commit.

$ git add .
$ git commit -m "finish pokemon server exercise"