Skip to content

Daan's assignment. Committing on his behalf #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package nl.rabobank.pirates.handlers;

import static nl.rabobank.pirates.model.battle.TurnActionFactory.makeFaintAnimation;

import java.util.ArrayList;
import java.util.List;

import nl.rabobank.pirates.helper.TurnActionHelper;
import nl.rabobank.pirates.model.battle.TurnAction;
import nl.rabobank.pirates.model.battle.TurnActionFactory;
import nl.rabobank.pirates.model.common.Pokemon;
import nl.rabobank.pirates.model.move.Move;

public abstract class BaseDamageMoveHandler extends BaseMoveHandler {

public List<TurnAction> handleMove(Move pokemonMove, Pokemon attackingPokemon, Pokemon defendingPokemon,
boolean isOwnPokemonAttacking) {

final List<TurnAction> actions = new ArrayList<>();

actions.add(TurnActionFactory.makePokemonUsedMove(attackingPokemon.getName().toUpperCase(),
pokemonMove.getName(), TurnActionHelper.getSubject(isOwnPokemonAttacking)));

if (!willMoveHit(pokemonMove, attackingPokemon, defendingPokemon)) {
actions.add(TurnActionFactory.makeTextOnly("The attack missed!"));
return actions;
}

// TODO calculate critical
// TODO calculate weakness/strenghts

actions.addAll(processNumberOfHits(pokemonMove, defendingPokemon, isOwnPokemonAttacking,
determineDamage(pokemonMove, attackingPokemon, defendingPokemon)));

actions.add(processFainting(defendingPokemon, isOwnPokemonAttacking));

actions.add(processStatusEffect(defendingPokemon, pokemonMove, isOwnPokemonAttacking));

return actions;
}

protected abstract int determineDamage(Move pokemonMove, Pokemon attackingPokemon, Pokemon defendingPokemon);

private List<TurnAction> processNumberOfHits(final Move pokemonMove, final Pokemon defendingPokemon,
final boolean isOwnPokemonAttacking, final int damage) {
final List<TurnAction> actions = new ArrayList<>();

int numberHits = calculationService.calculateNumberOfHitTimes(pokemonMove.getHitTimes());

for (int x = 0; x < numberHits; x++) {

defendingPokemon.dealDamage(damage);

actions.add(TurnActionFactory.makeDamageOnlyAnimation(damage,
TurnActionHelper.getSubject(isOwnPokemonAttacking)));
}

if (numberHits > 1) {
actions.add(TurnActionFactory.makeTextHitXTimes(numberHits));
}

return actions;
}

public TurnAction processFainting(final Pokemon defendingPokemon, boolean isOwnPokemonAttacking) {

if (checkIfDefendingPokemonFainted(defendingPokemon)) {
return makeFaintAnimation(defendingPokemon.getName().toUpperCase(),
TurnActionHelper.getSubject(isOwnPokemonAttacking));
}

return null;
}

public boolean checkIfDefendingPokemonFainted(final Pokemon defendingPokemon) {
return defendingPokemon.getCurrentHp() <= 0;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package nl.rabobank.pirates.handlers;

import static nl.rabobank.pirates.model.move.StatusEffect.Condition.CONFUSED;
import static nl.rabobank.pirates.model.move.StatusEffect.Condition.SLEEP;

import org.springframework.beans.factory.annotation.Autowired;

import nl.rabobank.pirates.helper.TurnActionHelper;
import nl.rabobank.pirates.model.battle.TurnAction;
import nl.rabobank.pirates.model.battle.TurnActionFactory;
import nl.rabobank.pirates.model.common.Pokemon;
import nl.rabobank.pirates.model.common.Stat;
import nl.rabobank.pirates.model.move.Move;
import nl.rabobank.pirates.service.CalculationService;

/**
* Class containing methods for shared functionality across MoveHandlers.
*
* @author Daan
*
*/
public class BaseMoveHandler {

@Autowired
protected CalculationService calculationService;

protected boolean willMoveHit(Move move, Pokemon attackingPokemon, Pokemon defendingPokemon) {
int moveAccuracy = move.getAccuracy();
int pokemonAccuracy = attackingPokemon.getStatAmount(Stat.ACCURACY);

return calculationService.calculateAccuracyAndRollIfMoveHits(pokemonAccuracy, moveAccuracy);
}

protected TurnAction processStatusEffect(final Pokemon defendingPokemon, final Move pokemonMove,
boolean isOwnPokemonAttacking) {

if (pokemonMove.getStatusEffect() == null) {
return null;
}

boolean isSuccessful = calculationService.isRollSuccessful(pokemonMove.getStatusEffect().getChance());
if (!isSuccessful) {
return null;
}

boolean canApplyStatusEffect = defendingPokemon.addStatusEffect(pokemonMove.getStatusEffect().getCondition());

if (!canApplyStatusEffect) {
return TurnActionFactory.makeTextOnly("The attack missed!");
}
if (SLEEP.equals(pokemonMove.getStatusEffect().getCondition())) {
defendingPokemon.putPokemonToSleep(calculationService.randomSleepOrConfusedTurns());
}
if (CONFUSED.equals(pokemonMove.getStatusEffect().getCondition())) {
defendingPokemon.confusePokemon(calculationService.randomSleepOrConfusedTurns());
}

return TurnActionFactory.makeStatusEffect(defendingPokemon.getName(),
pokemonMove.getStatusEffect().getCondition(), TurnActionHelper.getSubject(isOwnPokemonAttacking));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package nl.rabobank.pirates.handlers;

import java.util.List;

import nl.rabobank.pirates.model.battle.TurnAction;
import nl.rabobank.pirates.model.common.Pokemon;
import nl.rabobank.pirates.model.move.DamageClass;
import nl.rabobank.pirates.model.move.Move;

public interface MoveHandler {

public List<TurnAction> handleMove(final Move pokemonMove, final Pokemon attackingPokemon, final Pokemon defendingPokemon, boolean isOwnPokemonAttacking);

public DamageClass getClassType();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package nl.rabobank.pirates.handlers;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import nl.rabobank.pirates.model.move.DamageClass;

@Component
public class MoveHandlerFactory {

private static Map<DamageClass, MoveHandler> handlerMap;

@Autowired
public MoveHandlerFactory(List<MoveHandler> handlers) {
handlerMap = handlers.stream().collect(Collectors.toUnmodifiableMap(MoveHandler::getClassType, Function.identity()));
}

public static <T> MoveHandler getHandler(DamageClass damageClass) {
return Optional.ofNullable(handlerMap.get(damageClass)).orElseThrow(IllegalArgumentException::new);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package nl.rabobank.pirates.handlers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import nl.rabobank.pirates.model.common.Pokemon;
import nl.rabobank.pirates.model.move.DamageClass;
import nl.rabobank.pirates.model.move.Move;
import nl.rabobank.pirates.service.CalculationService;

@Component
public class PhysicalMoveHandler extends BaseDamageMoveHandler implements MoveHandler {

@Autowired
private CalculationService calculationService;

@Override
public DamageClass getClassType() {
return DamageClass.PHYSICAL;
}

@Override
public int determineDamage(Move pokemonMove, Pokemon attackingPokemon, Pokemon defendingPokemon) {
return calculationService.calculatePhysicalDamage(attackingPokemon, defendingPokemon, pokemonMove);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package nl.rabobank.pirates.handlers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import nl.rabobank.pirates.model.common.Pokemon;
import nl.rabobank.pirates.model.move.DamageClass;
import nl.rabobank.pirates.model.move.Move;
import nl.rabobank.pirates.service.CalculationService;

@Component
public class SpecialMoveHandler extends BaseDamageMoveHandler implements MoveHandler {

@Autowired
private CalculationService calculationService;

@Override
public DamageClass getClassType() {
return DamageClass.SPECIAL;
}

@Override
public int determineDamage(Move pokemonMove, Pokemon attackingPokemon, Pokemon defendingPokemon) {
return calculationService.calculateSpecialDamage(attackingPokemon, defendingPokemon, pokemonMove);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package nl.rabobank.pirates.handlers;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Component;

import nl.rabobank.pirates.helper.TurnActionHelper;
import nl.rabobank.pirates.model.battle.TurnAction;
import nl.rabobank.pirates.model.battle.TurnActionFactory;
import nl.rabobank.pirates.model.common.Pokemon;
import nl.rabobank.pirates.model.common.StatChange;
import nl.rabobank.pirates.model.common.StatMultiplier;
import nl.rabobank.pirates.model.move.DamageClass;
import nl.rabobank.pirates.model.move.Move;

@Component
public class StatusMoveHandler extends BaseMoveHandler implements MoveHandler {

@Override
public List<TurnAction> handleMove(Move pokemonMove, Pokemon attackingPokemon,
Pokemon defendingPokemon, boolean isOwnPokemonAttacking) {

final List<TurnAction> actions = new ArrayList<>();

actions.add(TurnActionFactory.makePokemonUsedMove(attackingPokemon.getName().toUpperCase(), pokemonMove.getName(), TurnActionHelper.getSubject(isOwnPokemonAttacking)));

if (!willMoveHit(pokemonMove, attackingPokemon, defendingPokemon)) {
actions.add(TurnActionFactory.makeTextOnly("The attack missed!"));
return actions;
}
actions.addAll(processMoveStatChanges(attackingPokemon, defendingPokemon, pokemonMove));

actions.add(processStatusEffect(defendingPokemon, pokemonMove, isOwnPokemonAttacking));

return actions;
}

private List<TurnAction> processMoveStatChanges(final Pokemon attackingPokemon, final Pokemon defendingPokemon,
final Move pokemonMove) {
final List<TurnAction> actions = new ArrayList<>();

for (StatChange statChange : pokemonMove.getStatChanges()) {

if (statChange.getChangeAmount() > 0) {

boolean wasModified = attackingPokemon.addStatMultiplier(StatMultiplier.builder()
.stat(statChange.getStat()).stageModification(statChange.getChangeAmount()).build());

if (wasModified) {
actions.add(TurnActionFactory.makeTextStatRose(attackingPokemon.getName(),
statChange.getStat().getLabel()));

} else {
actions.add(TurnActionFactory.makeTextStatWontRaiseHigher(attackingPokemon.getName(),
statChange.getStat().getLabel()));

}

} else {
boolean wasModified = defendingPokemon.addStatMultiplier(StatMultiplier.builder()
.stat(statChange.getStat()).stageModification(statChange.getChangeAmount()).build());
if (wasModified) {

actions.add(TurnActionFactory.makeTextStatFell(defendingPokemon.getName(),
statChange.getStat().getLabel()));
} else {
actions.add(TurnActionFactory.makeTextStatWontFallLower(defendingPokemon.getName(),
statChange.getStat().getLabel()));
}
}

}

return actions;
}

@Override
public DamageClass getClassType() {
return DamageClass.STATUS;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package nl.rabobank.pirates.helper;

import nl.rabobank.pirates.model.battle.TurnAction;

public class TurnActionHelper {

// TODO move to TurnAction class?
public static TurnAction.Subject getSubject(final boolean isOwnPokemonAttacking) {
TurnAction.Subject subjectAttackingPokemon = isOwnPokemonAttacking ? TurnAction.Subject.OWN
: TurnAction.Subject.ENEMY;
return subjectAttackingPokemon;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
import nl.rabobank.pirates.model.move.StatusEffect;

@Builder(toBuilder = true, access = AccessLevel.PACKAGE)
@Getter
@ToString
public class TurnAction {
private TurnActionType type;
private StatusEffect.Condition statusEffectCondition;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

import static nl.rabobank.pirates.model.move.StatusEffect.Condition.BURN;
import static nl.rabobank.pirates.model.move.StatusEffect.Condition.POISON;
Expand All @@ -32,12 +34,16 @@ public class BattleService {

@Getter
private Pokemon currentEnemyPokemon;

private AtomicInteger counter = new AtomicInteger(0);

public TurnInformation executeTurn() {
if (currentOwnPokemon == null || currentEnemyPokemon == null) return null;

List<TurnAction> actions = new ArrayList<>();

System.out.println("Calls to battleService: " + counter.incrementAndGet());

int ownPokemonMoveIndex = rollService.getRandomValue(0, currentOwnPokemon.getMoves().size());
int enemyPokemonMoveIndex = rollService.getRandomValue(0, currentEnemyPokemon.getMoves().size());
Move ownPokemonMove = currentOwnPokemon.getMoves().get(ownPokemonMoveIndex);
Expand Down Expand Up @@ -74,7 +80,16 @@ public TurnInformation executeTurn() {

actions.add(TurnActionFactory.makeWhatWillPokemonDo(currentOwnPokemon.getName()));
}


//TODO: once adding of actions has been properly refactored (see TurnInformationService) this can be removed
actions.removeIf(Objects::isNull);

//Below is used for debugging purposes and would not be part of PR
System.out.println("Number of actions: " + actions.size());
for (TurnAction turnAction : actions) {
System.out.println(turnAction);
}

return TurnInformation.builder().actions(actions).build();
}

Expand Down
Loading