-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
49 changed files
with
4,859 additions
and
107 deletions.
There are no files selected for viewing
635 changes: 619 additions & 16 deletions
635
src/main/java/it/polimi/ingsw/server/model/ActionPhase.java
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 102 additions & 0 deletions
102
src/main/java/it/polimi/ingsw/server/model/CentaurAndKnight.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package it.polimi.ingsw.server.model; | ||
|
||
import it.polimi.ingsw.server.model.enums.CharacterType; | ||
import it.polimi.ingsw.server.model.exceptions.InvalidCharacterParameterException; | ||
|
||
import java.util.Objects; | ||
|
||
/** | ||
* Represents the Centaur character card. | ||
* | ||
* @author Alexandru Gabriel Bradatan | ||
*/ | ||
class CentaurAndKnight extends Character { | ||
private final Behaviour behaviour; | ||
|
||
/** | ||
* Creates a new CentaurAndKnight card. If {@code behaviour} is {@link Behaviour#CENTAUR} the card will | ||
* act as a Centaur card. Otherwise, it will act a Knight card. | ||
* | ||
* @param behaviour an enum describing what this card will act as | ||
*/ | ||
CentaurAndKnight(Behaviour behaviour) { | ||
super(behaviour == Behaviour.CENTAUR ? CharacterType.CENTAUR : CharacterType.KNIGHT); | ||
this.behaviour = behaviour; | ||
} | ||
|
||
/** | ||
* Returns a shallow copy of the given card | ||
* | ||
* @param old the Centaur to copy | ||
* @throws IllegalArgumentException if {@code old} is null | ||
*/ | ||
private CentaurAndKnight(CentaurAndKnight old) { | ||
super(old); | ||
this.behaviour = old.behaviour; | ||
} | ||
|
||
/** | ||
* Abstract method that returns a shallow copy of the current object. | ||
* | ||
* @return returns a shallow copy of the current object. | ||
*/ | ||
@Override | ||
Character shallowCopy() { | ||
return new CentaurAndKnight(this); | ||
} | ||
|
||
/** | ||
* If acting as Centaur: Ignore the additional influence of towers during influence calculation. This effect requires no steps. | ||
* If acting as Knight: Ignore the additional influence of towers during influence calculation. This effect requires no steps. | ||
* | ||
* @param phase the {@link ActionPhase} the card's effect has been called from | ||
* @param steps an array of {@link CharacterStep} configuring the effect | ||
* @return a Tuple containing the updated ActionPhase and the updated Character | ||
* @throws IllegalArgumentException if {@code phase} or {@code steps} or are null | ||
* @throws InvalidCharacterParameterException if any of the parameters in {@code steps} is formatted incorrectly | ||
*/ | ||
@Override | ||
Tuple<ActionPhase, Character> doEffect(ActionPhase phase, CharacterStep[] steps) throws InvalidCharacterParameterException { | ||
return super.doEffect(phase, steps) | ||
.map(t -> { | ||
ActionPhase newPhase = t.getFirst(); | ||
Player p = newPhase.getCurrentPlayer(); | ||
CentaurAndKnight c = (CentaurAndKnight) t.getSecond(); | ||
if (c.behaviour == Behaviour.CENTAUR) { | ||
newPhase = newPhase.setInfluenceCalculator( | ||
new IgnoreTowersInfluenceDecorator(newPhase.getInfluenceCalculator())); | ||
} else { | ||
newPhase = newPhase.setInfluenceCalculator( | ||
new ExtraPointsInfluenceDecorator(newPhase.getInfluenceCalculator(), p, 2)); | ||
} | ||
return new Tuple<>(newPhase, c); | ||
}); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
if (!super.equals(o)) return false; | ||
CentaurAndKnight that = (CentaurAndKnight) o; | ||
return behaviour == that.behaviour; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
@Override | ||
public int hashCode() { | ||
return Objects.hash(super.hashCode(), behaviour); | ||
} | ||
|
||
/** | ||
* Enum for signaling what this card will act as | ||
*/ | ||
public enum Behaviour { | ||
CENTAUR, KNIGHT | ||
} | ||
} |
176 changes: 166 additions & 10 deletions
176
src/main/java/it/polimi/ingsw/server/model/Character.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,187 @@ | ||
package it.polimi.ingsw.server.model; | ||
|
||
import it.polimi.ingsw.server.model.enums.CharacterType; | ||
import it.polimi.ingsw.server.model.exceptions.InvalidCharacterParameterException; | ||
|
||
import java.util.Objects; | ||
|
||
/** | ||
* Represents an abstract character card. Each card has one "character", a cost that goes up by 1 after the first | ||
* use and two hooks into respectively the {@link PreparePhase} and {@link ActionPhase} of the game. This base class has | ||
* only default implementations that either do nothing, or throw an exception. Please see all subclasses for different | ||
* card effects. | ||
* | ||
* @author Alexandru Gabriel Bradatan | ||
* @see ActionPhase | ||
* @see PreparePhase | ||
*/ | ||
abstract class Character { | ||
private final CharacterType type; | ||
/** | ||
* This card's character. Represented as a {@link CharacterType} enum. | ||
*/ | ||
private final CharacterType characterType; | ||
|
||
/** | ||
* The base cost of the card. | ||
*/ | ||
private final int initialCost; | ||
|
||
/** | ||
* Indicates if a card has been used at least once. | ||
*/ | ||
private boolean used; | ||
|
||
/** | ||
* Base constructor. Sets up only the card's initial cost and character | ||
* | ||
* @param characterType this card's character | ||
* @throws IllegalArgumentException if {@code characterType} is null | ||
*/ | ||
Character(CharacterType characterType) { | ||
if (characterType == null) throw new IllegalArgumentException("characterType shouldn't be null"); | ||
this.characterType = characterType; | ||
this.initialCost = characterType.getInitialCost(); | ||
used = false; | ||
} | ||
|
||
Character(CharacterType type) { | ||
this.type = type; | ||
/** | ||
* Returns a copy of the passed Character | ||
* | ||
* @param old Character to copy | ||
* @throws IllegalArgumentException if {@code old} is null | ||
*/ | ||
Character(Character old) { | ||
if (old == null) throw new IllegalArgumentException("old shouldn't be null"); | ||
this.characterType = old.characterType; | ||
this.initialCost = this.characterType.getInitialCost(); | ||
this.used = old.used; | ||
} | ||
|
||
/** | ||
* Abstract method that returns a shallow copy of the current object. | ||
* | ||
* @return returns a shallow copy of the current object. | ||
*/ | ||
abstract Character shallowCopy(); | ||
|
||
/** | ||
* Getter for this card's CharacterType | ||
* | ||
* @return this card's CharacterType | ||
*/ | ||
CharacterType getCharacterType() { | ||
return type; | ||
return characterType; | ||
} | ||
|
||
/** | ||
* Getter for this card's actual cost. This means that this will return the card's initial cost if this card hasn't | ||
* been used before and the initial cos +1 otherwise. | ||
* | ||
* @return this card's actual cost | ||
*/ | ||
int getCost() { | ||
return type.getInitialCost(); | ||
return used ? initialCost + 1 : initialCost; | ||
} | ||
|
||
Tuple<ActionPhase, Character> doEffect(ActionPhase phase, CharacterStep[] params) { | ||
/** | ||
* Default implementation for the {@link PreparePhase} hook. This implementation only checks for nullity, so if | ||
* subclasses want to not rewrite it themselves, they can call this implementation. | ||
* | ||
* @param phase the {@link PreparePhase} the card's hook has been called from | ||
* @return a Tuple containing the updated PreparePhase and the updated Character | ||
* @throws IllegalArgumentException if {@code phase} is null | ||
*/ | ||
Tuple<PreparePhase, Character> doPrepare(PreparePhase phase) { | ||
if (phase == null) throw new IllegalArgumentException("phase shouldn't be null"); | ||
return new Tuple<>(phase, this); | ||
} | ||
|
||
Character pushBlock(BlockCard c) { | ||
throw new UnsupportedOperationException(); | ||
/** | ||
* Default implementation for the card's effect. This implementation only marks the card as used and checks for | ||
* nullity of parameters. All subclasses should call this implementation if they are overriding this method. | ||
* <p> | ||
* The number of steps and the parameters of each are detailed in each subclass. To signal that the player has not | ||
* provided any steps, an empty array should be passed. | ||
* | ||
* @param phase the {@link ActionPhase} the card's effect has been called from | ||
* @param steps an array of {@link CharacterStep} configuring the effect | ||
* @return a Tuple containing the updated ActionPhase and the updated Character | ||
* @throws IllegalArgumentException if {@code phase} or {@code steps} or are null | ||
* @throws InvalidCharacterParameterException if any of the parameters in {@code steps} is formatted incorrectly | ||
*/ | ||
Tuple<ActionPhase, Character> doEffect(ActionPhase phase, CharacterStep[] steps) throws InvalidCharacterParameterException { | ||
if (phase == null) throw new IllegalArgumentException("phase shouldn't be null"); | ||
if (steps == null) throw new IllegalArgumentException("steps shouldn't be null"); | ||
Character t = this.shallowCopy(); | ||
t.used = true; | ||
return new Tuple<>(phase, t); | ||
} | ||
|
||
/** | ||
* Helper for validating parameters in subclasses: check for nullity and length of the step array | ||
* | ||
* @param phase the ActionPhase to check | ||
* @param steps the CharacterStep array to check | ||
* @param minimumSteps the minimum number of steps that {@code steps} should have | ||
* @throws IllegalArgumentException in case of nullity | ||
* @throws InvalidCharacterParameterException if the length of {@code steps} is less than {@code minimumSteps} | ||
*/ | ||
void checkEffectParameters(ActionPhase phase, CharacterStep[] steps, int minimumSteps) throws InvalidCharacterParameterException { | ||
if (phase == null) throw new IllegalArgumentException("phase shouldn't be null"); | ||
if (steps == null) throw new IllegalArgumentException("steps shouldn't be null"); | ||
if (steps.length < minimumSteps) | ||
throw new InvalidCharacterParameterException("Too few parameters: at least 1 expected"); | ||
} | ||
|
||
/** | ||
* Returns the number of {@link BlockCard} available on this card. This implementation always returns 0 since | ||
* block related methods always throw an exception. | ||
* | ||
* @return the number of {@link BlockCard} available on this card | ||
*/ | ||
int getNumOfBlocks() { | ||
return 0; | ||
} | ||
|
||
/** | ||
* Adds the given {@link BlockCard} to the internal store. This implementation of the method throws a | ||
* {@link UnsupportedOperationException}. | ||
* | ||
* @param block the {@link BlockCard} to add to the store | ||
* @return the updated Character | ||
* @throws UnsupportedOperationException always | ||
*/ | ||
Character pushBlock(BlockCard block) { | ||
throw new UnsupportedOperationException("this card doesn't receive blocks"); | ||
} | ||
|
||
/** | ||
* Pops a {@link BlockCard} from the internal store and returns it. This implementation of the method throws a | ||
* {@link UnsupportedOperationException}. | ||
* | ||
* @return a Tuple containing the new Character and a BlockCard. | ||
* @throws UnsupportedOperationException always | ||
*/ | ||
Tuple<Character, BlockCard> popBlock() { | ||
throw new UnsupportedOperationException(); | ||
throw new UnsupportedOperationException("this card doesn't produce blocks"); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
Character character = (Character) o; | ||
return initialCost == character.initialCost && used == character.used && characterType == character.characterType; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
@Override | ||
public int hashCode() { | ||
return Objects.hash(characterType, initialCost, used); | ||
} | ||
} | ||
} |
Oops, something went wrong.