magic #11

Merged
masi0885 merged 4 commits from magic into main 2025-10-29 10:30:18 +01:00
9 changed files with 142 additions and 32 deletions
Showing only changes of commit bcb236a7f6 - Show all commits

View File

@ -0,0 +1,9 @@
package Combat;
import java.util.List;
public interface HasConditions {
void addCondition(String condition);
void removeCondition(String condition);
List<String> getConditions();
}

View File

@ -3,9 +3,11 @@ package Combat;
import Entity.Entity; import Entity.Entity;
public class OffensiveDamageSpell extends Spell { public class OffensiveDamageSpell extends Spell {
private final int potency;
public OffensiveDamageSpell(String spellName, int cost, int potency) { public OffensiveDamageSpell(String spellName, int cost, int potency) {
super(spellName, cost, potency); super(spellName, cost);
this.potency = potency;
} }
@Override @Override
@ -15,4 +17,6 @@ public class OffensiveDamageSpell extends Spell {
health.setHealth(health.getHealth() - this.getPotency()); health.setHealth(health.getHealth() - this.getPotency());
} }
} }
public int getPotency() {return potency;}
} }

View File

@ -0,0 +1,22 @@
package Combat;
import Entity.Entity;
public class OffensiveStatusSpell extends Spell {
private final String status;
public OffensiveStatusSpell(String spellName, int cost, String status) {
super(spellName, cost);
this.status = status;
}
public void cast(Entity source, Entity target) {
if(source instanceof HasMana mana && target instanceof HasConditions conditions) {
mana.setMana(mana.getMana() - this.getCost());
conditions.addCondition(this.getStatus());
}
}
public String getStatus() {return status;}
}

View File

@ -5,12 +5,10 @@ import Entity.Entity;
public abstract class Spell { public abstract class Spell {
private final String spellName; private final String spellName;
private int cost; private int cost;
private int potency;
public Spell(String spellName, int cost, int potency) { public Spell(String spellName, int cost) {
this.spellName = spellName; this.spellName = spellName;
this.cost = cost; this.cost = cost;
this.potency = potency;
} }
public String getSpellName() { public String getSpellName() {
@ -21,10 +19,6 @@ public abstract class Spell {
return cost; return cost;
} }
public int getPotency() {
return potency;
}
public abstract void cast(Entity source, Entity target); public abstract void cast(Entity source, Entity target);
@Override @Override
@ -35,7 +29,6 @@ public abstract class Spell {
Spell spell = (Spell) o; Spell spell = (Spell) o;
if (cost != spell.cost) return false; if (cost != spell.cost) return false;
if (potency != spell.potency) return false;
return spellName.equals(spell.spellName); return spellName.equals(spell.spellName);
} }
@ -43,12 +36,11 @@ public abstract class Spell {
public int hashCode() { public int hashCode() {
int result = spellName.hashCode(); int result = spellName.hashCode();
result = 31 * result + cost; result = 31 * result + cost;
result = 31 * result + potency;
return result; return result;
} }
@Override @Override
public String toString() { public String toString() {
return spellName + " (Cost: " + cost + ", Potency: " + potency + ")"; return spellName + " (Cost: " + cost + ")";
} }
} }

View File

@ -2,6 +2,7 @@ package Entity;
import Action.Action; import Action.Action;
import Action.Actor; import Action.Actor;
import Combat.HasConditions;
import Combat.HasHealth; import Combat.HasHealth;
import Combat.HasMana; import Combat.HasMana;
import Combat.Spell; import Combat.Spell;
@ -13,13 +14,14 @@ import Inventory.HasSpellBook;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
public class Player extends Entity implements Movable, Actor, HasInventory, HasSpellBook, HasJob, HasHealth, HasMana { public class Player extends Entity implements Movable, Actor, HasInventory, HasSpellBook, HasJob, HasHealth, HasMana, HasConditions {
protected int health; protected int health;
protected int mana; protected int mana;
protected Job job; protected Job job;
protected Position position; protected Position position;
protected List<String> items = new LinkedList<>(); protected List<String> items = new LinkedList<>();
protected List<Spell> spells = new LinkedList<>(); protected List<Spell> spells = new LinkedList<>();
protected List<String> conditions = new LinkedList<>();
public Player(String name, Job job) { public Player(String name, Job job) {
super(name); super(name);
this.job = job; this.job = job;
@ -56,6 +58,15 @@ public class Player extends Entity implements Movable, Actor, HasInventory, HasS
public List<Spell> getSpellBook() {return spells;} public List<Spell> getSpellBook() {return spells;}
@Override
public List<String> getConditions() {return conditions;}
@Override
public void addCondition(String condition) {this.conditions.add(condition);}
@Override
public void removeCondition(String condition) {this.conditions.remove(condition);}
@Override @Override
public void performAction(Action action) { public void performAction(Action action) {
action.exectue(this); action.exectue(this);

View File

@ -1,23 +1,17 @@
import Action.Actor;
import Combat.HasMana;
import Combat.OffensiveDamageSpell; import Combat.OffensiveDamageSpell;
import Combat.Spell; import Combat.OffensiveStatusSpell;
import Entity.Entity;
import Entity.Player; import Entity.Player;
import Inventory.HasSpellBook;
import Job.Wizard; import Job.Wizard;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.List;
import java.util.Scanner; import java.util.Scanner;
import static org.junit.jupiter.api.Assertions.*;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import static org.mockito.Mockito.*;
public class InterestingTests { public class InterestingTests {
@ -42,12 +36,10 @@ public class InterestingTests {
player.getSpellBook().add(fireball); player.getSpellBook().add(fireball);
int initialMana = player.getMana(); int initialMana = player.getMana();
int initialHealth = player.getHealth();
wizard.castSpell(player); wizard.castSpell(player);
assertThat(player.getMana(), is(initialMana - fireball.getCost())); assertThat(player.getMana(), is(initialMana - fireball.getCost()));
assertThat(player.getHealth(), is(initialHealth - fireball.getPotency()));
} }
@Test @Test
@ -63,11 +55,50 @@ public class InterestingTests {
player.getSpellBook().add(fireball); player.getSpellBook().add(fireball);
int initialMana = player.getMana(); int initialMana = player.getMana();
int initialHealth = player.getHealth();
wizard.castSpell(player); wizard.castSpell(player);
assertThat(player.getMana(),is(initialMana)); assertThat(player.getMana(),is(initialMana));
assertThat(player.getHealth(),is(initialHealth)); }
@Test
public void testCastSpell_indexOutOfBounds() {
Scanner testScanner = new Scanner(new ByteArrayInputStream("2\n".getBytes()));
wizard = new Wizard(testScanner);
Player player = new Player("Brick", wizard);
player.setMana(50);
player.setHealth(100);
OffensiveDamageSpell fireball = new OffensiveDamageSpell("Fireball", 20, 15);
player.getSpellBook().add(fireball);
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
PrintStream originalOut = System.out;
System.setOut(new PrintStream(outContent));
try {
wizard.castSpell(player);
String output = outContent.toString();
assertTrue(output.contains("Invalid choice!"));
} finally {
System.setOut(originalOut);
}
}
@Test
public void condition_spell_adds_condition() {
Scanner testScanner = new Scanner(new ByteArrayInputStream("1\n".getBytes()));
wizard = new Wizard(testScanner);
Player player = new Player("Alfon", wizard);
player.setMana(50);
OffensiveStatusSpell poisonSpray = new OffensiveStatusSpell("poisonSpray", 20, "Poison");
player.getSpellBook().add(poisonSpray);
wizard.castSpell(player);
assertThat(player.getConditions().contains("Poison"), is(true));
} }
} }

View File

@ -4,6 +4,10 @@ import Combat.OffensiveDamageSpell;
import Entity.Player; import Entity.Player;
import Job.Wizard; import Job.Wizard;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
public class MagicSystemTest { public class MagicSystemTest {
@ -52,10 +56,22 @@ public class MagicSystemTest {
} }
@Test void cant_cast_spell_with_empty_spellbook(){ @Test void cant_cast_spell_with_empty_spellbook(){
var p = defaultPlayer(); ByteArrayOutputStream outContent = new ByteArrayOutputStream();
var job = new Wizard(); PrintStream OriginalOut = System.out;
p.learnJob(job); System.setOut(new PrintStream(outContent));
p.performAction(new CastAction());
try {
var p = defaultPlayer();
var job = new Wizard();
p.learnJob(job);
p.performAction(new CastAction());
String output = outContent.toString();
assertTrue(output.contains("You haven't learned any spells"));
} finally {
System.setOut(OriginalOut);
}
} }
}
}

View File

@ -21,18 +21,35 @@ class PlayerTest {
assertFalse(p.isAlive()); assertFalse(p.isAlive());
} }
@Test void get_health_returns_health() { @Test
void get_health_returns_health() {
var p = defaultPlayer(); var p = defaultPlayer();
p.setHealth(10); p.setHealth(10);
assertEquals(10, p.getHealth()); assertEquals(10, p.getHealth());
} }
@Test void get_mana_returns_mana() { @Test
void get_mana_returns_mana() {
var p = defaultPlayer(); var p = defaultPlayer();
p.setMana(10); p.setMana(10);
assertEquals(10, p.getMana()); assertEquals(10, p.getMana());
} }
@Test
void get_conditions_returns_conditions() {
var p = defaultPlayer();
p.addCondition("Poison");
assertTrue(p.getConditions().contains("Poison"));
}
@Test
void remove_condition_removes_condition() {
var p = defaultPlayer();
p.addCondition("Poison");
p.removeCondition("Poison");
assertFalse(p.getConditions().contains("Poison"));
}
@Test @Test
public void can_change_position() { public void can_change_position() {
var p = defaultPlayer(); var p = defaultPlayer();

View File

@ -1,4 +1,5 @@
import Combat.OffensiveDamageSpell; import Combat.OffensiveDamageSpell;
import Combat.OffensiveStatusSpell;
import Combat.Spell; import Combat.Spell;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -9,6 +10,7 @@ public class SpellTest {
private Spell defaultSpell() { private Spell defaultSpell() {
return new OffensiveDamageSpell("fireball", 20, 40); return new OffensiveDamageSpell("fireball", 20, 40);
} }
private Spell statusSpell() {return new OffensiveStatusSpell("poisonSpray", 20, "Poison");}
@Test @Test
void setSpellNameOnCreation(){ void setSpellNameOnCreation(){
@ -25,6 +27,12 @@ public class SpellTest {
@Test @Test
void setPotencyOnCreation() { void setPotencyOnCreation() {
var spell = defaultSpell(); var spell = defaultSpell();
assertEquals(40, spell.getPotency(), "spell potency should have been set"); assertEquals(40, ((OffensiveDamageSpell) spell).getPotency(), "spell potency should have been set");
}
@Test
void setConditionOnCreation() {
var spell = statusSpell();
assertEquals("Poison", ((OffensiveStatusSpell) spell).getStatus(), "spell status should have been set");
} }
} }