Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate concerns of Player object #229

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions plugin/src/server/sc/plugin2020/Game.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand All @@ -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();
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -302,7 +302,7 @@ public List<Player> getWinners() {
/** Liste der Spieler. Reihenfolge: RED, BLUE */
@Override
public List<Player> getPlayers() {
return gameState.getPlayers();
return players;
}

/** Liste der playerScores für jeden Spieler. Reihenfolge: RED, BLUE */
Expand Down
11 changes: 3 additions & 8 deletions plugin/src/shared/sc/plugin2020/GameState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@ 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
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<Piece> = parsePiecesString(Constants.STARTING_PIECES, PlayerColor.RED),
private val undeployedBluePieces: MutableList<Piece> = parsePiecesString(Constants.STARTING_PIECES, PlayerColor.BLUE)
): TwoPlayerGameState<Player, IMove>(), Cloneable {
): TwoPlayerGameState<NamedPlayer, IMove>(), Cloneable {

private val allPieces: Collection<Piece>
get() = undeployedBluePieces + undeployedRedPieces + board.getPieces()
Expand All @@ -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
Expand All @@ -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))

Expand Down
44 changes: 6 additions & 38 deletions socha-sdk/src/server-api/sc/api/plugins/TwoPlayerGameState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,66 +3,34 @@ 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<P : Player, M : IMove> : IGameState {
abstract class TwoPlayerGameState<M : IMove> : IGameState {

abstract val red: P
abstract val blue: P
abstract val board: IBoard

@XStreamOmitField
private val logger = LoggerFactory.getLogger(TwoPlayerGameState::class.java)

/** 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<P>
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<String>
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)"

}
57 changes: 21 additions & 36 deletions socha-sdk/src/server-api/sc/framework/plugins/Player.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<IPlayerListener> = 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
}