Merge 292 into development (#293)

Applied template method pattern to abstract player
This commit is contained in:
Stef
2025-12-10 12:39:40 +01:00
committed by GitHub
parent 0132981d94
commit cd8eb99559
7 changed files with 49 additions and 35 deletions

View File

@@ -21,7 +21,7 @@ import org.toop.game.games.reversi.BitboardReversi;
import org.toop.game.games.tictactoe.BitboardTicTacToe;
import org.toop.game.players.ArtificialPlayer;
import org.toop.game.players.OnlinePlayer;
import org.toop.game.players.RandomAI;
import org.toop.game.players.ai.RandomAI;
import org.toop.local.AppContext;
import java.util.List;

View File

@@ -2,9 +2,6 @@ package org.toop.app.widget.view;
import javafx.application.Platform;
import org.toop.app.GameInformation;
import org.toop.app.canvas.ReversiBitCanvas;
import org.toop.app.canvas.TicTacToeBitCanvas;
import org.toop.app.gameControllers.GenericGameController;
import org.toop.app.gameControllers.ReversiBitController;
import org.toop.app.gameControllers.TicTacToeBitController;
import org.toop.framework.gameFramework.controller.GameController;
@@ -18,8 +15,8 @@ import org.toop.app.widget.complex.PlayerInfoWidget;
import org.toop.app.widget.complex.ViewWidget;
import org.toop.app.widget.popup.ErrorPopup;
import org.toop.app.widget.tutorial.*;
import org.toop.game.players.MiniMaxAI;
import org.toop.game.players.RandomAI;
import org.toop.game.players.ai.MiniMaxAI;
import org.toop.game.players.ai.RandomAI;
import org.toop.local.AppContext;
import javafx.geometry.Pos;
@@ -27,9 +24,6 @@ import javafx.scene.control.ScrollPane;
import javafx.scene.layout.VBox;
import org.toop.local.AppSettings;
import java.util.Arrays;
import java.util.Random;
public class LocalMultiplayerView extends ViewWidget {
private final GameInformation information;

View File

@@ -5,46 +5,66 @@ import org.apache.logging.log4j.Logger;
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
/**
* Abstract class representing a player in a game.
* <p>
* Players are entities that can make moves based on the current state of a game.
* player types, such as human players or AI players.
* </p>
* <p>
* Subclasses should override the {@link #getMove(GameR)} method to provide
* specific move logic.
* </p>
* Base class for players in a turn-based game.
*
* @param <T> the game type
*/
public abstract class AbstractPlayer<T extends TurnBasedGame<T>> implements Player<T> {
private final Logger logger = LogManager.getLogger(this.getClass());
private final Logger logger = LogManager.getLogger(this.getClass());
private final String name;
/**
* Creates a new player with the given name.
*
* @param name the player name
*/
protected AbstractPlayer(String name) {
this.name = name;
}
/**
* Creates a copy of another player.
*
* @param other the player to copy
*/
protected AbstractPlayer(AbstractPlayer<T> other) {
this.name = other.name;
}
/**
* Determines the next move based on the provided game state.
* Gets the player's move for the given game state.
* A deep copy is provided so the player cannot modify the real state.
* <p>
* The default implementation throws an {@link UnsupportedOperationException},
* indicating that concrete subclasses must override this method to provide
* actual move logic.
* </p>
* This method uses the Template Method Pattern: it defines the fixed
* algorithm and delegates the variable part to {@link #determineMove(T)}.
*
* @param gameCopy a snapshot of the current game state
* @return an integer representing the chosen move
* @throws UnsupportedOperationException if the method is not overridden
* @param game the current game
* @return the chosen move
*/
public long getMove(T gameCopy) {
logger.error("Method getMove not implemented.");
throw new UnsupportedOperationException("Not supported yet.");
public final long getMove(T game) {
return determineMove(game.deepCopy());
}
public String getName(){
/**
* Determines the player's move using a safe copy of the game.
* <p>
* This method is called by {@link #getMove(T)} and should contain
* the player's strategy for choosing a move.
*
* @param gameCopy a deep copy of the game
* @return the chosen move
*/
protected abstract long determineMove(T gameCopy);
/**
* Returns the player's name.
*
* @return the name
*/
public String getName() {
return this.name;
}
}

View File

@@ -44,7 +44,7 @@ public class ArtificialPlayer<T extends TurnBasedGame<T>> extends AbstractPlayer
* @return the integer representing the chosen move
* @throws ClassCastException if {@code gameCopy} is not of type {@code T}
*/
public long getMove(T gameCopy) {
protected long determineMove(T gameCopy) {
return ai.getMove(gameCopy);
}

View File

@@ -22,7 +22,7 @@ public class LocalPlayer<T extends TurnBasedGame<T>> extends AbstractPlayer<T> {
}
@Override
public long getMove(T gameCopy) {
protected long determineMove(T gameCopy) {
return getValidMove(gameCopy);
}

View File

@@ -1,4 +1,4 @@
package org.toop.game.players;
package org.toop.game.players.ai;
import org.toop.framework.gameFramework.GameState;
import org.toop.framework.gameFramework.model.game.PlayResult;

View File

@@ -1,4 +1,4 @@
package org.toop.game.players;
package org.toop.game.players.ai;
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
import org.toop.framework.gameFramework.model.player.AbstractAI;