Skip to content

Package: TicTacToeGameBuilderFactoryImpl

TicTacToeGameBuilderFactoryImpl

nameinstructionbranchcomplexitylinemethod
TicTacToeGameBuilderFactoryImpl()
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
TicTacToeGameBuilderFactoryImpl(TicTacToeStrategyFactoryProvider)
M: 12 C: 21
64%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 2 C: 6
75%
M: 0 C: 1
100%
createGameBuilder(InputProvider)
M: 17 C: 132
89%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 2 C: 30
94%
M: 0 C: 1
100%
getMaximumNumberOfPlayers()
M: 2 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getMinimumNumberOfPlayers()
M: 0 C: 2
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getName()
M: 2 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getStrategies()
M: 6 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getStrategy(Map)
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%
initPlayerBuilder(TicTacToePlayerBuilder, Map)
M: 0 C: 13
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
requestPlayerData(InputProvider, String, Optional)
M: 0 C: 43
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 10
100%
M: 0 C: 1
100%

Coverage

1: /*
2: * Copyright © 2021 Fachhochschule für die Wirtschaft (FHDW) Hannover
3: *
4: * This file is part of ipspiel21-tictactoe-core.
5: *
6: * ipspiel21-tictactoe-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: * ipspiel21-tictactoe-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: * ipspiel21-tictactoe-core. If not, see <http://www.gnu.org/licenses/>.
18: */
19: package de.fhdw.gaming.ipspiel21.tictactoe.core.domain.impl;
20:
21: import java.util.ArrayList;
22: import java.util.LinkedHashSet;
23: import java.util.List;
24: import java.util.Map;
25: import java.util.Optional;
26: import java.util.Set;
27: import java.util.regex.Pattern;
28:
29: import de.fhdw.gaming.core.domain.GameBuilder;
30: import de.fhdw.gaming.core.domain.GameBuilderFactory;
31: import de.fhdw.gaming.core.domain.GameException;
32: import de.fhdw.gaming.core.domain.Strategy;
33: import de.fhdw.gaming.core.ui.InputProvider;
34: import de.fhdw.gaming.core.ui.InputProviderException;
35: import de.fhdw.gaming.core.ui.type.validator.MaxValueValidator;
36: import de.fhdw.gaming.core.ui.type.validator.MinValueValidator;
37: import de.fhdw.gaming.core.ui.type.validator.PatternValidator;
38: import de.fhdw.gaming.ipspiel21.tictactoe.core.domain.TicTacToeGameBuilder;
39: import de.fhdw.gaming.ipspiel21.tictactoe.core.domain.TicTacToeGameBuilderFactory;
40: import de.fhdw.gaming.ipspiel21.tictactoe.core.domain.TicTacToePlayerBuilder;
41: import de.fhdw.gaming.ipspiel21.tictactoe.core.domain.TicTacToeStrategy;
42: import de.fhdw.gaming.ipspiel21.tictactoe.core.domain.factory.TicTacToeDefaultStrategyFactoryProvider;
43: import de.fhdw.gaming.ipspiel21.tictactoe.core.domain.factory.TicTacToeStrategyFactory;
44: import de.fhdw.gaming.ipspiel21.tictactoe.core.domain.factory.TicTacToeStrategyFactoryProvider;
45: import de.fhdw.gaming.ipspiel21.tictactoe.core.moves.factory.TicTacToeMoveFactory;
46: import de.fhdw.gaming.ipspiel21.tictactoe.core.moves.impl.TicTacToeDefaultMoveFactory;
47:
48: /**
49: * Implements {@link TicTacToeGameBuilderFactory} by creating a Tic Tac Toe game builder.
50: */
51: public final class TicTacToeGameBuilderFactoryImpl implements TicTacToeGameBuilderFactory {
52:
53: /**
54: * The number of players.
55: */
56: private static final int NUMBER_OF_PLAYERS = 2;
57: /**
58: * Minimum number of rows (and columns) of the board.
59: */
60: private static final int MIN_BOARD_SIZE = 2;
61: /**
62: * Maximum number of rows (and columns) of the board.
63: */
64: private static final int MAX_BOARD_SIZE = 16;
65: /**
66: * Smallest allowed maximum computation time per move in seconds.
67: */
68: private static final int MIN_MAX_COMPUTATION_TIME_PER_MOVE = 1;
69: /**
70: * Largest allowed maximum computation time per move in seconds.
71: */
72: private static final int MAX_MAX_COMPUTATION_TIME_PER_MOVE = 3600;
73:
74: /**
75: * All available Tic Tac Toe strategies.
76: */
77: private final Set<TicTacToeStrategy> strategies;
78:
79: /**
80: * Creates an Tic Tac Toe game factory. Tic Tac Toe strategies are loaded by using the
81: * {@link java.util.ServiceLoader}.
82: * <p>
83: * This constructor is meant to be used by the {@link java.util.ServiceLoader}.
84: */
85: public TicTacToeGameBuilderFactoryImpl() {
86: this(new TicTacToeDefaultStrategyFactoryProvider());
87: }
88:
89: /**
90: * Creates an Tic Tac Toe game factory.
91: *
92: * @param strategyFactoryProvider The {@link TicTacToeStrategyFactoryProvider} for loading Tic Tac Toe strategies.
93: */
94: TicTacToeGameBuilderFactoryImpl(final TicTacToeStrategyFactoryProvider strategyFactoryProvider) {
95: final TicTacToeMoveFactory moveFactory = new TicTacToeDefaultMoveFactory();
96:
97: final List<TicTacToeStrategyFactory> factories = strategyFactoryProvider.getStrategyFactories();
98: this.strategies = new LinkedHashSet<>();
99:• for (final TicTacToeStrategyFactory factory : factories) {
100: this.strategies.add(factory.create(moveFactory));
101: }
102: }
103:
104: @Override
105: public String getName() {
106: return "TicTacToe";
107: }
108:
109: @Override
110: public int getMinimumNumberOfPlayers() {
111: return TicTacToeGameBuilderFactoryImpl.NUMBER_OF_PLAYERS;
112: }
113:
114: @Override
115: public int getMaximumNumberOfPlayers() {
116: return TicTacToeGameBuilderFactoryImpl.NUMBER_OF_PLAYERS;
117: }
118:
119: @Override
120: public List<? extends Strategy<?, ?, ?>> getStrategies() {
121: return new ArrayList<>(this.strategies);
122: }
123:
124: @Override
125: public TicTacToeGameBuilder createGameBuilder(final InputProvider inputProvider) throws GameException {
126: try {
127: final TicTacToeGameBuilder gameBuilder = new TicTacToeGameBuilderImpl();
128:
129: @SuppressWarnings("unchecked")
130: final Map<String, Object> gameData = inputProvider
131: .needInteger(
132: TicTacToeGameBuilderFactory.PARAM_BOARD_SIZE,
133: "Number of rows (and columns)",
134: Optional.of(TicTacToeGameBuilder.DEFAULT_BOARD_SIZE),
135: new MinValueValidator<>(TicTacToeGameBuilderFactoryImpl.MIN_BOARD_SIZE),
136: new MaxValueValidator<>(TicTacToeGameBuilderFactoryImpl.MAX_BOARD_SIZE))
137: .needInteger(
138: GameBuilderFactory.PARAM_MAX_COMPUTATION_TIME_PER_MOVE,
139: "Maximum computation time per move in seconds",
140: Optional.of(GameBuilder.DEFAULT_MAX_COMPUTATION_TIME_PER_MOVE),
141: new MinValueValidator<>(TicTacToeGameBuilderFactoryImpl.MIN_MAX_COMPUTATION_TIME_PER_MOVE),
142: new MaxValueValidator<>(TicTacToeGameBuilderFactoryImpl.MAX_MAX_COMPUTATION_TIME_PER_MOVE))
143: .requestData("Board properties");
144:
145: gameBuilder.changeBoardSize((Integer) gameData.get(TicTacToeGameBuilderFactory.PARAM_BOARD_SIZE));
146: gameBuilder.changeMaximumComputationTimePerMove(
147: (Integer) gameData.get(GameBuilderFactory.PARAM_MAX_COMPUTATION_TIME_PER_MOVE));
148:
149: final InputProvider firstPlayerInputProvider = inputProvider.getNext(gameData);
150: final Map<String, Object> firstPlayerData = this
151: .requestPlayerData(firstPlayerInputProvider, "Player 1", Optional.empty());
152: final TicTacToePlayerBuilder firstPlayerBuilder = this
153: .initPlayerBuilder(gameBuilder.createPlayerBuilder(), firstPlayerData);
154: final TicTacToeStrategy firstPlayerStrategy = this.getStrategy(firstPlayerData);
155: gameBuilder.addPlayerBuilder(firstPlayerBuilder, firstPlayerStrategy);
156:
157: final InputProvider secondPlayerInputProvider = firstPlayerInputProvider.getNext(firstPlayerData);
158: final Map<String, Object> secondPlayerData = this.requestPlayerData(
159: secondPlayerInputProvider,
160: "Player 2",
161: Optional.of(
162:• !(Boolean) firstPlayerData.get(TicTacToeGameBuilderFactory.PARAM_PLAYER_USING_CROSSES)));
163: final TicTacToePlayerBuilder secondPlayerBuilder = this
164: .initPlayerBuilder(gameBuilder.createPlayerBuilder(), secondPlayerData);
165: final TicTacToeStrategy secondPlayerStrategy = this.getStrategy(secondPlayerData);
166: gameBuilder.addPlayerBuilder(secondPlayerBuilder, secondPlayerStrategy);
167:
168: return gameBuilder;
169: } catch (final InputProviderException e) {
170: throw new GameException(String.format("Creating Tic Tac Toe game was aborted: %s", e.getMessage()), e);
171: }
172: }
173:
174: /**
175: * Initialises an Tic Tac Toe player builder.
176: *
177: * @param inputProvider The input provider.
178: * @param title The title for the UI.
179: * @param usingCrosses If set, determines whether the player uses crosses or noughts. Otherwise, the setting is
180: * initially set to crosses, and the user can change it at will.
181: * @return {@code playerBuilder}.
182: * @throws InputProviderException if the operation has been aborted prematurely (e.g. if the user cancelled a
183: * dialog).
184: */
185: @SuppressWarnings("unchecked")
186: private Map<String, Object> requestPlayerData(final InputProvider inputProvider, final String title,
187: final Optional<Boolean> usingCrosses) throws GameException, InputProviderException {
188:
189: inputProvider
190: .needString(
191: GameBuilderFactory.PARAM_PLAYER_NAME,
192: "Name",
193: Optional.empty(),
194: new PatternValidator(Pattern.compile("\\S+(\\s+\\S+)*")))
195: .needBoolean(
196: TicTacToeGameBuilderFactory.PARAM_PLAYER_USING_CROSSES,
197: "Uses crosses",
198: Optional.of(Boolean.TRUE))
199: .needObject(GameBuilderFactory.PARAM_PLAYER_STRATEGY, "Strategy", Optional.empty(), this.strategies);
200:
201:• if (usingCrosses.isPresent()) {
202: inputProvider.fixedBoolean(TicTacToeGameBuilderFactory.PARAM_PLAYER_USING_CROSSES, usingCrosses.get());
203: }
204:
205: return inputProvider.requestData(title);
206: }
207:
208: /**
209: * Initialises an Tic Tac Toe player builder.
210: *
211: * @param playerBuilder The player builder.
212: * @param playerData The requested player data.
213: * @return {@code playerBuilder}.
214: * @throws InputProviderException if the operation has been aborted prematurely (e.g. if the user cancelled a
215: * dialog).
216: */
217: private TicTacToePlayerBuilder initPlayerBuilder(final TicTacToePlayerBuilder playerBuilder,
218: final Map<String, Object> playerData) throws GameException, InputProviderException {
219:
220: return playerBuilder.changeName((String) playerData.get(GameBuilderFactory.PARAM_PLAYER_NAME))
221: .changeUsingCrosses((Boolean) playerData.get(TicTacToeGameBuilderFactory.PARAM_PLAYER_USING_CROSSES));
222: }
223:
224: /**
225: * Returns an Tic Tac Toe strategy.
226: *
227: * @param playerData The requested player data.
228: * @return The Tic Tac Toe strategy.
229: */
230: private TicTacToeStrategy getStrategy(final Map<String, Object> playerData) {
231: return (TicTacToeStrategy) playerData.get(GameBuilderFactory.PARAM_PLAYER_STRATEGY);
232: }
233: }