Coverage Summary for Class: Card01 (it.polimi.ingsw.Model)
Class |
Class, %
|
Method, %
|
Branch, %
|
Line, %
|
Card01 |
100%
(1/1)
|
100%
(5/5)
|
86,4%
(19/22)
|
93,3%
(28/30)
|
1 package it.polimi.ingsw.Model;
2
3 import it.polimi.ingsw.Exceptions.Container.EmptyContainerException;
4 import it.polimi.ingsw.Exceptions.Input.GenericInputValidationException;
5 import it.polimi.ingsw.Exceptions.Input.InputValidationException;
6 import it.polimi.ingsw.Exceptions.Input.InvalidElementException;
7 import it.polimi.ingsw.Exceptions.Operation.FailedOperationException;
8 import it.polimi.ingsw.Logger;
9 import it.polimi.ingsw.Misc.OptionalValue;
10 import it.polimi.ingsw.Model.Enums.PawnColour;
11 import it.polimi.ingsw.Model.Enums.StateType;
12
13 import java.io.Serial;
14 import java.util.ArrayList;
15 import java.util.Arrays;
16 import java.util.List;
17
18
19 /**
20 * Character Card#1
21 * In setup, draw 4 Students and place them on this card. <br>
22 * EFFECT: Take 1 Student from this card and place it on
23 * an Island of your choice. Then, draw a new Student from the Bag and place it on this card.
24 */
25
26 public class Card01 extends StatefulEffect {
27 @Serial
28 private static final long serialVersionUID = 103L; // convention: 1 for model, (01 -> 99) for objects
29 private final PawnColour[] students = new PawnColour[4]; // array containing card's pawns
30
31 public Card01(Model ctx) {
32 super(1, 1, StateType.PAWNCOLOUR, ctx);
33 for (int i = 0; i < 4; i++) {
34 try {
35 this.students[i] = ctx.getMutableStudentBag().extract();
36 } catch (EmptyContainerException e) {
37 // should never happen
38 Logger.severe("student bag was found empty while adding a student to Card01. Critical, unrecoverable, error");
39 throw new RuntimeException(e);
40 }
41 }
42 }
43
44 /**
45 * Get card's content
46 *
47 * @return List of Objects with pawns (Can be cast to {@link PawnColour})
48 */
49 public List<Object> getState() {
50 return new ArrayList<>(Arrays.asList(students));
51 }
52
53 /**
54 * Get card's stateType
55 *
56 * @return card's stateType
57 */
58 public StateType getStateType() {
59 return stateType;
60 }
61
62 /**
63 * Refer to: {@link CharacterCard#overridableCheckInput(CharacterCardInput)} for further information
64 *
65 * @param input CharacterCardInput should contain:
66 * <ul>
67 * <li>A valid island's ID </li>
68 * <li>a valid PawnColour from card</li>
69 * </ul>
70 */
71 @Override
72 public OptionalValue<InputValidationException> overridableCheckInput(CharacterCardInput input) {
73 //check if input contains a valid island
74 if (input.getTargetIsland().isEmpty()) {
75 return OptionalValue.of(new InvalidElementException("Target Island"));
76 }
77 //check if input contains a valid pawnColour
78 if (input.getTargetPawn().isEmpty()) {
79 return OptionalValue.of(new InvalidElementException("Target Pawn Colour"));
80 }
81 Island ti = input.getTargetIsland().get();
82 if (ti.getId() < 0 || ti.getId() >= 12) {
83 return OptionalValue.of(new InvalidElementException("Target Island")); // target ti out of bounds for id
84 }
85 if (!this.context.getMutableIslandField().getMutableIslands().contains(ti)) {
86 return OptionalValue.of(new InvalidElementException("Target Island")); // target ti not in field
87 } // note: if island is in field then the island must also be in a group, due to how islandfield works.
88 // find if the target pawn colour is present in the card's stored pawn
89 if (Arrays.stream(this.students).noneMatch(cell -> cell == input.getTargetPawn().get())) {
90 return OptionalValue.of(new InvalidElementException("Target Pawn Colour"));
91 }
92 //if StudentBag is empty then the card could not be filled anymore
93 if (context.getMutableStudentBag().getSize() == 0) {
94 return OptionalValue.of(new GenericInputValidationException("Student Bag", "is empty"));
95 }
96 return OptionalValue.empty();
97 }
98
99 /**
100 * Refer to: {@link CharacterCard#unsafeApplyEffect(CharacterCardInput)} for further information
101 */
102 @Override
103 protected void unsafeApplyEffect(CharacterCardInput input) throws Exception {
104 PawnColour movedPawn = input.getTargetPawn().get();
105 // add target pawn to island
106 input.getTargetIsland().get().addStudent(movedPawn);
107 // find first occurrence of same target pawn in card state and swap it with a new pawn
108 for (int i = 0; i < 4; i++) {
109 if (this.students[i] == movedPawn) {
110 this.students[i] = context.getMutableStudentBag().extract();
111 return; // repeat this action only once per loop
112 }
113 }
114 throw new FailedOperationException("Card01.unsafeApplyEffect", "Target pawn was not contained in card's state");
115 }
116
117 }