Skip to contentMethod: addPlayer(TicTacToePlayer, TicTacToeStrategy)
      1: /*
2:  * Copyright © 2021 Fachhochschule für die Wirtschaft (FHDW) Hannover
3:  *
4:  * This file is part of ipspiel23-tictactoe-core.
5:  *
6:  * ipspiel23-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:  * ipspiel23-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:  * ipspiel23-tictactoe-core. If not, see <http://www.gnu.org/licenses/>.
18:  */
19: package de.fhdw.gaming.ipspiel23.tictactoe.core.domain.impl;
20: 
21: import java.util.LinkedHashMap;
22: import java.util.Map;
23: import java.util.Objects;
24: import java.util.Optional;
25: 
26: import de.fhdw.gaming.core.domain.DefaultObserverFactoryProvider;
27: import de.fhdw.gaming.core.domain.GameBuilder;
28: import de.fhdw.gaming.core.domain.GameException;
29: import de.fhdw.gaming.core.domain.ObserverFactoryProvider;
30: import de.fhdw.gaming.ipspiel23.tictactoe.core.domain.TicTacToeGame;
31: import de.fhdw.gaming.ipspiel23.tictactoe.core.domain.TicTacToeGameBuilder;
32: import de.fhdw.gaming.ipspiel23.tictactoe.core.domain.TicTacToePlayer;
33: import de.fhdw.gaming.ipspiel23.tictactoe.core.domain.TicTacToePlayerBuilder;
34: import de.fhdw.gaming.ipspiel23.tictactoe.core.domain.TicTacToeState;
35: import de.fhdw.gaming.ipspiel23.tictactoe.core.domain.TicTacToeStrategy;
36: import de.fhdw.gaming.ipspiel23.tictactoe.core.moves.impl.AbstractTicTacToeMove;
37: 
38: /**
39:  * Implements {@link TicTacToeGameBuilder}.
40:  */
41: final class TicTacToeGameBuilderImpl implements TicTacToeGameBuilder {
42: 
43:     /**
44:      * The {@link ObserverFactoryProvider}.
45:      */
46:     private ObserverFactoryProvider observerFactoryProvider;
47: 
48:     /**
49:      * The player using crosses.
50:      */
51:     private Optional<TicTacToePlayer> crossesPlayer;
52: 
53:     /**
54:      * The strategy of the player using crosses.
55:      */
56:     private Optional<TicTacToeStrategy> crossesPlayerStrategy;
57: 
58:     /**
59:      * The player using noughts.
60:      */
61:     private Optional<TicTacToePlayer> noughtsPlayer;
62: 
63:     /**
64:      * The strategy of the player using noughts.
65:      */
66:     private Optional<TicTacToeStrategy> noughtsPlayerStrategy;
67: 
68:     /**
69:      * The maximum computation time per move in seconds.
70:      */
71:     private int maxComputationTimePerMove;
72:     
73:     /**
74:      * The number of rows (and columns) of the board.
75:      */
76:     private int boardSize;
77: 
78:     /**
79:      * Creates an TicTacToe game builder.
80:      */
81:     TicTacToeGameBuilderImpl() {
82:         this.observerFactoryProvider = new DefaultObserverFactoryProvider();
83:         this.crossesPlayer = Optional.empty();
84:         this.crossesPlayerStrategy = Optional.empty();
85:         this.noughtsPlayer = Optional.empty();
86:         this.noughtsPlayerStrategy = Optional.empty();
87:         this.maxComputationTimePerMove = GameBuilder.DEFAULT_MAX_COMPUTATION_TIME_PER_MOVE;
88:         this.boardSize = TicTacToeGameBuilder.DEFAULT_BOARD_SIZE;
89:     }
90: 
91:     @Override
92:     public TicTacToePlayerBuilder createPlayerBuilder() {
93:         return new TicTacToePlayerBuilderImpl();
94:     }
95: 
96:     @Override
97:     public TicTacToeGameBuilder addPlayer(final TicTacToePlayer player, final TicTacToeStrategy strategy)
98:             throws GameException {
99: 
100:•        if (player.isUsingCrosses() && this.crossesPlayer.isEmpty()) {
101:             this.crossesPlayer = Optional.of(Objects.requireNonNull(player, "player"));
102:             this.crossesPlayerStrategy = Optional.of(Objects.requireNonNull(strategy, "crossesPlayerStrategy"));
103:•        } else if (!player.isUsingCrosses() && this.noughtsPlayer.isEmpty()) {
104:             this.noughtsPlayer = Optional.of(Objects.requireNonNull(player, "player"));
105:             this.noughtsPlayerStrategy = Optional.of(Objects.requireNonNull(strategy, "noughtsPlayerStrategy"));
106:         } else {
107:             throw new GameException(
108:                     String.format(
109:                             "Adding player %s is not allowed as a player using the same type of marks "
110:                                     + "has already been added.",
111:                             player));
112:         }
113:         return this;
114:     }
115: 
116:     @Override
117:     public TicTacToeGameBuilder changeMaximumComputationTimePerMove(final int newMaxComputationTimePerMove) {
118:         this.maxComputationTimePerMove = newMaxComputationTimePerMove;
119:         return this;
120:     }
121: 
122:     @Override
123:     public TicTacToeGameBuilder changeBoardSize(final int newBoardSize) {
124:         this.boardSize = newBoardSize;
125:         return this;
126:     }
127: 
128:     @Override
129:     public TicTacToeGameBuilder changeObserverFactoryProvider(
130:             final ObserverFactoryProvider newObserverFactoryProvider) {
131:         this.observerFactoryProvider = newObserverFactoryProvider;
132:         return this;
133:     }
134: 
135:     @Override
136:     public TicTacToeGame build(final int id) throws GameException, InterruptedException {
137:         if (!this.crossesPlayer.isPresent() || !this.noughtsPlayer.isPresent()) {
138:             throw new GameException("An Tic Tac Toe game needs two players.");
139:         }
140: 
141:         final TicTacToeBoardImpl board = new TicTacToeBoardImpl(this.boardSize);
142:         final TicTacToeState initialState = new TicTacToeStateImpl(
143:                 board,
144:                 this.crossesPlayer.get(),
145:                 this.noughtsPlayer.get(),
146:                 true);
147: 
148:         final Map<String, TicTacToeStrategy> strategies = new LinkedHashMap<>();
149:         strategies.put(initialState.getCrossesPlayer().getName(), this.crossesPlayerStrategy.orElseThrow());
150:         strategies.put(initialState.getNoughtsPlayer().getName(), this.noughtsPlayerStrategy.orElseThrow());
151:         return new TicTacToeGameImpl(
152:                 id,
153:                 initialState,
154:                 strategies,
155:                 this.maxComputationTimePerMove,
156:                 AbstractTicTacToeMove.class::isInstance,
157:                 this.observerFactoryProvider);
158:     }
159: }