diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..537eaa0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,34 @@
+### IntelliJ IDEA ###
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+*.idea
+.idea
+*.iml
+
+target/
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..094b135
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,35 @@
+
+
+ 4.0.0
+
+ groupId
+ lab-java-intro-to-testing
+ 1.0-SNAPSHOT
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+ provided
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.10.2
+ test
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/Elf.java b/src/main/java/Elf.java
new file mode 100644
index 0000000..8e8d30e
--- /dev/null
+++ b/src/main/java/Elf.java
@@ -0,0 +1,19 @@
+import lombok.*;
+
+@Getter
+public class Elf extends Player {
+
+ public static final int DEFAULT_SPEED = 10;
+
+ private int speed;
+
+ public Elf(int health, int strength, int lives, int speed) {
+ super(health, strength, lives);
+ this.speed = speed;
+ }
+
+ public Elf(int health, int strength, int lives) {
+ super(health, strength, lives);
+ this.speed = DEFAULT_SPEED;
+ }
+}
diff --git a/src/main/java/Player.java b/src/main/java/Player.java
new file mode 100644
index 0000000..6bbc158
--- /dev/null
+++ b/src/main/java/Player.java
@@ -0,0 +1,34 @@
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public abstract class Player {
+ public Player(int health, int strength, int lives) {
+ this.health = health;
+ this.strength = strength;
+ this.lives = lives;
+ initialHealth = health;
+ }
+
+ private final int initialHealth;
+ private int health;
+ private int strength;
+ private int lives;
+
+ public void attack(Player playerToAttack) {
+ playerToAttack.setHealth(playerToAttack.getHealth() - strength);
+ playerToAttack.checkHealth();
+ }
+
+ public void decrementLive(){
+ lives--;
+ health = 3;
+ if (lives <= 0) System.out.println("This character is dead");
+ }
+
+ public void checkHealth() {
+ if (health <= 0) decrementLive();
+ }
+
+}
diff --git a/src/main/java/Utils.java b/src/main/java/Utils.java
new file mode 100644
index 0000000..ca93458
--- /dev/null
+++ b/src/main/java/Utils.java
@@ -0,0 +1,29 @@
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+public class Utils {
+
+
+ public static int[] getOddsFromOneToValue(int value) {
+ return IntStream.rangeClosed(1, value)
+ .filter(n -> n % 2 != 0)
+ .toArray();
+ }
+
+ public boolean containsKeyWord(String s) {
+ List keywordsList = Arrays.asList(
+ "abstract", "continue", "for", "new", "switch", "assert", "default", "goto",
+ "package", "synchronized", "boolean", "do", "if", "private", "this", "break",
+ "double", "implements", "protected", "throw", "byte", "else", "import", "public",
+ "throws", "case", "enum", "instanceof", "return", "transient", "catch", "extends",
+ "int", "short", "try", "char", "final", "interface", "static", "void", "class",
+ "finally", "long", "strictfp", "volatile", "const", "float", "native", "super", "while"
+ );
+
+ return Arrays.stream(s.split(" ")).anyMatch(word -> keywordsList.contains(word));
+ }
+
+}
diff --git a/src/main/java/Warrior.java b/src/main/java/Warrior.java
new file mode 100644
index 0000000..512258a
--- /dev/null
+++ b/src/main/java/Warrior.java
@@ -0,0 +1,17 @@
+import lombok.Getter;
+
+@Getter
+public class Warrior extends Player {
+
+ private int force;
+
+ public Warrior(int health, int strength, int lives, int force) {
+ super(health, strength, lives);
+ this.force = force;
+ }
+
+ public Elf convertToElf(){
+ return new Elf(getHealth(), getStrength(), getLives());
+ }
+
+}
diff --git a/src/main/java/Wizard.java b/src/main/java/Wizard.java
new file mode 100644
index 0000000..7b046fe
--- /dev/null
+++ b/src/main/java/Wizard.java
@@ -0,0 +1,27 @@
+import lombok.Getter;
+
+
+
+@Getter
+public class Wizard extends Player {
+
+ private int spell;
+
+ public Wizard(int health, int strength, int lives, int spell) {
+ super(health, strength, lives);
+ this.spell = spell;
+ }
+
+ public Elf convertToElf(){
+ return new Elf(getHealth(), getStrength(), getLives());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Wizard wizard = (Wizard) o;
+ return spell == wizard.spell;
+ }
+
+}
diff --git a/src/test/java/PlayerTest.java b/src/test/java/PlayerTest.java
new file mode 100644
index 0000000..f957df6
--- /dev/null
+++ b/src/test/java/PlayerTest.java
@@ -0,0 +1,88 @@
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class PlayerTest {
+
+ Warrior warrior;
+ Wizard wizard;
+ Elf elf;
+
+ @Test
+ @DisplayName("Should create a warrior and convert it into an elf with the exact feature values and the default speed")
+ void convertWarriorToElf() {
+ warrior = new Warrior(100, 10, 3, 5);
+
+ elf = warrior.convertToElf();
+
+ assertTrue(warrior instanceof Warrior);
+ assertEquals(5, warrior.getForce());
+
+ assertTrue(elf instanceof Elf);
+
+ assertEquals(warrior.getHealth(), warrior.getInitialHealth());
+ assertEquals(warrior.getHealth(), elf.getHealth());
+ assertEquals(warrior.getStrength(), elf.getStrength());
+ assertEquals(warrior.getLives(), elf.getLives());
+ assertEquals(Elf.DEFAULT_SPEED, elf.getSpeed());
+ }
+
+ @Test
+ @DisplayName("Should create a wizard and convert it into an elf with the exact feature values and the default speed")
+ void convertWizardToElf() {
+ wizard = new Wizard(100, 10, 3, 5);
+
+ elf = wizard.convertToElf();
+
+ assertTrue(wizard instanceof Wizard);
+ assertEquals(5, wizard.getSpell());
+
+ assertTrue(elf instanceof Elf);
+ assertEquals(100, elf.getHealth());
+ assertEquals(10, elf.getStrength());
+ assertEquals(3, elf.getLives());
+
+ assertEquals(Elf.DEFAULT_SPEED, elf.getSpeed());
+ }
+
+ @Test
+ @DisplayName("Should create a copy of one wizard with the same feature values")
+ void createTwoDifferentWizards() {
+ Wizard wizard = new Wizard(100, 10, 3, 5);
+ Wizard wizardCopy = new Wizard(100, 10, 3, 5);
+
+ assertTrue(wizard.equals(wizardCopy));
+ }
+ @Test
+ @DisplayName("An Elf should attack a warrior and a wizard and decrease their health by -25")
+ void decrementHealth() {
+ wizard = new Wizard(80, 40, 3, 5);
+ warrior = new Warrior(100, 90, 3, 5);
+ elf = new Elf(300, 25, 3 ,5);
+ int initialWarriorHealth = warrior.getHealth();
+ int initialWizardHealth = wizard.getHealth();
+
+ elf.attack(warrior);
+ elf.attack(wizard);
+
+ assertEquals(initialWarriorHealth - elf.getStrength(), warrior.getHealth());
+ assertEquals(initialWizardHealth - elf.getStrength(), wizard.getHealth());
+ }
+
+ @Test
+ @DisplayName("An elf should kill a warrior")
+ void decrementLive() {
+ warrior = new Warrior(100, 90, 3, 5);
+ elf = new Elf(300, 25, 3 ,5);
+ int initialWarriorLives = warrior.getLives();
+
+ elf.attack(warrior);
+ elf.attack(warrior);
+ elf.attack(warrior);
+ elf.attack(warrior);
+
+ assertEquals(initialWarriorLives - 1, warrior.getLives());
+ }
+}
diff --git a/src/test/java/UtilsTest.java b/src/test/java/UtilsTest.java
new file mode 100644
index 0000000..106c6b0
--- /dev/null
+++ b/src/test/java/UtilsTest.java
@@ -0,0 +1,31 @@
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class UtilsTest {
+
+ private Utils utils;
+
+
+ @BeforeEach
+ public void setUp() {
+ utils = new Utils();
+ }
+
+ @Test
+ @DisplayName("Should take an integer n and return all odd integers from 1 to n")
+ void getOddsFromOneToValue() {
+ assertEquals(Utils.getOddsFromOneToValue(3).length, 2);
+ assertEquals(Utils.getOddsFromOneToValue(5).length, 3);
+ }
+
+ @Test
+ @DisplayName("Should return true when receive a String containing a keyword")
+ void containsKeyWord() {
+ assertTrue(utils.containsKeyWord("Don't break my heart"));
+ assertFalse(utils.containsKeyWord("I love to breakdance"));
+ }
+
+}
\ No newline at end of file