diff --git a/src/main/scala/Main.scala b/src/main/scala/Main.scala
new file mode 100644
index 0000000000000000000000000000000000000000..1c393e279525f1f23c38c523a8e95fe8991216ae
--- /dev/null
+++ b/src/main/scala/Main.scala
@@ -0,0 +1,11 @@
+@main def main() =
+    val pkmn = PokemonFactory("Bulbasaur")
+    val pkmn2 = PokemonFactory("Charmander")
+
+    println(pkmn)
+    println(pkmn2)
+
+    pkmn.attack(CapacityFactory("Vine Whip"), pkmn2)
+
+    println(pkmn)
+    println(pkmn2)
diff --git a/src/main/scala/Pokemon/Capacity.scala b/src/main/scala/Pokemon/Capacity.scala
new file mode 100644
index 0000000000000000000000000000000000000000..ae604352b3a9069ae188fbbea15cee5e84fcbd48
--- /dev/null
+++ b/src/main/scala/Pokemon/Capacity.scala
@@ -0,0 +1 @@
+class Capacity(name: String, val ctype: Type)
diff --git a/src/main/scala/Pokemon/CapacityFactory.scala b/src/main/scala/Pokemon/CapacityFactory.scala
new file mode 100644
index 0000000000000000000000000000000000000000..08d04df98f199b558365728179a86ef15fcdcdc7
--- /dev/null
+++ b/src/main/scala/Pokemon/CapacityFactory.scala
@@ -0,0 +1,6 @@
+object CapacityFactory:
+
+    private case class VineWhip() extends Capacity("Vine Whip", Grass)
+
+    def apply(name: String): Capacity = name match
+        case "Vine Whip" => VineWhip()
diff --git a/src/main/scala/Pokemon/Pokemon.scala b/src/main/scala/Pokemon/Pokemon.scala
new file mode 100644
index 0000000000000000000000000000000000000000..b16a05f5cf079cda1ff6597ef802dcb55eaaf54c
--- /dev/null
+++ b/src/main/scala/Pokemon/Pokemon.scala
@@ -0,0 +1,10 @@
+trait Pokemon(var name: String, var life: Int, val ptype: Type):
+
+    def attack(capacity: Capacity, other: Pokemon) =
+        val multiplicator = capacity.ctype.computeMultiplier(other.ptype)
+
+        other.decreaseLife(Math.round(multiplicator.floatValue))
+
+    def decreaseLife(x: Int) = this.life = this.life - x
+
+    override def toString(): String = s"[${this.name}] Life: ${this.life}"
diff --git a/src/main/scala/Pokemon/PokemonFactory.scala b/src/main/scala/Pokemon/PokemonFactory.scala
new file mode 100644
index 0000000000000000000000000000000000000000..e0f92207b38d5ca4a6e1b0830195afbd9a1262dc
--- /dev/null
+++ b/src/main/scala/Pokemon/PokemonFactory.scala
@@ -0,0 +1,10 @@
+object PokemonFactory:
+
+    private case class Bulbasaur() extends Pokemon("Bulbasaur", 25, Grass)
+    private case class Charmander() extends Pokemon("Charmander", 30, Fire)
+    private case class Squirtle() extends Pokemon("Squirtle", 25, Water)
+
+    def apply(name: String): Pokemon = name match
+        case "Bulbasaur"  => Bulbasaur()
+        case "Charmander" => Charmander()
+        case "Squirtle"   => Squirtle()
diff --git a/src/main/scala/Pokemon/Type.scala b/src/main/scala/Pokemon/Type.scala
new file mode 100644
index 0000000000000000000000000000000000000000..b75a3cd35ffefff00d51676dfbc4c507986e2ad9
--- /dev/null
+++ b/src/main/scala/Pokemon/Type.scala
@@ -0,0 +1,7 @@
+sealed trait Type(val strength: List[Type], val weakness: List[Type]):
+    def computeMultiplier(ptype: Type) =
+        if strength.contains(ptype) then 2 else if weakness.contains(ptype) then 0.5 else 1
+
+case object Grass extends Type(List(Water), List(Fire))
+case object Water extends Type(List(Fire), List(Grass, Water))
+case object Fire extends Type(List(Grass), List(Water))