Skip to content

Method: toFieldState(boolean)

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.moves.impl;
20:
21: import de.fhdw.gaming.core.domain.GameException;
22: import de.fhdw.gaming.ipspiel24.VierConnects.core.domain.VierConnectsDirection;
23: import de.fhdw.gaming.ipspiel24.VierConnects.core.domain.VierConnectsField;
24: import de.fhdw.gaming.ipspiel24.VierConnects.core.domain.VierConnectsFieldState;
25: import de.fhdw.gaming.ipspiel24.VierConnects.core.domain.VierConnectsPlayer;
26: import de.fhdw.gaming.ipspiel24.VierConnects.core.domain.VierConnectsPosition;
27: import de.fhdw.gaming.ipspiel24.VierConnects.core.domain.VierConnectsState;
28:
29: /**
30: * Represents a move which places a mark on a field on the board.
31: * <p>
32: * Note that this move is only allowed if the field is empty.
33: */
34: final class VierConnectsPlaceMarkMove extends AbstractVierConnectsMove {
35:
36: /**
37: * {@code true} if a cross is to be made, {@code false} chooses a nought instead.
38: */
39: private final boolean cross;
40: /**
41: * The position of where the player wants to place the token.
42: */
43: private final int columnNr;
44:
45:
46: /**
47: * Creates an {@link VierConnectsPlaceMarkMove} object.
48: *
49: * @param cross {@code true} if a cross is to be made, {@code false} chooses a nought instead.
50: * @param column The column of the field having its
51: * state changed. It must point to an empty field.
52: */
53: VierConnectsPlaceMarkMove(final boolean cross, final int column) {
54: this.cross = cross;
55: this.columnNr = column;
56:
57: }
58:
59: /**
60: * Returns {@code true} if a cross is to be made, and {@code false} if a nought is to be made instead.
61: */
62: boolean isCross() {
63: return this.cross;
64: }
65:
66: /**
67: * Returns the position of the token placed on the board.
68: */
69: int getColoumnNr() {
70: return this.columnNr;
71: }
72:
73: /**
74: * Returns the next token position.
75: * @param state
76: */
77: VierConnectsPosition getNewTokenPosition(final VierConnectsState state) throws GameException {
78: final int columnNumber = this.getColoumnNr();
79: final VierConnectsPosition tokenPosition = VierConnectsPosition.of(0, columnNumber);
80:
81: VierConnectsField fieldToPlaceOn = state.getBoard().getFieldAt(tokenPosition);
82:
83: if (!fieldToPlaceOn.getState().equals(VierConnectsFieldState.EMPTY)) {
84: throw new GameException(
85: String.format(
86: "Player cannot make %s on field at %s as the column is already full.",
87: toFieldState(this.cross),
88: this.getColoumnNr()));
89: }
90:
91: VierConnectsField nextPossibleField;
92: final int nrOfRows = state.getBoard().getRowSize();
93: for (int rowIndex = 0; rowIndex < nrOfRows; rowIndex++) {
94:
95: if (fieldToPlaceOn.hasNeighbour(VierConnectsDirection.SOUTH)) {
96: nextPossibleField = fieldToPlaceOn.getNeighbour(VierConnectsDirection.SOUTH);
97: } else {
98: return fieldToPlaceOn.getPosition();
99: }
100:
101: if (!nextPossibleField.getState().equals(VierConnectsFieldState.EMPTY)) {
102: return fieldToPlaceOn.getPosition();
103: } else {
104: fieldToPlaceOn = nextPossibleField;
105: }
106: }
107:
108:
109: throw new GameException("You should not be here. The placing has gone very wrong.");
110: }
111:
112:
113: @Override
114: public void applyTo(final VierConnectsState state, final VierConnectsPlayer player) throws GameException {
115: if (this.cross != player.isUsingCrosses()) {
116: throw new GameException(
117: String.format(
118: "Player %s cannot make %s on field at %s.",
119: player,
120: toFieldState(this.cross),
121: this.getColoumnNr()));
122: }
123:
124: final VierConnectsPosition realNewPosition = getNewTokenPosition(state);
125:
126: state.getBoard().getFieldAt(realNewPosition).changeState(toFieldState(this.cross));
127: state.moveCompleted();
128: }
129:
130: @Override
131: public String toString() {
132: return String.format("%s on field at %s", toFieldState(this.cross), this.columnNr);
133: }
134:
135: /**
136: * Maps a cross/nought boolean to a target {@link VierConnectsFieldState}.
137: *
138: * @param cross {@code true} for a cross and {@code false} for a nought.
139: */
140: private static VierConnectsFieldState toFieldState(final boolean cross) {
141:• return cross ? VierConnectsFieldState.CROSS : VierConnectsFieldState.NOUGHT;
142: }
143: }