Skip to content

Method: equals(Object)

1: package de.fhdw.gaming.ipspiel22.vierGewinnt.domain.impl;
2:
3: import java.util.ArrayList;
4: import java.util.Collections;
5: import java.util.LinkedHashMap;
6: import java.util.List;
7: import java.util.Map;
8: import java.util.Objects;
9: import java.util.Set;
10:
11: import de.fhdw.gaming.core.domain.GameException;
12: import de.fhdw.gaming.core.domain.PlayerState;
13: import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.VGBoard;
14: import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.VGField;
15: import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.VGFieldState;
16: import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.VGPlayer;
17: import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.VGState;
18:
19: /**
20: * Implements {@link VGState}.
21: */
22: @SuppressWarnings("PMD.GodClass")
23: public class VGStateImpl implements VGState {
24:
25: /**
26: * The board.
27: */
28: private final VGBoard board;
29: /**
30: * The first player.
31: */
32: private final VGPlayer redPlayer;
33: /**
34: * The second player.
35: */
36: private final VGPlayer yellowPlayer;
37: /**
38: * The current player.
39: */
40: private VGPlayer currentPlayer;
41:
42: /**
43: * Creates a Vier gewinnt state.
44: *
45: * @param board A board.s
46: * @param redPlayer The first player.
47: * @param yellowPlayer The second player.
48: * @param redIsNext Is red next.
49: * @throws GameException if the state cannot be created according to the rules of the game.
50: */
51: public VGStateImpl(final VGBoard board, final VGPlayer redPlayer, final VGPlayer yellowPlayer,
52: final boolean redIsNext)
53: throws GameException {
54:
55: this.board = Objects.requireNonNull(board, "board");
56: this.redPlayer = Objects.requireNonNull(redPlayer, "redPlayerBuilder");
57: this.yellowPlayer = Objects.requireNonNull(yellowPlayer, "yellowPlayerBuilder");
58: this.currentPlayer = redIsNext ? this.redPlayer : this.yellowPlayer;
59:
60: if (!this.redPlayer.isUsingRedChips()) {
61: throw new IllegalArgumentException(
62: String.format("Red player %s does not use red chips.", this.redPlayer));
63: }
64: if (this.yellowPlayer.isUsingRedChips()) {
65: throw new IllegalArgumentException(
66: String.format("Yellow player %s does not use yellow tokens.", this.yellowPlayer));
67: }
68: }
69:
70: /**
71: * Creates a Vier gewinnt state by copying an existing one.
72: *
73: * @param source The state to copy.
74: */
75: VGStateImpl(final VGStateImpl source) {
76: this.board = source.board.deepCopy();
77: this.redPlayer = source.redPlayer.deepCopy();
78: this.yellowPlayer = source.yellowPlayer.deepCopy();
79: this.currentPlayer = source.isRedPlayerCurrent() ? this.redPlayer : this.yellowPlayer;
80: }
81:
82: @Override
83: public String toString() {
84: return String.format(
85: "VGState[board=%s, redPlayer=%s, yellowPlayer=%s, currentPlayer=%s]",
86: this.board,
87: this.redPlayer,
88: this.yellowPlayer,
89: this.currentPlayer.isUsingRedChips() ? VGFieldState.RED : VGFieldState.YELLOW);
90: }
91:
92: @Override
93: public boolean equals(final Object obj) {
94:• if (obj instanceof VGStateImpl) {
95: final VGStateImpl other = (VGStateImpl) obj;
96:• return this.board.equals(other.board)
97:• && this.redPlayer.equals(other.redPlayer)
98:• && this.yellowPlayer.equals(other.yellowPlayer)
99:• && this.isRedPlayerCurrent() == other.isRedPlayerCurrent();
100: }
101: return false;
102: }
103:
104: @Override
105: public VGState deepCopy() {
106: return new VGStateImpl(this);
107: }
108:
109: @Override
110: public int hashCode() {
111: return Objects.hash(this.board, this.redPlayer, this.yellowPlayer, this.isRedPlayerCurrent());
112: }
113:
114: @Override
115: public Map<String, VGPlayer> getPlayers() {
116: final Map<String, VGPlayer> result = new LinkedHashMap<>();
117: result.put(this.redPlayer.getName(), this.redPlayer);
118: result.put(this.yellowPlayer.getName(), this.yellowPlayer);
119: return result;
120: }
121:
122: @Override
123: public Set<VGPlayer> computeNextPlayers() {
124: return Collections.singleton(this.currentPlayer);
125: }
126:
127: @Override
128: public void nextTurn() {
129: final List<VGField> allFields = new ArrayList<>();
130: this.getBoard().getFields().forEach(allFields::addAll);
131:
132: if (allFields.stream().noneMatch(vgField -> vgField.getState().equals(VGFieldState.EMPTY))) {
133:
134: if (this.checkWinner(this.currentPlayer)) {
135: this.currentPlayer.setState(PlayerState.WON);
136: this.getOtherPlayer().setState(PlayerState.LOST);
137: } else {
138: this.gameOver();
139: }
140: } else if (this.checkWinner(this.currentPlayer)) {
141: this.currentPlayer.setState(PlayerState.WON);
142: this.getOtherPlayer().setState(PlayerState.LOST);
143: }
144: this.currentPlayer = this.getOtherPlayer();
145: }
146:
147: /**
148: * Returns boolean, if Player has won.
149: *
150: * @param player The current player.
151: */
152: public boolean checkWinner(final VGPlayer player) {
153: VGFieldState state = VGFieldState.YELLOW;
154: if (player.isUsingRedChips()) {
155: state = VGFieldState.RED;
156: }
157: return this.checkVertical(state);
158: }
159:
160: /**
161: * Returns boolean, if Player has won.
162: *
163: * @param state The chips color of the current player.
164: */
165: private Boolean checkVertical(final VGFieldState state) {
166: for (int i = 0; i < this.board.getColumns(); i++) {
167: for (int j = 0; j < 3; j++) {
168: if (this.board.getFields().get(i).get(j).getState().equals(state)
169: && this.board.getFields().get(i).get(j + 1).getState().equals(state)
170: && this.board.getFields().get(i).get(j + 2).getState().equals(state)
171: && this.board.getFields().get(i).get(j + 3).getState().equals(state)) {
172: return true;
173: }
174: }
175: }
176: return this.checkHorizontal(state);
177: }
178:
179: /**
180: * Returns boolean, if Player has won.
181: *
182: * @param state The chips color of the current player.
183: */
184: private Boolean checkHorizontal(final VGFieldState state) {
185: for (int i = 0; i < this.board.getRows(); i++) { // Für Zeilen
186: for (int j = 0; j < 4; j++) { // Für Spalten
187: if (this.board.getFields().get(j).get(i).getState().equals(state)
188: && this.board.getFields().get(j + 1).get(i).getState().equals(state)
189: && this.board.getFields().get(j + 2).get(i).getState().equals(state)
190: && this.board.getFields().get(j + 3).get(i).getState().equals(state)) {
191: return true;
192: }
193: }
194: }
195: return this.checkDiagonalLeftToRight(state);
196: }
197:
198: /**
199: * Returns boolean, if Player has won.
200: *
201: * @param state The chips color of the current player.
202: */
203: private Boolean checkDiagonalLeftToRight(final VGFieldState state) {
204: for (int i = 0; i < 3; i++) {
205: for (int j = 0; j < 4; j++) {
206: if (this.board.getFields().get(j).get(i).getState().equals(state)
207: && this.board.getFields().get(j + 1).get(i + 1).getState().equals(state)
208: && this.board.getFields().get(j + 2).get(i + 2).getState().equals(state)
209: && this.board.getFields().get(j + 3).get(i + 3).getState().equals(state)) {
210: return true;
211: }
212: }
213: }
214: return this.checkDiagonalRightToLeft(state);
215: }
216:
217: /**
218: * Returns boolean, if Player has won.
219: *
220: * @param state The chips color of the current player.
221: */
222: private Boolean checkDiagonalRightToLeft(final VGFieldState state) {
223: for (int i = 0; i < 3; i++) {
224: for (int j = 3; j < 7; j++) {
225: if (this.board.getFields().get(j).get(i).getState().equals(state)
226: && this.board.getFields().get(j - 1).get(i + 1).getState().equals(state)
227: && this.board.getFields().get(j - 2).get(i + 2).getState().equals(state)
228: && this.board.getFields().get(j - 3).get(i + 3).getState().equals(state)) {
229: return true;
230: }
231: }
232: }
233: return false;
234: }
235:
236: @Override
237: public VGBoard getBoard() {
238: return this.board;
239: }
240:
241: @Override
242: public VGPlayer getRedPlayer() {
243: return this.redPlayer;
244: }
245:
246: @Override
247: public VGPlayer getYellowPlayer() {
248: return this.yellowPlayer;
249: }
250:
251: @Override
252: public VGPlayer getCurrentPlayer() {
253: return this.currentPlayer;
254: }
255:
256: /**
257: * Returns the currently inactive player.
258: */
259: private VGPlayer getOtherPlayer() {
260: if (this.isRedPlayerCurrent()) {
261: return this.yellowPlayer;
262: }
263: return this.redPlayer;
264: }
265:
266: /**
267: * Returns id the current player is the red Player.
268: */
269: private boolean isRedPlayerCurrent() {
270: return this.currentPlayer.equals(this.redPlayer);
271: }
272:
273: @Override
274: public void gameOver() {
275: this.redPlayer.setState(PlayerState.DRAW);
276: this.yellowPlayer.setState(PlayerState.DRAW);
277: }
278: }