diff --git a/pom.xml b/pom.xml
index 0680bce..a427f23 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,6 +20,18 @@
5.8.1
test
+
+ org.hamcrest
+ hamcrest-core
+ 2.2
+ test
+
+
+ org.mockito
+ mockito-core
+ 5.12.0
+ test
+
\ No newline at end of file
diff --git a/src/main/java/Action/Action.java b/src/main/java/Action/Action.java
index e1bf012..b65a6c4 100644
--- a/src/main/java/Action/Action.java
+++ b/src/main/java/Action/Action.java
@@ -1,5 +1,5 @@
package Action;
public interface Action {
- void exectue(Actor player);
+ void execute(Actor player);
}
diff --git a/src/main/java/Action/CastAction.java b/src/main/java/Action/CastAction.java
new file mode 100644
index 0000000..e54d024
--- /dev/null
+++ b/src/main/java/Action/CastAction.java
@@ -0,0 +1,19 @@
+package Action;
+
+import Job.HasJob;
+import Job.Wizard;
+
+public class CastAction implements Action {
+ private Wizard requireWizard(Actor actor) {
+ if (actor instanceof HasJob hasJob && hasJob.getJob() instanceof Wizard wizard) {
+ return wizard;
+ }
+ throw new IllegalStateException(actor + " cannot perform this action without being a Wizard!");
+ }
+
+ @Override
+ public void execute(Actor player) {
+ var wizard = requireWizard(player);
+ wizard.castSpell(player);
+ }
+}
diff --git a/src/main/java/Action/DigAction.java b/src/main/java/Action/DigAction.java
index 7fcc7fa..4d652e2 100644
--- a/src/main/java/Action/DigAction.java
+++ b/src/main/java/Action/DigAction.java
@@ -5,7 +5,7 @@ import Job.Miner;
public class DigAction implements Action {
@Override
- public void exectue(Actor actor) {
+ public void execute(Actor actor) {
Miner miner = requireMiner(actor);
miner.dig(actor);
}
diff --git a/src/main/java/Action/LearnSpellAction.java b/src/main/java/Action/LearnSpellAction.java
new file mode 100644
index 0000000..b3524a0
--- /dev/null
+++ b/src/main/java/Action/LearnSpellAction.java
@@ -0,0 +1,19 @@
+package Action;
+
+import Job.HasJob;
+import Job.Wizard;
+
+public class LearnSpellAction implements Action {
+ @Override
+ public void execute(Actor actor) {
+ Wizard wizard = requireWizard(actor);
+ wizard.learnSpell(actor);
+ }
+
+ private Wizard requireWizard(Actor actor) {
+ if (actor instanceof HasJob hasJob && hasJob.getJob() instanceof Wizard wizard) {
+ return wizard;
+ }
+ throw new IllegalStateException(actor + " cannot perform this action without being a Wizard!");
+ }
+}
diff --git a/src/main/java/Attack.java b/src/main/java/Attack.java
new file mode 100644
index 0000000..a292f3e
--- /dev/null
+++ b/src/main/java/Attack.java
@@ -0,0 +1,22 @@
+public abstract class Attack {
+ //Namnet och bägge dessa siffror är helt lösryckta
+ private static final String DEFAULT_NAME = "DEFAULT_NAME";
+ private static final double DEFAULT_ENERGY_COST = 5d;
+ private static final double DEFAULT_DAMAGE = 5d;
+
+ private String name;
+ private double energyCost;
+ private double damage;
+
+ public Attack() {
+ name = DEFAULT_NAME;
+ energyCost = DEFAULT_ENERGY_COST;
+ damage = DEFAULT_DAMAGE;
+ }
+
+ public Attack(String name, double energyCost, double damage) {
+ this.name = name;
+ this.energyCost = energyCost;
+ this.damage = damage;
+ }
+}
diff --git a/src/main/java/Biomes.java b/src/main/java/Biomes.java
new file mode 100644
index 0000000..3c61251
--- /dev/null
+++ b/src/main/java/Biomes.java
@@ -0,0 +1,3 @@
+public enum Biomes {
+ GRASSLAND, MOUNTAIN, COAST, FOREST //Är inte fäst vid dessa
+}
diff --git a/src/main/java/Character.java b/src/main/java/Character.java
new file mode 100644
index 0000000..3125774
--- /dev/null
+++ b/src/main/java/Character.java
@@ -0,0 +1,77 @@
+import Entity.Position;
+
+//Vill inte göra så mycket med den här klassen, då jag vill påverka implementeringen av Player så lite som möjligt
+public abstract class Character {
+ private static final double DEFAULT_HEALTH = 50d;
+ private static final double DEFAULT_LEVEL = 1.0;
+ private static final double DEFAULT_ENERGY = 50d; //Detta borde kanske egentligen beräknas och sättas automatiskt genom en algoritm som tar health och level i beaktskap?? Eller något sådant
+ private static final Position DEFAULT_POSITION = new Position(0,0); //Är detta en bra idé?? Mest för att kunna ha defaultkonstruktor
+
+ // Borde jag bara sätta allt till default direkt här????
+ private double health;
+ private double level;
+ private double energy; //Borde kanske beräknas genom en algoritm istället för att kunna sättas i konstruktorn... Så det alltid blir balanserat
+ private Position position;
+
+ // Hur många varianter på konstruktorn behövs?
+ public Character() {
+ this.health = DEFAULT_HEALTH;
+ this.level = DEFAULT_LEVEL;
+ this.energy = DEFAULT_ENERGY;
+ this.position = DEFAULT_POSITION;
+ }
+
+ // Jag antar att den som instansierar massa monster i världen ansvarar
+ // för att kolla att "position" har ett tillåtet värde.
+ // Just denna variant är bara för testning i min implementation av Monster
+ public Character(Position position) {
+ this.health = DEFAULT_HEALTH;
+ this.level = DEFAULT_LEVEL;
+ this.energy = DEFAULT_ENERGY;
+ this.position = position;
+ }
+
+ public Character(double health, double level, double energy, Position position) {
+ this.health = health;
+ this.level = level;
+ this.energy = energy;
+ this.position = position;
+ }
+
+ //Returnerar true om attacken gick igenom, annars false
+ //Tänker att positionen som skickas in är karaktärens egna
+ //Kommer antagligen behöva diverse hjälpmetoder i implementeringen då det är många krav som måste uppfyllas för att attacken ska gå igenom
+ abstract boolean attack(Position position, Character character);
+
+ public double getHealth() {
+ return health;
+ }
+
+ public void setHealth(int newHealth) {
+ health = newHealth;
+ }
+
+ public double getLevel() {
+ return level;
+ }
+
+ public void setLevel(int newLevel) {
+ level = newLevel;
+ }
+
+ public double getEnergy() {
+ return energy;
+ }
+
+ public void setEnergy(double newEnergy) {
+ energy = newEnergy;
+ }
+
+ public Position getPosition() {
+ return position;
+ }
+
+ public void setPosition(Position newPosition) {
+ position = newPosition;
+ }
+}
diff --git a/src/main/java/Character/HasSpellBook.java b/src/main/java/Character/HasSpellBook.java
new file mode 100644
index 0000000..6b3c6a4
--- /dev/null
+++ b/src/main/java/Character/HasSpellBook.java
@@ -0,0 +1,7 @@
+package Character;
+
+import java.util.List;
+
+public interface HasSpellBook {
+ List getSpellBook();
+}
diff --git a/src/main/java/Combat/HasHealth.java b/src/main/java/Combat/HasHealth.java
index 47e44c8..b5c7184 100644
--- a/src/main/java/Combat/HasHealth.java
+++ b/src/main/java/Combat/HasHealth.java
@@ -2,5 +2,6 @@ package Combat;
public interface HasHealth {
void setHealth(int health);
+ int getHealth();
boolean isAlive();
}
diff --git a/src/main/java/Combat/HasMana.java b/src/main/java/Combat/HasMana.java
new file mode 100644
index 0000000..8964f48
--- /dev/null
+++ b/src/main/java/Combat/HasMana.java
@@ -0,0 +1,6 @@
+package Combat;
+
+public interface HasMana {
+ void setMana(int mana);
+ int getMana();
+}
diff --git a/src/main/java/Combat/OffensiveDamageSpell.java b/src/main/java/Combat/OffensiveDamageSpell.java
new file mode 100644
index 0000000..05bea11
--- /dev/null
+++ b/src/main/java/Combat/OffensiveDamageSpell.java
@@ -0,0 +1,18 @@
+package Combat;
+
+import Entity.Entity;
+
+public class OffensiveDamageSpell extends Spell {
+
+ public OffensiveDamageSpell(String spellName, int cost, int potency) {
+ super(spellName, cost, potency);
+ }
+
+ @Override
+ public void cast(Entity source, Entity target) {
+ if(target instanceof HasHealth health && source instanceof HasMana mana) {
+ mana.setMana(mana.getMana() - this.getCost());
+ health.setHealth(health.getHealth() - this.getPotency());
+ }
+ }
+}
diff --git a/src/main/java/Combat/Spell.java b/src/main/java/Combat/Spell.java
new file mode 100644
index 0000000..927442b
--- /dev/null
+++ b/src/main/java/Combat/Spell.java
@@ -0,0 +1,54 @@
+package Combat;
+
+import Entity.Entity;
+
+public abstract class Spell {
+ private final String spellName;
+ private int cost;
+ private int potency;
+
+ public Spell(String spellName, int cost, int potency) {
+ this.spellName = spellName;
+ this.cost = cost;
+ this.potency = potency;
+ }
+
+ public String getSpellName() {
+ return spellName;
+ }
+
+ public int getCost() {
+ return cost;
+ }
+
+ public int getPotency() {
+ return potency;
+ }
+
+ public abstract void cast(Entity source, Entity target);
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Spell spell = (Spell) o;
+
+ if (cost != spell.cost) return false;
+ if (potency != spell.potency) return false;
+ return spellName.equals(spell.spellName);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = spellName.hashCode();
+ result = 31 * result + cost;
+ result = 31 * result + potency;
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return spellName + " (Cost: " + cost + ", Potency: " + potency + ")";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/Entity/Player.java b/src/main/java/Entity/Player.java
index 8b49942..a7cb7f3 100644
--- a/src/main/java/Entity/Player.java
+++ b/src/main/java/Entity/Player.java
@@ -3,18 +3,24 @@ package Entity;
import Action.Action;
import Action.Actor;
import Combat.HasHealth;
+import Combat.HasMana;
+import Combat.Spell;
+import Inventory.Inventory;
import Job.Job;
import Job.HasJob;
import Inventory.HasInventory;
+import Inventory.HasSpellBook;
import java.util.LinkedList;
import java.util.List;
-public class Player extends Entity implements Movable, Actor, HasInventory, HasJob, HasHealth {
+public class Player extends Entity implements Movable, Actor, HasInventory, HasSpellBook, HasJob, HasHealth, HasMana {
protected int health;
+ protected int mana;
protected Job job;
- protected Position position;
- protected List items = new LinkedList<>();
+ protected Position position = new Position(0,0);
+ protected Inventory inventory= new Inventory();
+ protected List spells = new LinkedList<>();
public Player(String name, Job job) {
super(name);
this.job = job;
@@ -34,7 +40,7 @@ public class Player extends Entity implements Movable, Actor, HasInventory, HasJ
@Override
public boolean canMoveTo(Position position) {
- return false;
+ return true;
}
public Job getJob() {
return job;
@@ -45,13 +51,15 @@ public class Player extends Entity implements Movable, Actor, HasInventory, HasJ
this.job = job;
}
- public List getInventory() {
- return items;
+ public Inventory getInventory() {
+ return inventory;
}
+ public List getSpellBook() {return spells;}
+
@Override
public void performAction(Action action) {
- action.exectue(this);
+ action.execute(this);
}
@Override
@@ -69,6 +77,15 @@ public class Player extends Entity implements Movable, Actor, HasInventory, HasJ
this.health = health;
}
+ @Override
+ public int getHealth() {return health;}
+
+ @Override
+ public void setMana(int mana) {this.mana = mana;}
+
+ @Override
+ public int getMana() {return mana;}
+
@Override
public boolean isAlive() {
return health > 0;
diff --git a/src/main/java/Inventory/HasInventory.java b/src/main/java/Inventory/HasInventory.java
index 856c2da..2b894b7 100644
--- a/src/main/java/Inventory/HasInventory.java
+++ b/src/main/java/Inventory/HasInventory.java
@@ -3,5 +3,5 @@ package Inventory;
import java.util.List;
public interface HasInventory {
- List getInventory();
+ Inventory getInventory();
}
diff --git a/src/main/java/Inventory/HasSpellBook.java b/src/main/java/Inventory/HasSpellBook.java
new file mode 100644
index 0000000..5188389
--- /dev/null
+++ b/src/main/java/Inventory/HasSpellBook.java
@@ -0,0 +1,8 @@
+package Inventory;
+
+import java.util.List;
+import Combat.Spell;
+
+public interface HasSpellBook {
+ List getSpellBook();
+}
diff --git a/src/main/java/Inventory/Inventory.java b/src/main/java/Inventory/Inventory.java
new file mode 100644
index 0000000..786cfda
--- /dev/null
+++ b/src/main/java/Inventory/Inventory.java
@@ -0,0 +1,24 @@
+package Inventory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Inventory {
+ List items;
+
+ public Inventory() {
+ items = new ArrayList<>();
+ }
+
+ List getItems() {
+ return items;
+ }
+
+ public void addItem(String item) {
+ items.add(item);
+ }
+
+ public boolean containsItem(String item) {
+ return items.contains(item);
+ }
+}
diff --git a/src/main/java/Job/Job.java b/src/main/java/Job/Job.java
index e399ed3..a25fe60 100644
--- a/src/main/java/Job/Job.java
+++ b/src/main/java/Job/Job.java
@@ -1,10 +1,11 @@
package Job;
-import Shared.HasExperience;
+import Shared.ExperienceTable;
+import Shared.Levelable;
import java.util.Objects;
-public abstract class Job implements HasExperience {
+public abstract class Job implements Levelable {
protected int level;
protected int experience;
protected String name;
@@ -18,7 +19,27 @@ public abstract class Job implements HasExperience {
return level;
}
+ @Override
+ public int remainingXpUntilLevelUp() {
+ return ExperienceTable.getXpForLevel(level) - experience;
+ }
+
+ @Override
+ public void gainExperience(int exp) {
+ experience += exp;
+ if (experience >= ExperienceTable.getXpForLevel(level)) {
+ levelUp();
+ }
+ }
+
+ @Override
+ public int getExperience() {
+ return experience;
+ }
+
+ @Override
public void levelUp() {
+ experience = experience - ExperienceTable.getXpForLevel(level);
level++;
}
@@ -38,4 +59,5 @@ public abstract class Job implements HasExperience {
return Objects.hash(name);
}
+
}
diff --git a/src/main/java/Job/Miner.java b/src/main/java/Job/Miner.java
index ae10edd..79c56ec 100644
--- a/src/main/java/Job/Miner.java
+++ b/src/main/java/Job/Miner.java
@@ -11,17 +11,7 @@ public class Miner extends Job {
public void dig(Actor actor) {
if (actor instanceof HasInventory a) {
- a.getInventory().add("Stone");
+ a.getInventory().addItem("Stone");
}
}
-
- @Override
- public int getExperience() {
- return experience;
- }
-
- @Override
- public void gainExperience(int exp) {
- experience += exp;
- }
}
diff --git a/src/main/java/Job/Wizard.java b/src/main/java/Job/Wizard.java
new file mode 100644
index 0000000..db06bf4
--- /dev/null
+++ b/src/main/java/Job/Wizard.java
@@ -0,0 +1,70 @@
+package Job;
+
+import Action.Actor;
+import Combat.HasMana;
+import Combat.OffensiveDamageSpell;
+import Entity.Entity;
+import Inventory.HasSpellBook;
+import Combat.Spell;
+
+import java.util.Scanner;
+
+public class Wizard extends Job {
+ private final Scanner scanner;
+ public Wizard(Scanner scanner) {
+ super("Wizard");
+ this.scanner = scanner;
+ }
+
+ public Wizard() {
+ this(new Scanner(System.in));
+ }
+
+ public void learnSpell(Actor actor) {
+ if(actor instanceof HasSpellBook a ) {
+ OffensiveDamageSpell defaultSpell = new OffensiveDamageSpell("fireball", 20, 20);
+ a.getSpellBook().add(defaultSpell);
+ }
+ }
+
+ public void castSpell(Actor actor) {
+ if(actor instanceof HasSpellBook spellbook && actor instanceof HasMana mana && actor instanceof Entity entity) {
+ if(spellbook.getSpellBook().isEmpty()){
+ System.out.println("You haven't learned any spells");
+ return;
+ }
+
+ System.out.println("Which spell do you want to cast?");
+ for(int i = 0; i < spellbook.getSpellBook().size(); i++){
+ System.out.println((i + 1) + ". " + spellbook.getSpellBook().get(i).toString());
+ }
+
+ int spellIndex = scanner.nextInt();
+ scanner.nextLine();
+
+ if(spellIndex < 1 || spellIndex > spellbook.getSpellBook().size()) {
+ System.out.println("Invalid choice!");
+ return;
+ }
+
+ Spell spell = spellbook.getSpellBook().get(spellIndex - 1);
+
+ if (mana.getMana() >= spell.getCost()){
+ spell.cast(entity, entity);
+ }
+ else{
+ System.out.println("Not enough mana!");
+ }
+ }
+ }
+
+ @Override
+ public int getExperience() {
+ return experience;
+ }
+
+ @Override
+ public void gainExperience(int exp) {
+ experience += exp;
+ }
+}
diff --git a/src/main/java/Monster.java b/src/main/java/Monster.java
new file mode 100644
index 0000000..a9b3efc
--- /dev/null
+++ b/src/main/java/Monster.java
@@ -0,0 +1,32 @@
+import Entity.Position;
+
+import java.util.*;
+
+public abstract class Monster extends Character{
+
+ private final List habitat = new ArrayList<>();
+
+ public Monster() {
+ habitat.addAll(Arrays.asList(Biomes.GRASSLAND, Biomes.MOUNTAIN, Biomes.COAST, Biomes.FOREST));
+ }
+
+ public Monster(Position position) {
+ super(position);
+ habitat.addAll(Arrays.asList(Biomes.GRASSLAND, Biomes.MOUNTAIN, Biomes.COAST, Biomes.FOREST));
+ }
+
+ public Monster(double health, double level, double energy, Position position) {
+ super(health, level, energy, position);
+ habitat.addAll(Arrays.asList(Biomes.GRASSLAND, Biomes.MOUNTAIN, Biomes.COAST, Biomes.FOREST));
+ }
+
+ public Monster(double health, double level, double energy, Position position, List habitat) {
+ super(health, level, energy, position);
+ this.habitat.addAll(habitat);
+ }
+
+ //Är detta bra??? Med unmodifiableList dvs
+ public List getHabitat() {
+ return Collections.unmodifiableList(habitat);
+ }
+}
diff --git a/src/main/java/Shared/ExperienceTable.java b/src/main/java/Shared/ExperienceTable.java
new file mode 100644
index 0000000..1bc0de6
--- /dev/null
+++ b/src/main/java/Shared/ExperienceTable.java
@@ -0,0 +1,16 @@
+package Shared;
+
+import java.util.Map;
+
+public final class ExperienceTable {
+ private static final Map XP_TABLE = Map.of(
+ 1, 100,
+ 2, 250
+ );
+
+ private ExperienceTable() {}
+
+ public static int getXpForLevel(int level) {
+ return XP_TABLE.getOrDefault(level, Integer.MAX_VALUE);
+ }
+}
diff --git a/src/main/java/Shared/HasExperience.java b/src/main/java/Shared/Levelable.java
similarity index 65%
rename from src/main/java/Shared/HasExperience.java
rename to src/main/java/Shared/Levelable.java
index fcfb9ad..039c8ba 100644
--- a/src/main/java/Shared/HasExperience.java
+++ b/src/main/java/Shared/Levelable.java
@@ -1,6 +1,6 @@
package Shared;
-public interface HasExperience {
+public interface Levelable {
int getLevel();
int getExperience();
@@ -8,4 +8,6 @@ public interface HasExperience {
void gainExperience(int exp);
void levelUp();
+
+ int remainingXpUntilLevelUp();
}
diff --git a/src/main/java/Spell.java b/src/main/java/Spell.java
deleted file mode 100644
index 62ae11d..0000000
--- a/src/main/java/Spell.java
+++ /dev/null
@@ -1,18 +0,0 @@
-public class Spell {
- private final String spellName;
- private int cost;
- private int potency;
-
- public Spell(String spellName, int cost, int potency) {
- this.spellName = spellName;
- this.cost = cost;
- this.potency = potency;
- }
-
- public String getSpellName() {return spellName;}
-
- public int getCost() {return cost;}
-
- public int getPotency() {return potency;}
-}
-
diff --git a/src/test/java/InterestingTests.java b/src/test/java/InterestingTests.java
new file mode 100644
index 0000000..365a456
--- /dev/null
+++ b/src/test/java/InterestingTests.java
@@ -0,0 +1,65 @@
+import Combat.OffensiveDamageSpell;
+import Entity.Player;
+import Job.Wizard;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.util.Scanner;
+import static org.hamcrest.Matchers.*;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+
+public class InterestingTests {
+
+ private Wizard wizard;
+
+ @BeforeEach
+ public void setup() {
+ wizard = new Wizard();
+ }
+
+ @Test
+ public void testCastSpell_successfulCast() {
+ Scanner testScanner = new Scanner(new ByteArrayInputStream("1\n".getBytes()));
+ wizard = new Wizard(testScanner);
+
+ Player player = new Player("Gandalf", wizard);
+
+ player.setMana(50);
+ player.setHealth(100);
+
+ OffensiveDamageSpell fireball = new OffensiveDamageSpell("Fireball", 20, 15);
+ player.getSpellBook().add(fireball);
+
+ int initialMana = player.getMana();
+ int initialHealth = player.getHealth();
+
+ wizard.castSpell(player);
+
+ assertThat(player.getMana(), is(initialMana - fireball.getCost()));
+ assertThat(player.getHealth(), is(initialHealth - fireball.getPotency()));
+ }
+
+ @Test
+ public void testCastSpell_notEnoughMana() {
+ Scanner testScanner = new Scanner(new ByteArrayInputStream("1\n".getBytes()));
+ wizard = new Wizard(testScanner);
+
+ Player player = new Player("Merlin", wizard);
+ player.setMana(10);
+ player.setHealth(100);
+
+ OffensiveDamageSpell fireball = new OffensiveDamageSpell("Fireball", 20, 15);
+ player.getSpellBook().add(fireball);
+
+ int initialMana = player.getMana();
+ int initialHealth = player.getHealth();
+
+ wizard.castSpell(player);
+
+ assertThat(player.getMana(), is(initialMana));
+ assertThat(player.getHealth(),is(initialHealth));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/MagicSystemTest.java b/src/test/java/MagicSystemTest.java
new file mode 100644
index 0000000..852daa2
--- /dev/null
+++ b/src/test/java/MagicSystemTest.java
@@ -0,0 +1,61 @@
+import Action.CastAction;
+import Action.LearnSpellAction;
+import Combat.OffensiveDamageSpell;
+import Entity.Player;
+import Job.Wizard;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.*;
+
+public class MagicSystemTest {
+
+ private Player defaultPlayer() {
+ return new Player("Alex");
+ }
+
+ @Test void cant_cast_spell_without_being_wizard(){
+ var p = defaultPlayer();
+ CastAction action = new CastAction();
+ IllegalStateException exception = assertThrows(
+ IllegalStateException.class,
+ () -> action.execute(p)
+ );
+
+ assertTrue(exception.getMessage().contains("cannot perform this action without being a Wizard"));
+ }
+
+ @Test void cant_learn_spell_without_being_wizard(){
+ var p = defaultPlayer();
+ LearnSpellAction action = new LearnSpellAction();
+ IllegalStateException exception = assertThrows(
+ IllegalStateException.class,
+ () -> action.execute(p)
+ );
+ assertTrue(exception.getMessage().contains("cannot perform this action without being a Wizard"));
+ }
+
+ @Test void damage_spell_damages_target(){
+ var defaultSpell = new OffensiveDamageSpell("fireball", 20, 20);
+ var p = defaultPlayer();
+ p.setMana(30);
+ p.setHealth(30);
+ defaultSpell.cast(p, p);
+ assertEquals(10, p.getHealth());
+ }
+
+ @Test void damage_spell_drains_mana_from_caster(){
+ var defaultSpell = new OffensiveDamageSpell("fireball", 20, 20);
+ var p = defaultPlayer();
+ p.setMana(30);
+ p.setHealth(30);
+ defaultSpell.cast(p, p);
+ assertEquals(10, p.getMana());
+ }
+
+ @Test void cant_cast_spell_with_empty_spellbook(){
+ var p = defaultPlayer();
+ var job = new Wizard();
+ p.learnJob(job);
+ p.performAction(new CastAction());
+
+ }
+}
diff --git a/src/test/java/MinerTest.java b/src/test/java/MinerTest.java
index 0aad49b..cb187fb 100644
--- a/src/test/java/MinerTest.java
+++ b/src/test/java/MinerTest.java
@@ -6,7 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
public class MinerTest {
@Test
- void miner_can_level_up() {
+ void can_level_up() {
var job = new Miner();
assertEquals(1, job.getLevel());
job.levelUp();
@@ -14,12 +14,33 @@ public class MinerTest {
}
@Test
- void miner_can_gain_xp() {
+ void can_gain_xp() {
var job = new Miner();
job.gainExperience(25);
assertEquals(25, job.getExperience());
}
+ @Test
+ void level_up_when_experience_cap_is_reached() {
+ var job = new Miner();
+ job.gainExperience(job.remainingXpUntilLevelUp());
+ assertEquals(2, job.getLevel());
+ }
+
+ @Test
+ void additional_xp_carries_over_on_level_up() {
+ var job = new Miner();
+ job.gainExperience(job.remainingXpUntilLevelUp() + 10);
+ assertEquals(10, job.getExperience());
+ }
+
+ @Test
+ void dig_on_ice_require_ice_pick() {
+
+ }
+
+
+
}
diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java
new file mode 100644
index 0000000..cc75cd4
--- /dev/null
+++ b/src/test/java/MonsterTest.java
@@ -0,0 +1,50 @@
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.Test;
+
+public class MonsterTest {
+
+ @Test
+ void monster_cannot_attack_when_dead() {
+ /*
+ Monster someMonster = new Monster();
+ someMonster.setHealth(-5d);
+ Assert(false, someMonster.attack(someMonster.getPosition(), character));
+ */
+ }
+
+ @Test
+ void monster_cannot_be_attacked_when_dead() {
+ /*
+ Monster attackingMonster = new Monster();
+ Monster deadMonster = new Monster();
+ deadMonster.setHealth(-4d);
+ Assert(false, attackingMonster.attack(attackingMonster.getPosition(), deadMonster));
+ */
+ }
+
+ @Test
+ void monster_cannot_attack_character_at_different_position() {
+ /*
+ Monster monsterAtOnePosition = new Monster(new Position(0,0));
+ Monster monsterAtDifferentPosition = new Monster(new Position(1,1));
+ Assert(false, monsterAtOnePosition.attack(monsterAtOnePosition.getPosition(), monsterAtDifferentPosition);
+ */
+ }
+
+ @Test
+ void monster_is_instantiated_correctly_from_default_constructor() {
+ /*
+ AssertAll????
+ */
+ }
+
+ @Test
+ void monster_is_instantiated_correctly_from_position_only_constructor() {
+
+ }
+
+ @Test
+ void monster_is_instantiated_correctly_from_full_constructor() {
+
+ }
+}
diff --git a/src/test/java/PlayerTest.java b/src/test/java/PlayerTest.java
index 37157aa..970f0f9 100644
--- a/src/test/java/PlayerTest.java
+++ b/src/test/java/PlayerTest.java
@@ -1,8 +1,11 @@
import Action.DigAction;
+import Action.LearnSpellAction;
+import Combat.OffensiveDamageSpell;
import Entity.Position;
import Job.Miner;
import Entity.Player;
import org.junit.jupiter.api.Test;
+import Job.Wizard;
import static org.junit.jupiter.api.Assertions.*;
@@ -18,6 +21,18 @@ class PlayerTest {
assertFalse(p.isAlive());
}
+ @Test void get_health_returns_health() {
+ var p = defaultPlayer();
+ p.setHealth(10);
+ assertEquals(10, p.getHealth());
+ }
+
+ @Test void get_mana_returns_mana() {
+ var p = defaultPlayer();
+ p.setMana(10);
+ assertEquals(10, p.getMana());
+ }
+
@Test
public void can_change_position() {
var p = defaultPlayer();
@@ -38,9 +53,19 @@ class PlayerTest {
@Test
void miner_can_dig() {
var p = new Player("John");
- var job = new Miner();
- p.learnJob(job);
+ p.learnJob(new Miner());
p.performAction(new DigAction());
- assertTrue(p.getInventory().contains("Stone"));
+ assertTrue(p.getInventory().containsItem("Stone"));
+ }
+
+ @Test
+ void wizard_can_learn_spell() {
+ var p = new Player("Bob");
+ var job = new Wizard();
+ var defaultSpell = new OffensiveDamageSpell("fireball", 20, 20);
+ p.learnJob(job);
+ p.performAction(new LearnSpellAction());
+ System.out.println(p.getSpellBook());
+ assertTrue(p.getSpellBook().contains(defaultSpell));
}
}
\ No newline at end of file
diff --git a/src/test/java/SpellTest.java b/src/test/java/SpellTest.java
index d039d0d..9ed92f4 100644
--- a/src/test/java/SpellTest.java
+++ b/src/test/java/SpellTest.java
@@ -1,3 +1,5 @@
+import Combat.OffensiveDamageSpell;
+import Combat.Spell;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@@ -5,19 +7,19 @@ import static org.junit.jupiter.api.Assertions.*;
public class SpellTest {
private Spell defaultSpell() {
- return new Spell("fireball", 20, 40);
+ return new OffensiveDamageSpell("fireball", 20, 40);
}
@Test
void setSpellNameOnCreation(){
var spell = defaultSpell();
- assertEquals("fireball", spell.getSpellName(), "Spell name should be set");
+ assertEquals("fireball", spell.getSpellName(), "Combat.Spell name should be set");
}
@Test
void setCostOnCreation() {
var spell = defaultSpell();
- assertEquals(20, spell.getCost(), "Spell cost should have been set");
+ assertEquals(20, spell.getCost(), "Combat.Spell cost should have been set");
}
@Test
diff --git a/src/test/java/WizardTest.java b/src/test/java/WizardTest.java
new file mode 100644
index 0000000..2fe1093
--- /dev/null
+++ b/src/test/java/WizardTest.java
@@ -0,0 +1,26 @@
+import Job.Wizard;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.*;
+
+public class WizardTest {
+
+ @Test
+ void wizard_has_level() {
+ var job = new Wizard();
+ assertEquals(1, job.getLevel());
+ }
+
+ @Test
+ void wizard_can_level_up() {
+ var job = new Wizard();
+ job.levelUp();
+ assertEquals(2, job.getLevel());
+ }
+
+ @Test
+ void wizard_can_gain_xp(){
+ var job = new Wizard();
+ job.gainExperience(40);
+ assertEquals(40, job.getExperience());
+ }
+}