From b60e217ab96e172c043f5b4c746c63b59e6ad321 Mon Sep 17 00:00:00 2001 From: Xerus <27jf@web.de> Date: Mon, 7 Oct 2019 15:38:15 +0200 Subject: [PATCH] rework(sdk): start to separate different player concerns --- plugin/src/server/sc/plugin2020/Game.java | 12 ++-- plugin/src/shared/sc/plugin2020/GameState.kt | 11 +--- .../sc/api/plugins/TwoPlayerGameState.kt | 44 ++------------ .../server-api/sc/framework/plugins/Player.kt | 57 +++++++------------ 4 files changed, 36 insertions(+), 88 deletions(-) diff --git a/plugin/src/server/sc/plugin2020/Game.java b/plugin/src/server/sc/plugin2020/Game.java index 1908cf900..de98cd54a 100644 --- a/plugin/src/server/sc/plugin2020/Game.java +++ b/plugin/src/server/sc/plugin2020/Game.java @@ -8,6 +8,7 @@ import sc.api.plugins.IMove; import sc.api.plugins.host.GameLoader; import sc.framework.plugins.ActionTimeout; +import sc.framework.plugins.NamedPlayer; import sc.framework.plugins.Player; import sc.framework.plugins.RoundBasedGameInstance; import sc.plugin2020.util.Configuration; @@ -75,7 +76,7 @@ public Player onPlayerJoined() { if(PlayerColor.RED == playerColor && this.gameState.getPlayer(PlayerColor.RED) != null) { player = this.gameState.getPlayer(PlayerColor.RED); } else if(PlayerColor.BLUE == playerColor && this.gameState.getPlayer(PlayerColor.BLUE) != null) { - player = this.gameState.getPlayer(PlayerColor.BLUE); + player = this.players.getPlayer(PlayerColor.BLUE); } else { player = new Player(playerColor); } @@ -98,11 +99,11 @@ public void start() { @Override public PlayerScore getScoreFor(Player player) { logger.debug("get score for player {} (violated: {})", player.getColor(), player.hasViolated()); - int[] stats = this.gameState.getPlayerStats(player); + int[] stats = this.gameState.getPlayerStats(player.getColor()); int matchPoints = Constants.DRAW_SCORE; WinCondition winCondition = checkWinCondition(); String reason = null; - Player opponent = gameState.getOpponent(player); + NamedPlayer opponent = gameState.getOpponent(player); if(winCondition != null) { PlayerColor winner = winCondition.getWinner(); reason = winner != null ? winCondition.toString(gameState.getPlayer(winner).getDisplayName()) : winCondition.toString(); @@ -263,8 +264,7 @@ public void loadGameInfo(Object gameInfo) { // currentPlayer if(this.gameState.getCurrentPlayerColor() != PlayerColor.RED) { this.gameState.setCurrentPlayerColor(PlayerColor.RED); - Player newRed = this.gameState.getPlayer(PlayerColor.BLUE).clone(); - newRed.setColor(PlayerColor.RED); + Player newRed = this.gameState.getPlayer(PlayerColor.BLUE).copy(); Player newBlue = this.gameState.getPlayer(PlayerColor.RED).clone(); newBlue.setColor(PlayerColor.BLUE); this.gameState.setRed(newRed); @@ -302,7 +302,7 @@ public List getWinners() { /** Liste der Spieler. Reihenfolge: RED, BLUE */ @Override public List getPlayers() { - return gameState.getPlayers(); + return players; } /** Liste der playerScores für jeden Spieler. Reihenfolge: RED, BLUE */ diff --git a/plugin/src/shared/sc/plugin2020/GameState.kt b/plugin/src/shared/sc/plugin2020/GameState.kt index 84be4af06..92ee33c2d 100644 --- a/plugin/src/shared/sc/plugin2020/GameState.kt +++ b/plugin/src/shared/sc/plugin2020/GameState.kt @@ -4,6 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias import com.thoughtworks.xstream.annotations.XStreamAsAttribute import sc.api.plugins.IMove import sc.api.plugins.TwoPlayerGameState +import sc.framework.plugins.NamedPlayer import sc.framework.plugins.Player import sc.plugin2020.util.Constants import sc.plugin2020.util.GameRuleLogic @@ -11,14 +12,12 @@ import sc.shared.PlayerColor @XStreamAlias(value = "state") data class GameState( - override var red: Player = Player(PlayerColor.RED), - override var blue: Player = Player(PlayerColor.BLUE), override var board: Board = Board(), @XStreamAsAttribute override var turn: Int = 0, private val undeployedRedPieces: MutableList = parsePiecesString(Constants.STARTING_PIECES, PlayerColor.RED), private val undeployedBluePieces: MutableList = parsePiecesString(Constants.STARTING_PIECES, PlayerColor.BLUE) -): TwoPlayerGameState(), Cloneable { +): TwoPlayerGameState(), Cloneable { private val allPieces: Collection get() = undeployedBluePieces + undeployedRedPieces + board.getPieces() @@ -39,7 +38,7 @@ data class GameState( return ownerPieces } - fun addPlayer(player: Player) { + fun addPlayer(player: NamedPlayer) { when(player.color) { PlayerColor.RED -> red = player PlayerColor.BLUE -> blue = player @@ -50,10 +49,6 @@ data class GameState( return GameRuleLogic.freeBeeNeighbours(this.board, playerColor) } - fun getPlayerStats(p: Player): IntArray { - return getPlayerStats(p.color) - } - fun getPlayerStats(playerColor: PlayerColor): IntArray = intArrayOf(this.getPointsForPlayer(playerColor)) diff --git a/socha-sdk/src/server-api/sc/api/plugins/TwoPlayerGameState.kt b/socha-sdk/src/server-api/sc/api/plugins/TwoPlayerGameState.kt index 7e0d7d7e6..da6a8a82d 100644 --- a/socha-sdk/src/server-api/sc/api/plugins/TwoPlayerGameState.kt +++ b/socha-sdk/src/server-api/sc/api/plugins/TwoPlayerGameState.kt @@ -3,13 +3,10 @@ package sc.api.plugins import com.thoughtworks.xstream.annotations.XStreamAsAttribute import com.thoughtworks.xstream.annotations.XStreamOmitField import org.slf4j.LoggerFactory -import sc.framework.plugins.Player import sc.shared.PlayerColor -abstract class TwoPlayerGameState

: IGameState { +abstract class TwoPlayerGameState : IGameState { - abstract val red: P - abstract val blue: P abstract val board: IBoard @XStreamOmitField @@ -17,52 +14,23 @@ abstract class TwoPlayerGameState

: IGameState { /** Farbe des Startspielers */ @XStreamAsAttribute - open var startPlayerColor: PlayerColor = PlayerColor.RED + open var startPlayer: PlayerColor = PlayerColor.RED /** Farbe des Spielers, der aktuell am Zug ist */ @XStreamAsAttribute - open var currentPlayerColor: PlayerColor = PlayerColor.RED - - /** Liste der Spieler. Reihenfolge: RED, BLUE */ - val players: List

- get() = listOf(red, blue) - - /** Der Spieler, der momentan am Zug ist. */ - val currentPlayer: P - get() = getPlayer(currentPlayerColor) - - /** Der Spieler, der momentan nicht am Zug ist. */ - val otherPlayer: P - get() = getPlayer(otherPlayerColor) + open var currentPlayer: PlayerColor = PlayerColor.RED /** Farbe des Spielers, der momentan nicht am Zug ist. */ - val otherPlayerColor: PlayerColor - get() = currentPlayerColor.opponent() - - /** Der Spieler, der das Spiel begonnen hat. */ - val startPlayer: P - get() = getPlayer(startPlayerColor) - - /** Die Namen der beiden Spieler. */ - val playerNames: Array - get() = arrayOf(red.displayName, blue.displayName) + val otherPlayer: PlayerColor + get() = currentPlayer.opponent() /** Letzter getaetigter Zug. */ var lastMove: M? = null - fun getOpponent(player: P) = - getPlayer(player.color.opponent()) - - fun getPlayer(color: PlayerColor): P = - when(color) { - PlayerColor.RED -> red - PlayerColor.BLUE -> blue - } - /** Gibt die angezeigte Punktzahl des Spielers zurueck. */ abstract fun getPointsForPlayer(playerColor: PlayerColor): Int override fun toString() = - "GameState(turn=$turn,currentPlayer=${currentPlayer.color})" + "GameState(turn=$turn,currentPlayer=$currentPlayer)" } \ No newline at end of file diff --git a/socha-sdk/src/server-api/sc/framework/plugins/Player.kt b/socha-sdk/src/server-api/sc/framework/plugins/Player.kt index 32f6b9b8c..06be3a05a 100644 --- a/socha-sdk/src/server-api/sc/framework/plugins/Player.kt +++ b/socha-sdk/src/server-api/sc/framework/plugins/Player.kt @@ -2,7 +2,6 @@ package sc.framework.plugins import com.thoughtworks.xstream.annotations.XStreamAlias import com.thoughtworks.xstream.annotations.XStreamAsAttribute -import com.thoughtworks.xstream.annotations.XStreamOmitField import org.slf4j.LoggerFactory import sc.api.plugins.host.IPlayerListener import sc.framework.plugins.protocol.MoveRequest @@ -12,68 +11,54 @@ import java.util.* private val logger = LoggerFactory.getLogger(Player::class.java) -@XStreamAlias(value = "player") -open class Player(@XStreamAsAttribute var color: PlayerColor) : Cloneable { - - public override fun clone() = Player(color) - - @XStreamOmitField +open class Player(override val color: PlayerColor, override val displayName: String): PlayerName, Cloneable { + + public override fun clone() = Player(color, displayName) + protected var listeners: MutableList = ArrayList() - - @XStreamOmitField + var isCanTimeout: Boolean = false - - @XStreamOmitField var isShouldBePaused: Boolean = false - - @XStreamAsAttribute - var displayName: String = "" - - @XStreamOmitField var violated = false - fun hasViolated() = violated - - @XStreamOmitField var left = false - fun hasLeft() = left - - @XStreamOmitField var softTimeout = false - fun hasSoftTimeout() = softTimeout - - @XStreamOmitField var hardTimeout = false - fun hasHardTimeout() = hardTimeout - - /** @return Reason for violation - */ - @XStreamOmitField var violationReason: String? = null - + fun addPlayerListener(listener: IPlayerListener) { this.listeners.add(listener) } - + fun removePlayerListener(listener: IPlayerListener) { this.listeners.remove(listener) } - + fun notifyListeners(o: ProtocolMessage) { - for (listener in this.listeners) { + for(listener in this.listeners) { listener.onPlayerEvent(o) } } - + open fun requestMove() { val request = MoveRequest() notifyListeners(request) logger.debug("Move requested from $this") } + +} +@XStreamAlias(value = "player") +data class NamedPlayer @JvmOverloads constructor( + @XStreamAsAttribute override val color: PlayerColor, + @XStreamAsAttribute override val displayName: String = ""): PlayerName { override fun toString(): String = "Player %s(%s)".format(color, displayName) - } + +interface PlayerName { + val color: PlayerColor + val displayName: String +} \ No newline at end of file