Skip to content

Method: addPlayer(TicTacToePlayer, TicTacToeStrategy)

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