Skip to contentMethod: getPossibleMoves(TicTacToeState)
      1: /*
2:  * Copyright © 2021-2023 Fachhochschule für die Wirtschaft (FHDW) Hannover
3:  *
4:  * This file is part of ipspiel24-tictactoe-strategy-minimax.
5:  *
6:  * ipspiel24-tictactoe-strategy-minimax 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-strategy-minimax 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-strategy-minimax. If not, see <http://www.gnu.org/licenses/>.
18:  */
19: package de.fhdw.gaming.ipspiel24.tictactoe.strategy.minimax;
20: 
21: import java.util.ArrayList;
22: import java.util.Collections;
23: import java.util.List;
24: import java.util.Map;
25: import java.util.Optional;
26: import java.util.Set;
27: 
28: import de.fhdw.gaming.core.domain.GameException;
29: import de.fhdw.gaming.ipspiel24.minimax.Minimax;
30: import de.fhdw.gaming.ipspiel24.minimax.MinimaxStrategy;
31: import de.fhdw.gaming.ipspiel24.tictactoe.core.domain.TicTacToeBoard;
32: import de.fhdw.gaming.ipspiel24.tictactoe.core.domain.TicTacToeField;
33: import de.fhdw.gaming.ipspiel24.tictactoe.core.domain.TicTacToeFieldState;
34: import de.fhdw.gaming.ipspiel24.tictactoe.core.domain.TicTacToePlayer;
35: import de.fhdw.gaming.ipspiel24.tictactoe.core.domain.TicTacToePosition;
36: import de.fhdw.gaming.ipspiel24.tictactoe.core.domain.TicTacToeRow;
37: import de.fhdw.gaming.ipspiel24.tictactoe.core.domain.TicTacToeState;
38: import de.fhdw.gaming.ipspiel24.tictactoe.core.domain.TicTacToeStrategy;
39: import de.fhdw.gaming.ipspiel24.tictactoe.core.moves.TicTacToeMove;
40: import de.fhdw.gaming.ipspiel24.tictactoe.core.moves.factory.TicTacToeMoveFactory;
41: 
42: /**
43:  * Implements {@link TicTacToeStrategy} by asking the user for a move.
44:  */
45: public class TicTacToeMinimaxStrategy implements MinimaxStrategy<TicTacToePlayer, TicTacToeState, TicTacToeMove>,
46:         TicTacToeStrategy {
47: 
48:     /**
49:      * The factory for creating TicTacToe moves.
50:      */
51:     private final TicTacToeMoveFactory moveFactory;
52:     
53:     /**
54:      * Creates an {@link TicTacToeMinimaxStrategyOLD}.
55:      * 
56:      * @param moveFactory The factory for creating TicTacToe moves.
57:      */
58:     public TicTacToeMinimaxStrategy(final TicTacToeMoveFactory moveFactory) {
59:         this.moveFactory = moveFactory;
60:     }
61: 
62:     @Override
63:     public Optional<TicTacToeMove> computeNextMove(int gameId, TicTacToePlayer player, TicTacToeState state,
64:             long maxComputationTimePerMove) throws GameException, InterruptedException {
65:         final TicTacToePlayer opponent = this.getOpponent(state);
66:         
67:         final Minimax<TicTacToePlayer, TicTacToeState, TicTacToeMove> minimax = 
68:                 new Minimax<TicTacToePlayer, TicTacToeState, TicTacToeMove>(this, 10, opponent);
69:         final TicTacToeMove bestMove = minimax.getBestMove(state, player);
70:         //System.out.println("We are: " + player.toString());
71:         return Optional.of(bestMove);
72:     }
73: 
74:     @Override
75:     public List<TicTacToeMove> getPossibleMoves(final TicTacToeState state) {
76:•        if (!state.getBoard().getRowsUniformlyMarked().isEmpty()) {
77:             return Collections.emptyList();
78:         }
79:         final List<TicTacToeMove> possibleMoves = new ArrayList<>();
80:         final TicTacToeBoard board = state.getBoard();
81:         final Map<TicTacToePosition,
82:                 ? extends TicTacToeField> fieldMap = board.getFieldsBeing(TicTacToeFieldState.EMPTY);
83:•        for (Map.Entry<TicTacToePosition, ? extends TicTacToeField> entry : fieldMap.entrySet()) {
84:             possibleMoves.add(moveFactory.createPlaceMarkMove(
85:                     state.getCurrentPlayer().isUsingCrosses(), entry.getKey()));
86:         }
87: 
88:         return possibleMoves;
89:     }
90: 
91:     @Override
92:     public int evaluate(TicTacToeState state, TicTacToePlayer player, int depth) {
93:         final TicTacToeBoard board = state.getBoard();
94:         final Set<TicTacToeRow> uniformRows = board.getRowsUniformlyMarked();
95:         if (!uniformRows.isEmpty()) {
96:             final TicTacToeFieldState rowState = uniformRows.iterator().next().getState().orElseThrow();
97:             final TicTacToeFieldState playerState = player.isUsingCrosses() 
98:                     ? TicTacToeFieldState.CROSS : TicTacToeFieldState.NOUGHT;
99:             final int returnScore = rowState.equals(playerState) ? 10 + depth : -10 - depth;
100:             //System.out.println("Returning score: " + returnScore + " board: " + state.getBoard());
101:             return returnScore;
102:         } /*else {
103:             final Map<TicTacToePosition,
104:                     ? extends TicTacToeField> emptyFields = board.getFieldsBeing(TicTacToeFieldState.EMPTY);
105:             if (emptyFields.isEmpty()) {
106:                 return 0;
107:             }
108:         }*/
109:         return 0;
110:     }
111: 
112:     @Override
113:     public String toString() {
114:         return "TicTacToe Minimax Strategy";
115:     }
116: 
117:     @Override
118:     public TicTacToePlayer getOpponent(TicTacToeState state) {
119:         System.out.println("Opponent" + (state.getCurrentPlayer() == state.getCrossesPlayer() 
120:                 ? state.getNoughtsPlayer() : state.getCrossesPlayer()) + " currentPLayer: " + state.getCurrentPlayer());
121:         return state.getCurrentPlayer() == state.getCrossesPlayer() 
122:                 ? state.getNoughtsPlayer() : state.getCrossesPlayer();
123:         
124:         /*final Map<String, TicTacToePlayer> players = state.getPlayers();
125:         for (Map.Entry<String, TicTacToePlayer> entry : players.entrySet()) {
126:             System.out.println("Player: " + entry.getValue().toString());
127:             if (entry.getValue() != currentPlayer) {
128:                 System.out.println("Opponent: " + entry.getValue().toString());
129:                 return entry.getValue();
130:             }
131:         }
132:         return null;*/
133:     }
134: }