Pokemon Battle
Mix.install([
{:jason, "~> 1.4"},
{:kino, "~> 0.9", override: true},
{:youtube, github: "brooklinjazz/youtube"},
{:hidden_cell, github: "brooklinjazz/hidden_cell"}
])
Navigation
Home Report An Issue RPG DialogueRangesOverview
You’re going to create a pokemon battle game. If you’re not familiar with pokemon, it’s a game where elemental creatures battle.
Define The Pokemon Struct
You’re going to represent pokemon using a Pokemon
struct with the following keys.
-
:name
will be a string. -
:type
will be an atom of either:grass
,:water
, or:fire
-
:health
will be a float with a default value of20.0
-
:attack
will be an integer with a default value of5
-
:speed
will be an integer
You do not need to validate the data types for the keys above.
These are simply the expected data types for each Pokemon
struct instance.
%Pokemon{name: "Bulbasaur", type: :grass, health: 20, attack: 5, speed: 20}
Pokemon.attack/2
Create a Pokemon.attack/2 function to make one pokemon attack another.
The pokemon will apply their :attack
value multiplied by a type advantage modified according to the following list. strong attacks are multiplied by 2
and weak attacks are multiplied by 0.5
.
-
:fire
is strong against:grass
-
:grass
is strong against:water
-
:water
is strong against:fire
-
:fire
is weak against:water
-
:grass
is weak against:fire
-
:water
is weak against:grass
- the same type should deal normal damage.
For example:
attacker = %Pokemon{name: "Charmander", type: :fire, health: 20.0, attack: 5, speed: 20}
defender = %Pokemon{name: "Bulbasaur", type: :grass, health: 20.0, attack: 5, speed: 20}
# Applies 5 * 2 Damage. Original Health: 20.0, New Health: 10.0.
Pokemon.attack(attacker, defender)
%Pokemon{name: "Bulbasaur", type: :grass, health: 10.0, attack: 5, speed: 20}
Example solution
defmodule Pokemon do
defstruct [:name, :type, :health, :attack, :speed]
def attack(attacker, defender) do
damage = attacker.attack * modifier(attacker.type, defender.type)
%__MODULE__{defender | health: defender.health - damage}
end
defp modifier(attacker_type, defender_type) do
cond do
super_effective?(attacker_type, defender_type) -> 2
super_effective?(defender_type, attacker_type) -> 0.5
true -> 1
end
end
defp super_effective?(attacker_type, defender_type) do
{attacker_type, defender_type} in [{:fire, :grass}, {:grass, :water}, {:water, :fire}]
end
end
defmodule Pokemon do
@moduledoc """
Pokemon
## Examples
iex> attacker = %Pokemon{name: "Charmander", type: :fire, health: 20.0, attack: 5, speed: 20}
iex> defender = %Pokemon{name: "Bulbasaur", type: :grass, health: 20.0, attack: 5, speed: 20}
iex> Pokemon.attack(attacker, defender)
%Pokemon{name: "Bulbasaur", type: :grass, health: 10.0, attack: 5, speed: 20}
"""
defstruct [:name, :attack, :health, :speed, :type]
def attack(attacker, defender) do
dmg = attacker.attack * modifier(attacker.type, defender.type)
%__MODULE__{defender | health: defender.health - dmg}
end
defp modifier(attacker, defender) do
cond do
strong_attack?(attacker, defender) -> 2
strong_attack?(defender, attacker) -> 0.5
true -> 1
end
end
defp strong_attack?(attacker, defender) do
{attacker, defender} in [{:fire, :grass}, {:grass, :water}, {:water, :fire}]
end
end
Consider using the following Elixir cell to test your solution.
charmander = %Pokemon{name: "Charmander", type: :fire, health: 20.0, attack: 5, speed: 20}
bulbasaur = %Pokemon{name: "Bulbasaur", type: :grass, health: 20.0, attack: 5, speed: 20}
squirtle = %Pokemon{name: "Squirtle", type: :water, health: 20.0, attack: 5, speed: 20}
bulbasaur = Pokemon.attack(squirtle, bulbasaur)
squirtle = Pokemon.attack(bulbasaur, squirtle)
squirtle = Pokemon.attack(bulbasaur, squirtle)
Pokemon Instances
Bind three variables charmander
, bulbasaur
, and squirtle
to an instance of a Pokemon
struct with the following information.
classDiagram
class charmander {
name: "Charmander"
type: :fire
health: 20.0
attack: 5
speed: 20
}
class bulbasaur {
name: "Bulbasar"
type: :grass
health: 20.0
attack: 5
speed: 20
}
class squirtle {
name: "Squirtle"
type: :water
health: 20.0
attack: 5
speed: 20
}
You may use these three structs to test your Pokemon.attack/2
function.
Example solution
charmander = %Pokemon{name: "Charmander", type: :fire, health: 20, attack: 5, speed: 20}
bulbasaur = %Pokemon{name: "Bulbasaur", type: :grass, health: 20, attack: 5, speed: 20}
squirtle = %Pokemon{name: "Squirtle", type: :water, health: 20, attack: 5, speed: 20}
# Testing Example
Pokemon.attack(charmander, bulbasaur)
Enter your solution below.
charmander = %Pokemon{name: "Charmander", type: :fire, health: 20.0, attack: 5, speed: 20}
bulbasaur = %Pokemon{name: "Bulbasaur", type: :grass, health: 20.0, attack: 5, speed: 20}
squirtle = %Pokemon{name: "Squirtle", type: :water, health: 20.0, attack: 5, speed: 20}
Commit Your Progress
DockYard Academy now recommends you use the latest Release rather than forking or cloning our repository.
Run git status
to ensure there are no undesirable changes.
Then run the following in your command line from the curriculum
folder to commit your progress.
$ git add .
$ git commit -m "finish Pokemon Battle exercise"
$ git push
We’re proud to offer our open-source curriculum free of charge for anyone to learn from at their own pace.
We also offer a paid course where you can learn from an instructor alongside a cohort of your peers. We will accept applications for the June-August 2023 cohort soon.