monster #20
@@ -14,8 +14,8 @@ public enum MovementPatterns {
|
|||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Position> findLegalDestinations(Position position) {
|
public List<Position> findLegalDestinations(Position position) {
|
||||||
Set<Position> legalDestinations = new HashSet<>();
|
List<Position> legalDestinations = new ArrayList<>();
|
||||||
int x = position.x();
|
int x = position.x();
|
||||||
int y = position.y();
|
int y = position.y();
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public class Shade extends Monster implements CanMove, CanAttack {
|
|||||||
private List<Position> validDestinations = new ArrayList<>();
|
private List<Position> validDestinations = new ArrayList<>();
|
||||||
|
|
||||||
public Shade() {
|
public Shade() {
|
||||||
super(MAX_HEALTH, MAX_ENERGY, Monster.DEFAULT_POSITION);
|
super(MAX_HEALTH, MAX_ENERGY, DEFAULT_POSITION);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Shade(int health, int energy, Position position) {
|
public Shade(int health, int energy, Position position) {
|
||||||
@@ -120,7 +120,7 @@ public class Shade extends Monster implements CanMove, CanAttack {
|
|||||||
validDestinations.clear();
|
validDestinations.clear();
|
||||||
for (MovementPatterns move : MOVES) {
|
for (MovementPatterns move : MOVES) {
|
||||||
if (move.cost <= energy) {
|
if (move.cost <= energy) {
|
||||||
Set<Position> destinations = move.findLegalDestinations(position);
|
List<Position> destinations = move.findLegalDestinations(position);
|
||||||
for (Position destination : destinations) {
|
for (Position destination : destinations) {
|
||||||
if (noPlayerIsAtPosition(destination, world)) {
|
if (noPlayerIsAtPosition(destination, world)) {
|
||||||
validDestinations.add(destination);
|
validDestinations.add(destination);
|
||||||
|
|||||||
@@ -1,8 +1,154 @@
|
|||||||
package Monster;
|
package Monster;
|
||||||
|
|
||||||
public abstract class Troll extends Monster implements CanMove, CanAttack {
|
import Entity.Entity;
|
||||||
|
import Entity.Player;
|
||||||
|
import Entity.Position;
|
||||||
|
import World.World;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
|
public class Troll extends Monster implements CanMove, CanAttack {
|
||||||
|
public static final List<Biomes> HABITAT = Collections.unmodifiableList(Arrays.asList(Biomes.FOREST, Biomes.MOUNTAIN));
|
||||||
|
public static final List<MovementPatterns> MOVES = Collections.unmodifiableList(Arrays.asList(MovementPatterns.ONE_DIAGONAL_STEP, MovementPatterns.TWO_STEPS_IN_STRAIGHT_LINE));
|
||||||
|
public static final int MAX_HEALTH = 80;
|
||||||
|
public static final int MAX_ENERGY = 100;
|
||||||
|
|
||||||
|
private static final int HEALTH_PER_HEAL = 6;
|
||||||
|
private static final int ENERGY_COST_PER_HEAL = 3;
|
||||||
|
|
||||||
|
private Random random = new Random();
|
||||||
|
private List<Position> validDestinations = new ArrayList<>();
|
||||||
|
|
||||||
public Troll() {
|
public Troll() {
|
||||||
super(0,0,Monster.DEFAULT_POSITION);
|
super(MAX_HEALTH, MAX_ENERGY, DEFAULT_POSITION);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Troll(int health, int energy, Position position) {
|
||||||
|
super(health, energy, position);
|
||||||
|
enforceHealthValueBoundries();
|
||||||
|
enforceEnergyValueBoundries();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean heal() {
|
||||||
|
if (isDead()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (health == MIN_HEALTH) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (health == MAX_HEALTH) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (energy < ENERGY_COST_PER_HEAL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
health += HEALTH_PER_HEAL;
|
||||||
|
energy -= ENERGY_COST_PER_HEAL;
|
||||||
|
enforceHealthValueBoundries();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean takeDamage(int amount) {
|
||||||
|
if (amount < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (health - amount <= 0) {
|
||||||
|
kill();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
health =- amount;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean performAttack(Attacks attack, Player player) {
|
||||||
|
if (isDead()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (attack.cost > energy) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean move(World world) {
|
||||||
|
if (isDead()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
updateDestinations(position, world);
|
||||||
|
if (validDestinations.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
position = validDestinations.get(random.nextInt(validDestinations.size()));
|
||||||
|
updateDestinations(position, world);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean moveTo(Position destination, World world) {
|
||||||
|
if (isDead()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (playerIsAtPosition(destination, world)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
position = destination;
|
||||||
|
updateDestinations(position, world);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDestinations(Position position, World world) {
|
||||||
|
validDestinations.clear();
|
||||||
|
for (MovementPatterns move : MOVES) {
|
||||||
|
if (move.cost <= energy) {
|
||||||
|
List<Position> destinations = move.findLegalDestinations(position);
|
||||||
|
for (Position destination : destinations) {
|
||||||
|
if (noPlayerIsAtPosition(destination, world)) {
|
||||||
|
validDestinations.add(destination);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean playerIsAtPosition(Position position, World world) {
|
||||||
|
List<Entity> entitiesAtPosition = world.getPositionEntityMap().get(position);
|
||||||
|
if (isNull(entitiesAtPosition)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (Entity entity : entitiesAtPosition) {
|
||||||
|
if (entity instanceof Player) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean noPlayerIsAtPosition(Position position, World world) {
|
||||||
|
return !playerIsAtPosition(position, world);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enforceHealthValueBoundries() {
|
||||||
|
if (health > MAX_HEALTH) {
|
||||||
|
health = MAX_HEALTH;
|
||||||
|
}
|
||||||
|
else if (health <= MIN_HEALTH) {
|
||||||
|
health = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enforceEnergyValueBoundries() {
|
||||||
|
if (energy > MAX_ENERGY) {
|
||||||
|
energy = MAX_ENERGY;
|
||||||
|
}
|
||||||
|
else if (energy < MIN_ENERGY) {
|
||||||
|
energy = MIN_ENERGY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,14 +108,17 @@ public class MonsterTest {
|
|||||||
assertThat(shade.performAttack(Attacks.CHILL, mockPlayer), equalTo(false));
|
assertThat(shade.performAttack(Attacks.CHILL, mockPlayer), equalTo(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*@Test
|
@Test
|
||||||
void only_moves_within_energy_budget_are_performed() {
|
void only_moves_within_energy_budget_are_performed() {
|
||||||
Troll troll = new Troll(Troll.MAX_HEALTH)
|
Troll troll = new Troll(Troll.MAX_HEALTH, 1, Troll.DEFAULT_POSITION);
|
||||||
}*/
|
List<Position> movesWithinBudget = MovementPatterns.ONE_DIAGONAL_STEP.findLegalDestinations(troll.getPosition());
|
||||||
|
troll.move(mockWorld);
|
||||||
|
|
||||||
|
assertThat(movesWithinBudget, hasItem(troll.getPosition()));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void use_of_attack_not_in_arsenal_is_rejected() {
|
void use_of_attack_not_in_arsenal_is_rejected() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user