Skip to content

Package: VierConnectsStateImpl

VierConnectsStateImpl

nameinstructionbranchcomplexitylinemethod
VierConnectsStateImpl(VierConnectsBoard, VierConnectsPlayer, VierConnectsPlayer, boolean)
M: 0 C: 86
100%
M: 0 C: 8
100%
M: 0 C: 5
100%
M: 0 C: 13
100%
M: 0 C: 1
100%
VierConnectsStateImpl(VierConnectsStateImpl)
M: 0 C: 30
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
computeNextPlayers()
M: 0 C: 12
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
deepCopy()
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
equals(Object)
M: 2 C: 33
94%
M: 1 C: 9
90%
M: 1 C: 5
83%
M: 1 C: 5
83%
M: 0 C: 1
100%
gameOver(VierConnectsFieldState)
M: 12 C: 33
73%
M: 1 C: 3
75%
M: 1 C: 3
75%
M: 2 C: 11
85%
M: 0 C: 1
100%
getBoard()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getCrossesPlayer()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getCurrentPlayer()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getNoughtsPlayer()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getOtherPlayer()
M: 0 C: 9
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
getPlayers()
M: 0 C: 22
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
hashCode()
M: 0 C: 25
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
isCrossesPlayerCurrent()
M: 0 C: 9
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
moveCompleted()
M: 0 C: 31
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 9
100%
M: 0 C: 1
100%
nextTurn()
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
toString()
M: 1 C: 29
97%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 0 C: 2
100%
M: 0 C: 1
100%

Coverage

1: /*
2: * Copyright © 2021-2023 Fachhochschule für die Wirtschaft (FHDW) Hannover
3: *
4: * This file is part of ipspiel24-VierConnects-core.
5: *
6: * ipspiel24-VierConnects-core is free software: you can redistribute it and/or modify it under
7: * the terms of the GNU General Public License as published by the Free Software
8: * Foundation, either version 3 of the License, or (at your option) any later
9: * version.
10: *
11: * ipspiel24-VierConnects-core is distributed in the hope that it will be useful, but WITHOUT
12: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14: * details.
15: *
16: * You should have received a copy of the GNU General Public License along with
17: * ipspiel24-VierConnects-core. If not, see <http://www.gnu.org/licenses/>.
18: */
19: package de.fhdw.gaming.ipspiel24.VierConnects.core.domain.impl;
20:
21: import java.util.Collections;
22: import java.util.LinkedHashMap;
23: import java.util.Map;
24: import java.util.Objects;
25: import java.util.Set;
26:
27: import de.fhdw.gaming.core.domain.GameException;
28: import de.fhdw.gaming.core.domain.PlayerState;
29: import de.fhdw.gaming.ipspiel24.VierConnects.core.domain.VierConnectsBoard;
30: import de.fhdw.gaming.ipspiel24.VierConnects.core.domain.VierConnectsField;
31: import de.fhdw.gaming.ipspiel24.VierConnects.core.domain.VierConnectsFieldState;
32: import de.fhdw.gaming.ipspiel24.VierConnects.core.domain.VierConnectsPlayer;
33: import de.fhdw.gaming.ipspiel24.VierConnects.core.domain.VierConnectsPosition;
34: import de.fhdw.gaming.ipspiel24.VierConnects.core.domain.VierConnectsRow;
35: import de.fhdw.gaming.ipspiel24.VierConnects.core.domain.VierConnectsState;
36:
37: /**
38: * Implements {@link VierConnectsState}.
39: */
40: @SuppressWarnings("PMD.GodClass")
41: final class VierConnectsStateImpl implements VierConnectsState {
42:
43: /**
44: * The board.
45: */
46: private final VierConnectsBoard board;
47:
48: /**
49: * The player using crosses.
50: */
51: private final VierConnectsPlayer crossesPlayer;
52:
53: /**
54: * The player using noughts.
55: */
56: private final VierConnectsPlayer noughtsPlayer;
57:
58: /**
59: * The current player.
60: */
61: private VierConnectsPlayer currentPlayer;
62:
63: /**
64: * Creates an Vier Connects state.
65: *
66: * @param board The board.
67: * @param crossesPlayer The player using crosses.
68: * @param noughtsPlayer The player using noughts.
69: * @param crossesIsNext {@code true} if the player using crosses is next, else the player using noughts is next.
70: * @throws GameException if the state cannot be created according to the rules of the game.
71: */
72: VierConnectsStateImpl(final VierConnectsBoard board, final VierConnectsPlayer crossesPlayer,
73: final VierConnectsPlayer noughtsPlayer, final boolean crossesIsNext) throws GameException {
74:
75: this.board = Objects.requireNonNull(board, "board");
76: this.crossesPlayer = Objects.requireNonNull(crossesPlayer, "crossesPlayer");
77: this.noughtsPlayer = Objects.requireNonNull(noughtsPlayer, "noughtsPlayer");
78:• this.currentPlayer = crossesIsNext ? this.crossesPlayer : this.noughtsPlayer;
79:
80:• if (!this.crossesPlayer.isUsingCrosses()) {
81: throw new IllegalArgumentException(String.format("Player %s does not use crosses.", this.crossesPlayer));
82: }
83:• if (this.noughtsPlayer.isUsingCrosses()) {
84: throw new IllegalArgumentException(String.format("Player %s does not use noughts.", this.noughtsPlayer));
85: }
86:• if (this.crossesPlayer.getName().equals(this.noughtsPlayer.getName())) {
87: throw new IllegalArgumentException(
88: String.format("Both players have the same name '%s'.", this.crossesPlayer.getName()));
89: }
90: }
91:
92: /**
93: * Creates an VierConnects state by copying an existing one.
94: *
95: * @param source The state to copy.
96: */
97: VierConnectsStateImpl(final VierConnectsStateImpl source) {
98: this.board = source.board.deepCopy();
99: this.crossesPlayer = source.crossesPlayer.deepCopy();
100: this.noughtsPlayer = source.noughtsPlayer.deepCopy();
101:• this.currentPlayer = source.isCrossesPlayerCurrent() ? this.crossesPlayer : this.noughtsPlayer;
102: }
103:
104: @Override
105: public String toString() {
106: return String.format(
107: "VierConnectsState[board=\n%s, crossesPlayer=%s, noughtsPlayer=%s, currentPlayer=%s]",
108: this.board,
109: this.crossesPlayer,
110: this.noughtsPlayer,
111:• this.currentPlayer.isUsingCrosses() ? VierConnectsFieldState.CROSS : VierConnectsFieldState.NOUGHT);
112: }
113:
114: @Override
115: public boolean equals(final Object obj) {
116:• if (obj instanceof VierConnectsStateImpl) {
117: final VierConnectsStateImpl other = (VierConnectsStateImpl) obj;
118:• return this.board.equals(other.board) && this.crossesPlayer.equals(other.crossesPlayer)
119:• && this.noughtsPlayer.equals(other.noughtsPlayer)
120:• && this.isCrossesPlayerCurrent() == other.isCrossesPlayerCurrent();
121: }
122: return false;
123: }
124:
125: @Override
126: public int hashCode() {
127: return Objects.hash(this.board, this.crossesPlayer, this.noughtsPlayer, this.isCrossesPlayerCurrent());
128: }
129:
130: @Override
131: public VierConnectsStateImpl deepCopy() {
132: return new VierConnectsStateImpl(this);
133: }
134:
135: @Override
136: public Map<String, VierConnectsPlayer> getPlayers() {
137: final Map<String, VierConnectsPlayer> result = new LinkedHashMap<>();
138: result.put(this.crossesPlayer.getName(), this.crossesPlayer);
139: result.put(this.noughtsPlayer.getName(), this.noughtsPlayer);
140: return result;
141: }
142:
143: @Override
144: public VierConnectsBoard getBoard() {
145: return this.board;
146: }
147:
148: @Override
149: public VierConnectsPlayer getCrossesPlayer() {
150: return this.crossesPlayer;
151: }
152:
153: @Override
154: public VierConnectsPlayer getNoughtsPlayer() {
155: return this.noughtsPlayer;
156: }
157:
158: @Override
159: public VierConnectsPlayer getCurrentPlayer() {
160: return this.currentPlayer;
161: }
162:
163:
164: @Override
165: public void moveCompleted() {
166: final Set<VierConnectsRow> winningRows = this.board.getRowsWithFourMarked();
167:• if (!winningRows.isEmpty()) {
168: final VierConnectsFieldState rowState = winningRows.iterator().next().getState().orElseThrow();
169: this.gameOver(rowState);
170: } else {
171: final Map<VierConnectsPosition,
172: ? extends VierConnectsField> emptyFields = this.board.getFieldsBeing(VierConnectsFieldState.EMPTY);
173:• if (emptyFields.isEmpty()) {
174: this.gameOver(VierConnectsFieldState.EMPTY);
175: }
176: }
177: }
178:
179: @Override
180: public Set<VierConnectsPlayer> computeNextPlayers() {
181:• if (this.currentPlayer.getState().equals(PlayerState.PLAYING)) {
182: return Collections.singleton(this.currentPlayer);
183: }
184: return Collections.emptySet();
185: }
186:
187: @Override
188: public void nextTurn() {
189: this.currentPlayer = this.getOtherPlayer();
190: }
191:
192: /**
193: * Returns the currently inactive player.
194: */
195: private VierConnectsPlayer getOtherPlayer() {
196:• if (this.isCrossesPlayerCurrent()) {
197: return this.noughtsPlayer;
198: }
199: return this.crossesPlayer;
200: }
201:
202: /**
203: * Returns {@code true} iff the current player uses crosses.
204: */
205: @SuppressWarnings("PMD.CompareObjectsWithEquals")
206: private boolean isCrossesPlayerCurrent() {
207:• return this.currentPlayer == this.crossesPlayer;
208: }
209:
210: /**
211: * Updates the player states after the game has finished.
212: *
213: * @param rowState The state of some uniformly marked row, or {@link VierConnectsFieldState#EMPTY} if no player has
214: * won
215: * the game yet and no empty fields have remained.
216: */
217: private void gameOver(final VierConnectsFieldState rowState) {
218:• switch (rowState) {
219: case CROSS:
220: this.crossesPlayer.setState(PlayerState.WON);
221: this.noughtsPlayer.setState(PlayerState.LOST);
222: break;
223: case NOUGHT:
224: this.crossesPlayer.setState(PlayerState.LOST);
225: this.noughtsPlayer.setState(PlayerState.WON);
226: break;
227: case EMPTY:
228: this.crossesPlayer.setState(PlayerState.DRAW);
229: this.noughtsPlayer.setState(PlayerState.DRAW);
230: break;
231: default:
232: throw new IllegalArgumentException(
233: String.format("VierConnectsState.gameOver() called with state %s.", rowState));
234: }
235: }
236: }