mirror of
https://gitlab.com/arnekeller/kit-programmieren-ws1920-final2.git
synced 2024-11-27 18:55:54 +00:00
Move item building and dice roll logic out of CardGame
This commit is contained in:
parent
fe77053ac9
commit
cc4e75f64e
@ -39,6 +39,21 @@ public enum Card implements RequireDice {
|
||||
*/
|
||||
THUNDERSTORM;
|
||||
|
||||
/**
|
||||
* Return value indicating that the player successfully fought against an animal.
|
||||
*
|
||||
* @see #activate(CardGame, int, int)
|
||||
* @see CardCategory#ANIMAL
|
||||
*/
|
||||
public static final String SURVIVED = "survived";
|
||||
/**
|
||||
* Return value indicating that the player lost against an animal.
|
||||
*
|
||||
* @see #activate(CardGame, int, int)
|
||||
* @see CardCategory#ANIMAL
|
||||
*/
|
||||
public static final String LOSE = "lose";
|
||||
|
||||
/**
|
||||
* Activate this card. Behaviour depends on the {@link #category category} of this card.
|
||||
*
|
||||
@ -50,7 +65,7 @@ public enum Card implements RequireDice {
|
||||
game.givePlayerCard(this);
|
||||
break;
|
||||
case ANIMAL: // animal cards trigger an encounter
|
||||
game.startEncounter(this);
|
||||
game.startDiceRoll(this);
|
||||
break;
|
||||
case CATASTROPHE:
|
||||
game.deletePlayerResources();
|
||||
@ -61,6 +76,24 @@ public enum Card implements RequireDice {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String activate(CardGame game, int diceSize, int roll) throws LogicException {
|
||||
if (!this.minimumDiceRollNeeded().isPresent()) {
|
||||
throw new IllegalStateException("can not process dice roll");
|
||||
} else if (this.diceSizeNeeded().get() != diceSize) {
|
||||
throw new LogicException("unexpected dice size");
|
||||
} else if (roll > diceSize || roll < 1) {
|
||||
throw new LogicException("impossible roll");
|
||||
}
|
||||
|
||||
if (roll + game.getFightingBonus() >= this.minimumDiceRollNeeded().get()) {
|
||||
return SURVIVED;
|
||||
} else {
|
||||
game.deletePlayerResources();
|
||||
return LOSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the category of this card.
|
||||
*
|
||||
|
@ -28,29 +28,6 @@ public class CardGame {
|
||||
* @see #build(Item)
|
||||
*/
|
||||
public static final String OK = "OK";
|
||||
/**
|
||||
* Return value indicating that the player won.
|
||||
*
|
||||
* @see #build(Item)
|
||||
* @see #rollDice(int, int)
|
||||
* @see ItemCategory#ESCAPE
|
||||
*/
|
||||
public static final String WIN = "win";
|
||||
/**
|
||||
* Return value indicating that the player successfully fought against an animal.
|
||||
*
|
||||
* @see #rollDice(int, int)
|
||||
* @see CardCategory#ANIMAL
|
||||
*/
|
||||
public static final String SURVIVED = "survived";
|
||||
/**
|
||||
* Return value indicating that the player lost against an animal or failed to escape.
|
||||
*
|
||||
* @see #rollDice(int, int)
|
||||
* @see CardCategory#ANIMAL
|
||||
* @see ItemCategory#ESCAPE
|
||||
*/
|
||||
public static final String LOSE = "lose";
|
||||
|
||||
/**
|
||||
* Card stack used.
|
||||
@ -120,16 +97,16 @@ public class CardGame {
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a new encounter. {@link #rollDice} has to be used next.
|
||||
* Wait for a dice roll to activate the specified object. {@link #rollDice} has to be used next.
|
||||
*
|
||||
* @param card (animal) card
|
||||
* @param requireDice something that requires a dice roll
|
||||
*/
|
||||
public void startEncounter(Card card) {
|
||||
if (!card.diceSizeNeeded().isPresent()) {
|
||||
throw new IllegalArgumentException("card does not require dice");
|
||||
public void startDiceRoll(RequireDice requireDice) {
|
||||
if (!requireDice.diceSizeNeeded().isPresent()) {
|
||||
throw new IllegalArgumentException("object does not require dice");
|
||||
}
|
||||
requireDice = card;
|
||||
phase = CardGame.Phase.ENCOUNTER;
|
||||
this.requireDice = requireDice;
|
||||
phase = Phase.AWAITING_DICE_ROLL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -156,51 +133,38 @@ public class CardGame {
|
||||
*
|
||||
* @param size dice size
|
||||
* @param roll dice result
|
||||
* @return result of the throw ({@link #SURVIVED survived}, {@link #LOSE lose} or {@link #WIN win})
|
||||
* @return result of the dice roll (see {@link RequireDice#activate})
|
||||
* @throws LogicException if not expecting dice roll or dice roll is invalid
|
||||
*/
|
||||
public String rollDice(int size, int roll) throws LogicException {
|
||||
if (requireDice == null) {
|
||||
throw new LogicException("not expecting dice roll");
|
||||
}
|
||||
// compare with currently expected dice
|
||||
final int sizeNeeded = requireDice.diceSizeNeeded().get();
|
||||
final int minimumNeeded = requireDice.minimumDiceRollNeeded().get();
|
||||
if (sizeNeeded != size) {
|
||||
} else if (requireDice.diceSizeNeeded().get() != size) {
|
||||
throw new LogicException("unexpected dice size");
|
||||
} else if (roll > sizeNeeded || roll < 1) {
|
||||
} else if (roll > size || roll < 1) {
|
||||
throw new LogicException("impossible roll");
|
||||
}
|
||||
// no longer waiting for dice roll
|
||||
// leave encounter/endeavor phase
|
||||
phase = Phase.SCAVENGE;
|
||||
// compute the result of the dice roll
|
||||
final String result = requireDice.activate(this, size, roll);
|
||||
// no longer waiting
|
||||
requireDice = null;
|
||||
if (phase == Phase.ENCOUNTER) {
|
||||
// calculate fighting bonus, selecting the most powerful item the player owns
|
||||
final int bonus = inventory.getItems().stream().mapToInt(Item::fightingBonus).max().orElse(0);
|
||||
phase = Phase.SCAVENGE;
|
||||
if (roll + bonus >= minimumNeeded) {
|
||||
return SURVIVED;
|
||||
} else {
|
||||
inventory.clearResources();
|
||||
return LOSE;
|
||||
}
|
||||
} else { // attempting to escape
|
||||
// do not remove item used to escape
|
||||
if (roll >= minimumNeeded) {
|
||||
endGame();
|
||||
phase = Phase.WON;
|
||||
return WIN;
|
||||
} else {
|
||||
phase = Phase.SCAVENGE;
|
||||
return LOSE;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the player's fighting bonus against {@link CardCategory#ANIMAL animals}
|
||||
*/
|
||||
public int getFightingBonus() {
|
||||
return inventory.getItems().stream().mapToInt(Item::fightingBonus).max().orElse(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to build the specified item.
|
||||
*
|
||||
* @param item item to build
|
||||
* @return building result ({@link #OK} or {@link #WIN win}, or null if item can not be built
|
||||
* @return building result (see {@link Item#activate(CardGame)}), or null if item can not be built
|
||||
* @throws LogicException if in wrong phase or item already built
|
||||
*/
|
||||
public String build(Item item) throws LogicException {
|
||||
@ -214,22 +178,18 @@ public class CardGame {
|
||||
if (!inventory.build(item)) {
|
||||
throw new LogicException("can not build item: missing resources/items");
|
||||
}
|
||||
if (item.category() == ItemCategory.ESCAPE) {
|
||||
if (item.diceSizeNeeded().isPresent()) {
|
||||
// player needs to roll dice to escape
|
||||
requireDice = item;
|
||||
phase = Phase.ENDEAVOR;
|
||||
} else {
|
||||
// player won
|
||||
endGame();
|
||||
phase = Phase.WON;
|
||||
return WIN;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
return item.activate(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* End the game by forcing the player to win.
|
||||
*/
|
||||
public void winGame() {
|
||||
endGame();
|
||||
phase = Phase.WON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this game ever received a {@link #start start} command.
|
||||
*
|
||||
@ -254,10 +214,12 @@ public class CardGame {
|
||||
* @see #gameLost
|
||||
*/
|
||||
private void checkLost() {
|
||||
// can not draw new cards
|
||||
if (cardStack != null && cardStack.isEmpty()
|
||||
// obviously, player can only lose after starting the game
|
||||
if (gameStarted()
|
||||
// can not draw new cards
|
||||
&& (cardStack == null || cardStack.isEmpty())
|
||||
// can not roll dice
|
||||
&& phase != Phase.ENCOUNTER && phase != Phase.ENDEAVOR
|
||||
&& phase != Phase.AWAITING_DICE_ROLL
|
||||
// can not build item
|
||||
&& Arrays.stream(Item.values()).noneMatch(inventory::canBuild)
|
||||
&& phase != Phase.WON) {
|
||||
@ -359,19 +321,12 @@ public class CardGame {
|
||||
*/
|
||||
SCAVENGE,
|
||||
/**
|
||||
* Player has to fight an animal.
|
||||
* Player has to fight an animal or attempt to escape using {@link #rollDice(int, int)}.
|
||||
*
|
||||
* @see #rollDice
|
||||
* @see CardCategory#ANIMAL
|
||||
*/
|
||||
ENCOUNTER,
|
||||
/**
|
||||
* Player is attempting to escape.
|
||||
*
|
||||
* @see #rollDice
|
||||
* @see ItemCategory#ESCAPE
|
||||
*/
|
||||
ENDEAVOR,
|
||||
AWAITING_DICE_ROLL,
|
||||
/**
|
||||
* Player won.
|
||||
*/
|
||||
|
@ -49,6 +49,65 @@ public enum Item implements RequireDice {
|
||||
*/
|
||||
BALLON;
|
||||
|
||||
/**
|
||||
* Return value indicating success.
|
||||
*
|
||||
* @see #activate
|
||||
*/
|
||||
public static final String OK = "OK";
|
||||
/**
|
||||
* Return value indicating that the player won.
|
||||
*
|
||||
* @see #activate
|
||||
* @see ItemCategory#ESCAPE
|
||||
*/
|
||||
public static final String WIN = "win";
|
||||
/**
|
||||
* Return value indicating that the player failed to escape.
|
||||
*
|
||||
* @see #activate(CardGame, int, int)
|
||||
* @see ItemCategory#ESCAPE
|
||||
*/
|
||||
public static final String LOSE = "lose";
|
||||
|
||||
/**
|
||||
* Activate this item on the specified game.
|
||||
*
|
||||
* @param game card game to use
|
||||
* @return result (either {@link #OK} or {@link #WIN})
|
||||
*/
|
||||
public String activate(CardGame game) {
|
||||
if (this.category() == ItemCategory.ESCAPE) {
|
||||
if (this.diceSizeNeeded().isPresent()) {
|
||||
// player needs to roll dice to escape
|
||||
game.startDiceRoll(this);
|
||||
} else {
|
||||
// player won
|
||||
game.winGame();
|
||||
return WIN;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String activate(CardGame game, int diceSize, int roll) throws LogicException {
|
||||
if (!this.minimumDiceRollNeeded().isPresent()) {
|
||||
throw new IllegalStateException("can not process dice roll");
|
||||
} else if (this.diceSizeNeeded().get() != diceSize) {
|
||||
throw new LogicException("unexpected dice size");
|
||||
} else if (roll > diceSize || roll < 1) {
|
||||
throw new LogicException("impossible roll");
|
||||
}
|
||||
|
||||
if (roll >= this.minimumDiceRollNeeded().get()) {
|
||||
game.winGame();
|
||||
return WIN;
|
||||
} else {
|
||||
return LOSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resources needed to build this item, in no particular order.
|
||||
*
|
||||
|
@ -22,4 +22,15 @@ public interface RequireDice {
|
||||
* @return minimum dice roll needed to use this item (empty if dice not required)
|
||||
*/
|
||||
Optional<Integer> minimumDiceRollNeeded();
|
||||
|
||||
/**
|
||||
* Activate this object in a game, if the dice roll is good enough.
|
||||
*
|
||||
* @param game card game to use
|
||||
* @param diceSize size of the dice rolled
|
||||
* @param rolled result of the dice roll
|
||||
* @return activation result
|
||||
* @throws LogicException if dice roll is incorrect
|
||||
*/
|
||||
String activate(CardGame game, int diceSize, int rolled) throws LogicException;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user