Skip to content

Method: GDGameBuilderFactoryImpl(GDStrategyFactoryProvider)

1: package de.fhdw.gaming.ipspiel22.gefangenenDilemma.domain.impl;
2:
3: import java.util.ArrayList;
4: import java.util.LinkedHashMap;
5: import java.util.LinkedHashSet;
6: import java.util.List;
7: import java.util.Map;
8: import java.util.Optional;
9: import java.util.Set;
10: import java.util.regex.Pattern;
11:
12: import de.fhdw.gaming.core.domain.GameBuilder;
13: import de.fhdw.gaming.core.domain.GameBuilderFactory;
14: import de.fhdw.gaming.core.domain.GameException;
15: import de.fhdw.gaming.core.domain.Strategy;
16: import de.fhdw.gaming.core.ui.InputProvider;
17: import de.fhdw.gaming.core.ui.InputProviderException;
18: import de.fhdw.gaming.core.ui.type.validator.MaxValueValidator;
19: import de.fhdw.gaming.core.ui.type.validator.MinValueValidator;
20: import de.fhdw.gaming.core.ui.type.validator.PatternValidator;
21: import de.fhdw.gaming.ipspiel22.gefangenenDilemma.domain.GDGameBuilder;
22: import de.fhdw.gaming.ipspiel22.gefangenenDilemma.domain.GDGameBuilderFactory;
23: import de.fhdw.gaming.ipspiel22.gefangenenDilemma.domain.GDPlayer;
24: import de.fhdw.gaming.ipspiel22.gefangenenDilemma.domain.GDPlayerBuilder;
25: import de.fhdw.gaming.ipspiel22.gefangenenDilemma.domain.GDStrategy;
26: import de.fhdw.gaming.ipspiel22.gefangenenDilemma.domain.factory.GDDefaultStrategyFactoryProvider;
27: import de.fhdw.gaming.ipspiel22.gefangenenDilemma.domain.factory.GDStrategyFactory;
28: import de.fhdw.gaming.ipspiel22.gefangenenDilemma.domain.factory.GDStrategyFactoryProvider;
29: import de.fhdw.gaming.ipspiel22.gefangenenDilemma.moves.factory.GDMoveFactory;
30: import de.fhdw.gaming.ipspiel22.gefangenenDilemma.moves.impl.GDDefaultMoveFactory;
31:
32: /**
33: * Implements {@link GameBuilderFactory} by creating a Gefangenen Dilemma game builder.
34: */
35: public class GDGameBuilderFactoryImpl implements GDGameBuilderFactory {
36:
37: /**
38: * The number of players.
39: */
40: private static final int NUMBER_OF_PLAYERS = 2;
41: /**
42: * Smallest allowed maximum computation time per move in seconds.
43: */
44: private static final int MIN_MAX_COMPUTATION_TIME_PER_MOVE = 1;
45: /**
46: * Largest allowed maximum computation time per move in seconds.
47: */
48: private static final int MAX_MAX_COMPUTATION_TIME_PER_MOVE = 3600;
49:
50: /**
51: * All available Gefangenen Dilemma strategies.
52: */
53: private final Set<GDStrategy> strategies;
54:
55: /**
56: * Creates a Gefangenen Dilemma game factory. Gefangenen Dilemma strategies are loaded by using the
57: * {@link java.util.ServiceLoader}.
58: * <p>
59: * This constructor is meant to be used by the {@link java.util.ServiceLoader}.
60: */
61: public GDGameBuilderFactoryImpl() {
62: this(new GDDefaultStrategyFactoryProvider());
63: }
64:
65: /**
66: * Creates a Gefangenen Dilemma game factory.
67: *
68: * @param strategyFactoryProvider The {@link GDStrategyFactoryProvider} for loading Gefangenen Dilemma strategies.
69: */
70: GDGameBuilderFactoryImpl(final GDStrategyFactoryProvider strategyFactoryProvider) {
71: final GDMoveFactory moveFactory = new GDDefaultMoveFactory();
72:
73: final List<GDStrategyFactory> factories = strategyFactoryProvider.getStrategyFactories();
74: this.strategies = new LinkedHashSet<>();
75:• for (final GDStrategyFactory factory : factories) {
76: this.strategies.add(factory.create(moveFactory));
77: }
78: }
79:
80: @Override
81: public String getName() {
82: return "Gefangenen Dilemma";
83: }
84:
85: @Override
86: public int getMinimumNumberOfPlayers() {
87: return GDGameBuilderFactoryImpl.NUMBER_OF_PLAYERS;
88: }
89:
90: @Override
91: public int getMaximumNumberOfPlayers() {
92: return GDGameBuilderFactoryImpl.NUMBER_OF_PLAYERS;
93: }
94:
95: @Override
96: public List<? extends Strategy<?, ?, ?>> getStrategies() {
97: return new ArrayList<>(this.strategies);
98: }
99:
100: @Override
101: public GDGameBuilder createGameBuilder(final InputProvider inputProvider) throws GameException {
102: try {
103: final GDGameBuilder gameBuilder = new GDGameBuilderImpl();
104:
105: @SuppressWarnings("unchecked")
106: final Map<String,
107: Object> gameData = inputProvider.needInteger(
108: GameBuilderFactory.PARAM_MAX_COMPUTATION_TIME_PER_MOVE,
109: "Maximum computation time per move in seconds",
110: Optional.of(GameBuilder.DEFAULT_MAX_COMPUTATION_TIME_PER_MOVE),
111: new MinValueValidator<>(GDGameBuilderFactoryImpl.MIN_MAX_COMPUTATION_TIME_PER_MOVE),
112: new MaxValueValidator<>(GDGameBuilderFactoryImpl.MAX_MAX_COMPUTATION_TIME_PER_MOVE))
113: .requestData("Game properties");
114:
115: gameBuilder.changeMaximumComputationTimePerMove(
116: (Integer) gameData.get(GameBuilderFactory.PARAM_MAX_COMPUTATION_TIME_PER_MOVE));
117:
118: final InputProvider firstPlayerInputProvider = inputProvider.getNext(gameData);
119: final Map<String, Object> firstPlayerData = this.requestPlayerData(firstPlayerInputProvider, "Player 1");
120: final GDPlayer firstPlayer = this.createPlayer(gameBuilder.createPlayerBuilder(), firstPlayerData);
121: final GDStrategy firstPlayerStrategy = this.getStrategy(firstPlayerData);
122: gameBuilder.addPlayer(firstPlayer, firstPlayerStrategy);
123:
124: final InputProvider secondPlayerInputProvider = firstPlayerInputProvider.getNext(firstPlayerData);
125: final Map<String, Object> secondPlayerData = this.requestPlayerData(secondPlayerInputProvider, "Player 2");
126: final GDPlayer secondPlayer = this.createPlayer(gameBuilder.createPlayerBuilder(), secondPlayerData);
127: final GDStrategy secondPlayerStrategy = this.getStrategy(secondPlayerData);
128: gameBuilder.addPlayer(secondPlayer, secondPlayerStrategy);
129:
130: return gameBuilder;
131: } catch (final InputProviderException e) {
132: throw new GameException(String.format("Creating Gefangenen Dilemma game was aborted: %s", e.getMessage()),
133: e);
134: }
135: }
136:
137: /**
138: * Returns data for a player builder.
139: *
140: * @param inputProvider The input provider.
141: * @param title The title for the UI.
142: * @throws InputProviderException if the operation has been aborted prematurely (e.g. if the user cancelled a
143: * dialog).
144: */
145: @SuppressWarnings("unchecked")
146: private Map<String, Object> requestPlayerData(final InputProvider inputProvider, final String title)
147: throws GameException, InputProviderException {
148:
149: if (title.equals("Player 1")) {
150: inputProvider
151: .needString(
152: GameBuilderFactory.PARAM_PLAYER_NAME,
153: "Name",
154: Optional.empty(),
155: new PatternValidator(Pattern.compile("\\S+(\\s+\\S+)*")))
156: .needInteger(
157: GDGameBuilderFactory.PARAM_PLAYER_OUTCOME_ON_STATEM_STATEM,
158: "Player's outcome on Statement/Statement",
159: Optional.of(-8))
160: .needInteger(
161: GDGameBuilderFactory.PARAM_PLAYER_OUTCOME_ON_STATEM_QUIET,
162: "Player's outcome on Statement/Quiet",
163: Optional.of(0))
164: .needInteger(
165: GDGameBuilderFactory.PARAM_PLAYER_OUTCOME_ON_QUIET_STATEM,
166: "Player's outcome on Quiet/Statement",
167: Optional.of(-10))
168: .needInteger(
169: GDGameBuilderFactory.PARAM_PLAYER_OUTCOME_ON_QUIET_QUIET,
170: "Player's outcome on Quiet/Quiet",
171: Optional.of(-1))
172: .needObject(GameBuilderFactory.PARAM_PLAYER_STRATEGY, "Strategy", Optional.empty(),
173: this.strategies);
174: } else {
175: inputProvider
176: .needString(
177: GameBuilderFactory.PARAM_PLAYER_NAME,
178: "Name",
179: Optional.empty(),
180: new PatternValidator(Pattern.compile("\\S+(\\s+\\S+)*")))
181: .needInteger(
182: GDGameBuilderFactory.PARAM_PLAYER_OUTCOME_ON_STATEM_STATEM,
183: "Player's outcome on Statement/Statement",
184: Optional.of(-8))
185: .needInteger(
186: GDGameBuilderFactory.PARAM_PLAYER_OUTCOME_ON_STATEM_QUIET,
187: "Player's outcome on Statement/Quiet",
188: Optional.of(-10))
189: .needInteger(
190: GDGameBuilderFactory.PARAM_PLAYER_OUTCOME_ON_QUIET_STATEM,
191: "Player's outcome on Quiet/Statement",
192: Optional.of(0))
193: .needInteger(
194: GDGameBuilderFactory.PARAM_PLAYER_OUTCOME_ON_QUIET_QUIET,
195: "Player's outcome on Quiet/Quiet",
196: Optional.of(-1))
197: .needObject(GameBuilderFactory.PARAM_PLAYER_STRATEGY, "Strategy", Optional.empty(),
198: this.strategies);
199: }
200: return inputProvider.requestData(title);
201: }
202:
203: /**
204: * Creates a Gefangenen Dilemma player.
205: *
206: * @param playerBuilder The player builder.
207: * @param playerData The requested player data.
208: * @return The created {@link GDPlayer}.
209: * @throws InputProviderException if the operation has been aborted prematurely (e.g. if the user cancelled a
210: * dialog).
211: */
212: private GDPlayer createPlayer(final GDPlayerBuilder playerBuilder,
213: final Map<String, Object> playerData) throws GameException, InputProviderException {
214:
215: final Map<Boolean, Map<Boolean, Double>> possibleOutcomes = new LinkedHashMap<>();
216:
217: final Map<Boolean, Double> possibleOutcomesStatement = new LinkedHashMap<>();
218: possibleOutcomesStatement.put(
219: Boolean.FALSE,
220: (double) (Integer) playerData.get(GDGameBuilderFactory.PARAM_PLAYER_OUTCOME_ON_STATEM_STATEM));
221: possibleOutcomesStatement.put(
222: Boolean.TRUE,
223: (double) (Integer) playerData.get(GDGameBuilderFactory.PARAM_PLAYER_OUTCOME_ON_STATEM_QUIET));
224: possibleOutcomes.put(Boolean.FALSE, possibleOutcomesStatement);
225:
226: final Map<Boolean, Double> possibleOutcomesQuiet = new LinkedHashMap<>();
227: possibleOutcomesQuiet.put(
228: Boolean.FALSE,
229: (double) (Integer) playerData.get(GDGameBuilderFactory.PARAM_PLAYER_OUTCOME_ON_QUIET_STATEM));
230: possibleOutcomesQuiet.put(
231: Boolean.TRUE,
232: (double) (Integer) playerData.get(GDGameBuilderFactory.PARAM_PLAYER_OUTCOME_ON_QUIET_QUIET));
233: possibleOutcomes.put(Boolean.TRUE, possibleOutcomesQuiet);
234:
235: return playerBuilder.changeName((String) playerData.get(GameBuilderFactory.PARAM_PLAYER_NAME))
236: .changePossibleOutcomes(possibleOutcomes).build();
237: }
238:
239: /**
240: * Returns a Gefangenen Dilemma strategy.
241: *
242: * @param playerData The requested player data.
243: * @return The Gefangenen Dilemma strategy.
244: */
245: private GDStrategy getStrategy(final Map<String, Object> playerData) {
246: return (GDStrategy) playerData.get(GameBuilderFactory.PARAM_PLAYER_STRATEGY);
247: }
248: }