Skip to content

Method: changeBoardSize(int)

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