mirror of
https://github.com/2OOP/pism.git
synced 2026-02-04 10:54:51 +00:00
272 remake game framework interfaces to properly represent vmc (#278)
* Cleaned up a lot of old files and renamed/remade interfaces to better suit the framework * Broken commit * Fixed online play * Better file structure and closer to MVC
This commit is contained in:
@@ -1,127 +0,0 @@
|
||||
package org.toop.framework.gameFramework.abstractClasses;
|
||||
|
||||
import org.toop.framework.gameFramework.interfaces.IPlayableR;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Abstract base class representing a general grid-based game.
|
||||
* <p>
|
||||
* Provides the basic structure for games with a two-dimensional board stored as a
|
||||
* one-dimensional array. Tracks the board state, row and column sizes, and provides
|
||||
* helper methods for accessing and modifying the board.
|
||||
* </p>
|
||||
* <p>
|
||||
* Concrete subclasses must implement the {@link #clone()} method and can extend this
|
||||
* class with specific game rules, winning conditions, and move validation logic.
|
||||
* </p>
|
||||
*/
|
||||
public abstract class GameR implements IPlayableR, Cloneable {
|
||||
|
||||
/** Constant representing an empty position on the board. */
|
||||
public static final int EMPTY = -1;
|
||||
|
||||
/** Number of rows in the game board. */
|
||||
private final int rowSize;
|
||||
|
||||
/** Number of columns in the game board. */
|
||||
private final int columnSize;
|
||||
|
||||
/** The game board stored as a one-dimensional array. */
|
||||
private final int[] board;
|
||||
|
||||
/**
|
||||
* Constructs a new game board with the specified row and column size.
|
||||
*
|
||||
* @param rowSize number of rows (> 0)
|
||||
* @param columnSize number of columns (> 0)
|
||||
* @throws AssertionError if rowSize or columnSize is not positive
|
||||
*/
|
||||
|
||||
protected GameR(int rowSize, int columnSize) {
|
||||
assert rowSize > 0 && columnSize > 0;
|
||||
|
||||
this.rowSize = rowSize;
|
||||
this.columnSize = columnSize;
|
||||
|
||||
board = new int[rowSize * columnSize];
|
||||
Arrays.fill(board, EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor for creating a deep copy of another game instance.
|
||||
*
|
||||
* @param copy the game instance to copy
|
||||
*/
|
||||
protected GameR(GameR copy) {
|
||||
this.rowSize = copy.rowSize;
|
||||
this.columnSize = copy.columnSize;
|
||||
this.board = copy.board.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an array contains a value.
|
||||
*
|
||||
* @param array array containing ints
|
||||
* @param value int to check for
|
||||
*
|
||||
* @return true if array contains value
|
||||
*/
|
||||
|
||||
public static boolean contains(int[] array, int value) {
|
||||
// O(n)
|
||||
for (int element : array){
|
||||
if (element == value) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of rows in the board.
|
||||
*
|
||||
* @return number of rows
|
||||
*/
|
||||
public int getRowSize() {
|
||||
return this.rowSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of columns in the board.
|
||||
*
|
||||
* @return number of columns
|
||||
*/
|
||||
public int getColumnSize() {
|
||||
return this.columnSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the current board state.
|
||||
*
|
||||
* @return a cloned array representing the board
|
||||
*/
|
||||
public int[] getBoard() {
|
||||
return this.board.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a specific position on the board.
|
||||
*
|
||||
* @param position the index in the board array
|
||||
* @param player the value to set (e.g., player number)
|
||||
*/
|
||||
protected void setBoardPosition(int position, int player) {
|
||||
this.board[position] = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a deep copy of this game instance.
|
||||
* <p>
|
||||
* Subclasses must implement this method to ensure proper copying of any
|
||||
* additional fields beyond the base board structure.
|
||||
* </p>
|
||||
*
|
||||
* @return a cloned instance of this game
|
||||
*/
|
||||
@Override
|
||||
public abstract GameR clone();
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package org.toop.framework.gameFramework.abstractClasses;
|
||||
|
||||
public abstract class TurnBasedGameR extends GameR {
|
||||
private final int playerCount; // How many players are playing
|
||||
private int turn = 0; // What turn it is in the game
|
||||
|
||||
protected TurnBasedGameR(int rowSize, int columnSize, int playerCount) {
|
||||
super(rowSize, columnSize);
|
||||
this.playerCount = playerCount;
|
||||
}
|
||||
|
||||
protected TurnBasedGameR(TurnBasedGameR other){
|
||||
super(other);
|
||||
this.playerCount = other.playerCount;
|
||||
this.turn = other.turn;
|
||||
}
|
||||
|
||||
public int getPlayerCount(){return this.playerCount;}
|
||||
|
||||
protected void nextTurn() {
|
||||
turn += 1;
|
||||
}
|
||||
|
||||
public int getCurrentTurn() {
|
||||
return turn % playerCount;
|
||||
}
|
||||
|
||||
protected void setBoard(int position) {
|
||||
super.setBoardPosition(position, getCurrentTurn());
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.toop.framework.gameFramework.interfaces;
|
||||
package org.toop.framework.gameFramework.controller;
|
||||
|
||||
/**
|
||||
* Interface for classes that can trigger a UI update.
|
||||
@@ -1,20 +0,0 @@
|
||||
package org.toop.framework.gameFramework.interfaces;
|
||||
|
||||
import org.toop.framework.gameFramework.abstractClasses.GameR;
|
||||
|
||||
/**
|
||||
* AI interface for selecting the best move in a game.
|
||||
*
|
||||
* @param <T> the type of game this AI can play, extending {@link GameR}
|
||||
*/
|
||||
public interface IAIMoveR<T extends GameR> {
|
||||
|
||||
/**
|
||||
* Determines the optimal move for the current player.
|
||||
*
|
||||
* @param game the current game state
|
||||
* @param depth the search depth for evaluating moves
|
||||
* @return an integer representing the chosen move
|
||||
*/
|
||||
int findBestMove(T game, int depth);
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package org.toop.framework.gameFramework.model.game;
|
||||
|
||||
import org.toop.framework.gameFramework.model.player.Player;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public abstract class AbstractGame<T extends TurnBasedGame<T>> implements TurnBasedGame<T> {
|
||||
private final int playerCount; // How many players are playing
|
||||
private final Player<T>[] players;
|
||||
private int turn = 0; // What turn it is in the game
|
||||
|
||||
/** Constant representing an empty position on the board. */
|
||||
public static final int EMPTY = -1;
|
||||
|
||||
/** Number of rows in the game board. */
|
||||
private final int rowSize;
|
||||
|
||||
/** Number of columns in the game board. */
|
||||
private final int columnSize;
|
||||
|
||||
/** The game board stored as a one-dimensional array. */
|
||||
private final int[] board;
|
||||
|
||||
|
||||
|
||||
protected AbstractGame(int rowSize, int columnSize, int playerCount, Player<T>[] players) {
|
||||
assert rowSize > 0 && columnSize > 0;
|
||||
|
||||
this.rowSize = rowSize;
|
||||
this.columnSize = columnSize;
|
||||
|
||||
this.players = players;
|
||||
|
||||
board = new int[rowSize * columnSize];
|
||||
Arrays.fill(board, EMPTY);
|
||||
|
||||
this.playerCount = playerCount;
|
||||
}
|
||||
|
||||
protected AbstractGame(AbstractGame<T> other){
|
||||
this.rowSize = other.rowSize;
|
||||
this.columnSize = other.columnSize;
|
||||
this.board = other.board.clone();
|
||||
this.playerCount = other.playerCount;
|
||||
this.turn = other.turn;
|
||||
// TODO: Make this a deep copy, add deep copy interface to Player
|
||||
this.players = other.players;
|
||||
|
||||
}
|
||||
|
||||
public static boolean contains(int[] array, int value) {
|
||||
// O(n)
|
||||
for (int element : array){
|
||||
if (element == value) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Player<T> getPlayer(int index) {
|
||||
return players[index];
|
||||
}
|
||||
|
||||
public int getPlayerCount(){return this.playerCount;}
|
||||
|
||||
protected void nextTurn() {
|
||||
turn += 1;
|
||||
}
|
||||
|
||||
public int getCurrentTurn() {
|
||||
return turn % playerCount;
|
||||
}
|
||||
|
||||
protected void setBoard(int position) {
|
||||
setBoard(position, getCurrentTurn());
|
||||
}
|
||||
|
||||
protected void setBoard(int position, int player) {
|
||||
this.board[position] = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of rows in the board.
|
||||
*
|
||||
* @return number of rows
|
||||
*/
|
||||
public int getRowSize() {
|
||||
return this.rowSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of columns in the board.
|
||||
*
|
||||
* @return number of columns
|
||||
*/
|
||||
public int getColumnSize() {
|
||||
return this.columnSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the current board state.
|
||||
*
|
||||
* @return a cloned array representing the board
|
||||
*/
|
||||
public int[] getBoard() {
|
||||
return this.board.clone();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.toop.framework.gameFramework.model.game;
|
||||
|
||||
public interface DeepCopyable<T extends TurnBasedGame<T>> {
|
||||
T deepCopy();
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.toop.framework.gameFramework;
|
||||
package org.toop.framework.gameFramework.model.game;
|
||||
|
||||
import org.toop.framework.gameFramework.GameState;
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package org.toop.framework.gameFramework.interfaces;
|
||||
package org.toop.framework.gameFramework.model.game;
|
||||
|
||||
import org.toop.framework.gameFramework.GameState;
|
||||
import org.toop.framework.gameFramework.PlayResult;
|
||||
|
||||
/**
|
||||
* Interface for turn-based games that can be played and queried for legal moves.
|
||||
*/
|
||||
public interface IPlayableR {
|
||||
public interface Playable {
|
||||
|
||||
/**
|
||||
* Returns the moves that are currently valid in the game.
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.toop.framework.gameFramework.model.game;
|
||||
|
||||
import org.toop.framework.gameFramework.model.player.Player;
|
||||
|
||||
public interface PlayerProvider<T extends TurnBasedGame<T>> {
|
||||
Player<T> getPlayer(int index);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.toop.framework.gameFramework.interfaces;
|
||||
package org.toop.framework.gameFramework.model.game;
|
||||
|
||||
import org.toop.framework.networking.events.NetworkEvents;
|
||||
|
||||
@@ -10,10 +10,10 @@ import org.toop.framework.networking.events.NetworkEvents;
|
||||
public interface SupportsOnlinePlay {
|
||||
|
||||
/** Called when it is this player's turn to make a move. */
|
||||
void yourTurn(NetworkEvents.YourTurnResponse event);
|
||||
void onYourTurn(NetworkEvents.YourTurnResponse event);
|
||||
|
||||
/** Called when a move from another player is received. */
|
||||
void moveReceived(NetworkEvents.GameMoveResponse event);
|
||||
void onMoveReceived(NetworkEvents.GameMoveResponse event);
|
||||
|
||||
/** Called when the game has finished, with the final result. */
|
||||
void gameFinished(NetworkEvents.GameResultResponse event);
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.toop.framework.gameFramework.model.game;
|
||||
|
||||
public interface TurnBasedGame<T extends TurnBasedGame<T>> extends Playable, DeepCopyable<T>, PlayerProvider<T> {
|
||||
int getCurrentTurn();
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.toop.framework.gameFramework.model.game.threadBehaviour;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
|
||||
import org.toop.framework.gameFramework.model.player.Player;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Base class for thread-based game behaviours.
|
||||
* <p>
|
||||
* Provides common functionality for managing game state and execution:
|
||||
* a running flag, a game reference, and a logger.
|
||||
* Subclasses implement the actual game-loop logic.
|
||||
*/
|
||||
public abstract class AbstractThreadBehaviour<T extends TurnBasedGame<T>> implements ThreadBehaviour<T> {
|
||||
|
||||
/** Indicates whether the game loop or event processing is active. */
|
||||
protected final AtomicBoolean isRunning = new AtomicBoolean();
|
||||
|
||||
/** The game instance controlled by this behaviour. */
|
||||
protected final T game;
|
||||
|
||||
/** Logger for the subclass to report errors or debug info. */
|
||||
protected final Logger logger = LogManager.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* Creates a new base behaviour for the specified game.
|
||||
*
|
||||
* @param game the turn-based game to control
|
||||
*/
|
||||
public AbstractThreadBehaviour(T game) {
|
||||
this.game = game;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.toop.framework.gameFramework.model.game.threadBehaviour;
|
||||
|
||||
public interface Controllable {
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.toop.framework.gameFramework.model.game.threadBehaviour;
|
||||
|
||||
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
|
||||
import org.toop.framework.gameFramework.model.player.AbstractPlayer;
|
||||
import org.toop.framework.gameFramework.model.player.Player;
|
||||
|
||||
/**
|
||||
* Strategy interface for controlling game thread behavior.
|
||||
* <p>
|
||||
* Defines how a game's execution is started, stopped, and which player is active.
|
||||
*/
|
||||
public interface ThreadBehaviour<T extends TurnBasedGame<T>> extends Controllable {
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.toop.framework.gameFramework.abstractClasses;
|
||||
package org.toop.framework.gameFramework.model.player;
|
||||
|
||||
import org.toop.framework.gameFramework.interfaces.IAIMoveR;
|
||||
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
|
||||
|
||||
/**
|
||||
* Abstract base class for AI implementations for games extending {@link GameR}.
|
||||
@@ -12,6 +12,6 @@ import org.toop.framework.gameFramework.interfaces.IAIMoveR;
|
||||
*
|
||||
* @param <T> the specific type of game this AI can play, extending {@link GameR}
|
||||
*/
|
||||
public abstract class AIR<T extends GameR> implements IAIMoveR<T> {
|
||||
public abstract class AbstractAI<T extends TurnBasedGame> implements MoveProvider<T> {
|
||||
// Concrete AI implementations should override findBestMove(T game, int depth)
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.toop.framework.gameFramework.model.player;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
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>
|
||||
*/
|
||||
public abstract class AbstractPlayer<T extends TurnBasedGame<T>> implements Player<T> {
|
||||
private int playerIndex = -1;
|
||||
|
||||
private Logger logger = LogManager.getLogger(this.getClass());
|
||||
|
||||
private final String name;
|
||||
|
||||
protected AbstractPlayer(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
/**
|
||||
* Determines the next move based on the provided game state.
|
||||
* <p>
|
||||
* The default implementation throws an {@link UnsupportedOperationException},
|
||||
* indicating that concrete subclasses must override this method to provide
|
||||
* actual move logic.
|
||||
* </p>
|
||||
*
|
||||
* @param gameCopy a snapshot of the current game state
|
||||
* @return an integer representing the chosen move
|
||||
* @throws UnsupportedOperationException if the method is not overridden
|
||||
*/
|
||||
public int getMove(T gameCopy) {
|
||||
logger.error("Method getMove not implemented.");
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public String getName(){
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.toop.framework.gameFramework.model.player;
|
||||
|
||||
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
|
||||
|
||||
public interface MoveProvider<T extends TurnBasedGame> {
|
||||
int getMove(T game);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.toop.framework.gameFramework.model.player;
|
||||
|
||||
public interface NameProvider {
|
||||
String getName();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.toop.framework.gameFramework.model.player;
|
||||
|
||||
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
|
||||
|
||||
public interface Player<T extends TurnBasedGame<T>> extends NameProvider, MoveProvider<T> {
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.toop.framework.gameFramework;
|
||||
package org.toop.framework.gameFramework.view;
|
||||
|
||||
import org.toop.framework.eventbus.events.EventsBase;
|
||||
import org.toop.framework.eventbus.events.GenericEvent;
|
||||
Reference in New Issue
Block a user