Skip to contentMethod: VGGameBuilderFactoryImpl()
      1: package de.fhdw.gaming.ipspiel22.vierGewinnt.domain.impl;
2: 
3: import java.util.ArrayList;
4: import java.util.LinkedHashSet;
5: import java.util.List;
6: import java.util.Map;
7: import java.util.Optional;
8: import java.util.Set;
9: import java.util.regex.Pattern;
10: 
11: import de.fhdw.gaming.core.domain.GameBuilder;
12: import de.fhdw.gaming.core.domain.GameBuilderFactory;
13: import de.fhdw.gaming.core.domain.GameException;
14: import de.fhdw.gaming.core.domain.Strategy;
15: import de.fhdw.gaming.core.ui.InputProvider;
16: import de.fhdw.gaming.core.ui.InputProviderException;
17: import de.fhdw.gaming.core.ui.type.validator.MaxValueValidator;
18: import de.fhdw.gaming.core.ui.type.validator.MinValueValidator;
19: import de.fhdw.gaming.core.ui.type.validator.PatternValidator;
20: import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.VGGameBuilder;
21: import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.VGGameBuilderFactory;
22: import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.VGPlayer;
23: import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.VGPlayerBuilder;
24: import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.VGStrategy;
25: import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.factory.VGDefaultStrategyFactoryProvider;
26: import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.factory.VGStrategyFactory;
27: import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.factory.VGStrategyFactoryProvider;
28: import de.fhdw.gaming.ipspiel22.vierGewinnt.moves.factory.VGMoveFactory;
29: import de.fhdw.gaming.ipspiel22.vierGewinnt.moves.impl.VGDefaultMoveFactory;
30: 
31: /**
32:  * Implements {@link GameBuilderFactory} by creating a Vier gewinnt game builder.
33:  */
34: public class VGGameBuilderFactoryImpl implements VGGameBuilderFactory {
35: 
36:     /**
37:      * The number of players.
38:      */
39:     private static final int NUMBER_OF_PLAYERS = 2;
40:     /**
41:      * Smallest allowed maximum computation time per move in seconds.
42:      */
43:     private static final int MIN_MAX_COMPUTATION_TIME_PER_MOVE = 1;
44:     /**
45:      * Largest allowed maximum computation time per move in seconds.
46:      */
47:     private static final int MAX_MAX_COMPUTATION_TIME_PER_MOVE = 3600;
48: 
49:     /**
50:      * All available Vier gewinnt strategies.
51:      */
52:     private final Set<VGStrategy> strategies;
53: 
54:     /**
55:      * Creates a Vier gewinnt game factory. Vier gewinnt strategies are loaded by using the
56:      * {@link java.util.ServiceLoader}.
57:      * <p>
58:      * This constructor is meant to be used by the {@link java.util.ServiceLoader}.
59:      */
60:     public VGGameBuilderFactoryImpl() {
61:         this(new VGDefaultStrategyFactoryProvider());
62:     }
63: 
64:     /**
65:      * Creates a Vier gewinnt game factory.
66:      *
67:      * @param strategyFactoryProvider The {@link VGStrategyFactoryProvider} for loading Vier gewinnt strategies.
68:      */
69:     VGGameBuilderFactoryImpl(final VGStrategyFactoryProvider strategyFactoryProvider) {
70:         final VGMoveFactory moveFactory = new VGDefaultMoveFactory();
71: 
72:         final List<VGStrategyFactory> factories = strategyFactoryProvider.getStrategyFactories();
73:         this.strategies = new LinkedHashSet<>();
74:         for (final VGStrategyFactory factory : factories) {
75:             this.strategies.add(factory.create(moveFactory));
76:         }
77:     }
78: 
79:     @Override
80:     public String getName() {
81:         return "Vier gewinnt";
82:     }
83: 
84:     @Override
85:     public int getMinimumNumberOfPlayers() {
86:         return VGGameBuilderFactoryImpl.NUMBER_OF_PLAYERS;
87:     }
88: 
89:     @Override
90:     public int getMaximumNumberOfPlayers() {
91:         return VGGameBuilderFactoryImpl.NUMBER_OF_PLAYERS;
92:     }
93: 
94:     @Override
95:     public List<? extends Strategy<?, ?, ?>> getStrategies() {
96:         return new ArrayList<>(this.strategies);
97:     }
98: 
99:     @Override
100:     public VGGameBuilder createGameBuilder(final InputProvider inputProvider) throws GameException {
101:         try {
102:             final VGGameBuilder gameBuilder = new VGGameBuilderImpl();
103: 
104:             @SuppressWarnings("unchecked")
105:             final Map<String,
106:                     Object> gameData = inputProvider.needInteger(
107:                             GameBuilderFactory.PARAM_MAX_COMPUTATION_TIME_PER_MOVE,
108:                             "Maximum computation time per move in seconds",
109:                             Optional.of(GameBuilder.DEFAULT_MAX_COMPUTATION_TIME_PER_MOVE),
110:                             new MinValueValidator<>(VGGameBuilderFactoryImpl.MIN_MAX_COMPUTATION_TIME_PER_MOVE),
111:                             new MaxValueValidator<>(VGGameBuilderFactoryImpl.MAX_MAX_COMPUTATION_TIME_PER_MOVE))
112:                             .requestData("Game properties");
113: 
114:             gameBuilder.changeMaximumComputationTimePerMove(
115:                     (Integer) gameData.get(GameBuilderFactory.PARAM_MAX_COMPUTATION_TIME_PER_MOVE));
116: 
117:             final InputProvider firstPlayerInputProvider = inputProvider.getNext(gameData);
118:             final Map<String, Object> firstPlayerData = this.requestPlayerData(firstPlayerInputProvider, "Player 1",
119:                     Optional.empty());
120:             final VGPlayer firstPlayer = this.createPlayer(gameBuilder.createPlayerBuilder(), firstPlayerData);
121:             final VGStrategy firstPlayerStrategy = this.getStrategy(firstPlayerData);
122:             gameBuilder.addPlayer(firstPlayer, firstPlayerStrategy);
123: 
124:             final InputProvider secondPlayerInputProvider = inputProvider.getNext(firstPlayerData);
125:             final Map<String, Object> secondPlayerData = this.requestPlayerData(secondPlayerInputProvider, "Player 2",
126:                     Optional.of(!(Boolean) firstPlayerData
127:                             .get(VGGameBuilderFactory.PARAM_PLAYER_USING_RED_CHIPS)));
128:             final VGPlayer secondPlayer = this.createPlayer(gameBuilder.createPlayerBuilder(), secondPlayerData);
129:             final VGStrategy secondPlayerStrategy = this.getStrategy(secondPlayerData);
130:             gameBuilder.addPlayer(secondPlayer, secondPlayerStrategy);
131: 
132:             return gameBuilder;
133:         } catch (final InputProviderException e) {
134:             throw new GameException(String.format("Creating Vier gewinnt game was aborted: %s", e.getMessage()),
135:                     e);
136:         }
137:     }
138: 
139:     /**
140:      * Returns data for a player builder.
141:      *
142:      * @param inputProvider The input provider.
143:      * @param title         The title for the UI.
144:      * @param usingRedChips If set, determines the mandatory colour of the player. Otherwise, the colour is initially
145:      *                      set to red, and the user can change it at will.
146:      * @throws InputProviderException if the operation has been aborted prematurely (e.g. if the user cancelled a
147:      *                                dialog).
148:      */
149:     @SuppressWarnings("unchecked")
150:     private Map<String, Object> requestPlayerData(final InputProvider inputProvider, final String title,
151:             final Optional<Boolean> usingRedChips)
152:             throws GameException, InputProviderException {
153: 
154:         inputProvider
155:                 .needString(
156:                         GameBuilderFactory.PARAM_PLAYER_NAME,
157:                         "Name",
158:                         Optional.empty(),
159:                         new PatternValidator(Pattern.compile("\\S+(\\s+\\S+)*")))
160:                 .needBoolean(
161:                         VGGameBuilderFactory.PARAM_PLAYER_USING_RED_CHIPS,
162:                         "Red colour",
163:                         Optional.of(Boolean.TRUE))
164:                 .needObject(GameBuilderFactory.PARAM_PLAYER_STRATEGY, "Strategy", Optional.empty(), this.strategies);
165: 
166:         if (usingRedChips.isPresent()) {
167:             inputProvider.fixedBoolean(
168:                     VGGameBuilderFactory.PARAM_PLAYER_USING_RED_CHIPS,
169:                     usingRedChips.get());
170:         }
171: 
172:         return inputProvider.requestData(title);
173:     }
174: 
175:     /**
176:      * Creates a Vier gewinnt player.
177:      *
178:      * @param playerBuilder The player builder.
179:      * @param playerData    The requested player data.
180:      * @return {@link VGPlayer}.
181:      * @throws InputProviderException if the operation has been aborted prematurely (e.g. if the user cancelled a
182:      *                                dialog).
183:      */
184:     private VGPlayer createPlayer(final VGPlayerBuilder playerBuilder,
185:             final Map<String, Object> playerData) throws GameException, InputProviderException {
186:         return playerBuilder.changeName((String) playerData.get(GameBuilderFactory.PARAM_PLAYER_NAME))
187:                 .changeUsingRedChips((Boolean) playerData.get(VGGameBuilderFactory.PARAM_PLAYER_USING_RED_CHIPS))
188:                 .build();
189:     }
190: 
191:     /**
192:      * Returns a Vier gewinnt strategy.
193:      *
194:      * @param playerData The requested player data.
195:      * @return The Vier gewinnt strategy.
196:      */
197:     private VGStrategy getStrategy(final Map<String, Object> playerData) {
198:         return (VGStrategy) playerData.get(GameBuilderFactory.PARAM_PLAYER_STRATEGY);
199:     }
200: }