Skip to content

Commit

Permalink
Merge branch 'master' into fix/skipmoves
Browse files Browse the repository at this point in the history
  • Loading branch information
SKoschnicke committed Oct 30, 2020
2 parents 5b85067 + 7d04cbd commit e91714f
Show file tree
Hide file tree
Showing 14 changed files with 199 additions and 196 deletions.
17 changes: 17 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
socha.gameName=blokus
socha.version.year=21
socha.version.minor=00
socha.version.patch=00
socha.version.patch=03
24 changes: 7 additions & 17 deletions gradle/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ plugins {
maven
`java-library`
kotlin("jvm") version "1.4.10"
id("org.jetbrains.dokka") version "0.9.17"
id("org.jetbrains.dokka") version "0.10.1"
id("scripts-task")

id("com.github.ben-manes.versions") version "0.33.0"
Expand Down Expand Up @@ -52,17 +52,13 @@ tasks {
}

val doc by creating(DokkaTask::class) {
val includedProjects = documentedProjects
mustRunAfter(includedProjects.map { "$it:classes" })
moduleName = "Software-Challenge API $version"
val sourceSets = includedProjects.map { project(it).sourceSets.main.get() }
sourceDirs = files(sourceSets.map { it.java.sourceDirectories })
outputDirectory = deployDir.resolve("doc").toString()
outputFormat = "javadoc"
jdkVersion = 8
reportUndocumented = false
doFirst {
classpath = files(sourceSets.map { it.runtimeClasspath }.flatMap { it.files }.filter { it.exists() })
subProjects = listOf("sdk", "plugin")
configuration {
reportUndocumented = false
moduleName = "Software-Challenge API $version"
jdkVersion = 8
}
}

Expand Down Expand Up @@ -247,17 +243,11 @@ allprojects {

if (this.name in documentedProjects) {
apply(plugin = "maven")
apply(plugin = "org.jetbrains.dokka")
tasks {
val doc by creating(DokkaTask::class) {
moduleName = "Software-Challenge API $version"
classpath = sourceSets.main.get().runtimeClasspath
outputDirectory = buildDir.resolve("doc").toString()
outputFormat = "javadoc"
jdkVersion = 8
reportUndocumented = false
doFirst {
classpath = files(sourceSets.main.get().runtimeClasspath.files.filter { it.exists() })
}
}
val docJar by creating(Jar::class) {
dependsOn(doc)
Expand Down
2 changes: 1 addition & 1 deletion player/src/sc/player2021/Starter.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
public class Starter extends AbstractClient {
private static final Logger logger = LoggerFactory.getLogger(Starter.class);

public Starter(String host, int port, String reservation) throws Exception {
public Starter(String host, int port, String reservation) {
// client starten
super(host, port);

Expand Down
49 changes: 16 additions & 33 deletions player/src/sc/player2021/logic/Logic.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sc.framework.plugins.Player;
import sc.player2021.Starter;
import sc.plugin2021.GameState;
import sc.plugin2021.IGameHandler;
import sc.plugin2021.Move;
import sc.plugin2021.Team;
import sc.plugin2021.*;
import sc.plugin2021.util.GameRuleLogic;
import sc.shared.GameResult;
import sc.api.plugins.ITeam;

import java.util.List;
import java.util.ArrayList;
Expand All @@ -19,64 +14,52 @@
* Das Herz des Clients:
* Eine sehr simple Logik, die ihre Zuege zufaellig waehlt,
* aber gueltige Zuege macht.
*
* Ausserdem werden zum Spielverlauf Konsolenausgaben gemacht.
*/
public class Logic implements IGameHandler {
private static final Logger log = LoggerFactory.getLogger(Logic.class);

private Starter client;
/** Internet Client, der mit dem Spielserver kommuniziert. */
private final AbstractClient client;
/** Aktueller Spielstatus. */
private GameState gameState;
/** Aktueller eigener Spieler. */
private Player currentPlayer;

/**
* Erzeugt ein neues Strategieobjekt, das zufaellige Zuege taetigt.
*
* @param client Der zugrundeliegende Client, der mit dem Spielserver kommuniziert.
*/
public Logic(Starter client) {
/** Erzeugt eine neue Instanz dieser Strategie, die über den mitgegebenen Client Züge absendet. */
public Logic(AbstractClient client) {
this.client = client;
}

/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
public void gameEnded(GameResult data, Team color, String errorMessage) {
log.info("Das Spiel ist beendet.");
}

/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
@Override
public void onRequestAction() {
long startTime = System.currentTimeMillis();
log.info("Es wurde ein Zug angefordert.");
List possibleMoves = new ArrayList<>(GameRuleLogic.getPossibleMoves(gameState));
sendAction((Move) possibleMoves.get((int) (Math.random() * possibleMoves.size())));
List<Move> possibleMoves = new ArrayList<>(GameRuleLogic.getPossibleMoves(gameState));
sendAction(possibleMoves.get((int) (Math.random() * possibleMoves.size())));
}

/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
@Override
public void onUpdate(Player player, Player otherPlayer) {
currentPlayer = player;
log.info("Spielerwechsel: " + player.getColor());
}

/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
@Override
public void onUpdate(GameState gameState) {
this.gameState = gameState;
currentPlayer = gameState.getCurrentPlayer();
log.info("Zug: {} Spieler: {}", gameState.getTurn(), currentPlayer.getColor());
log.info("Zug: {} Dran: {}", gameState.getTurn(), gameState.getCurrentPlayer().getColor());
}

/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
@Override
public void sendAction(Move move) {
client.sendMove(move);
Expand Down
25 changes: 14 additions & 11 deletions plugin/src/client/sc/plugin2021/AbstractClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,14 @@ import sc.protocol.responses.ProtocolErrorMessage
import sc.protocol.responses.ProtocolMessage
import sc.shared.GameResult
import sc.shared.WelcomeMessage
import java.io.IOException
import java.net.ConnectException
import kotlin.system.exitProcess

/**
* Eine abstrakte Implementation des [ILobbyClientListener].
* Hier sind alle Methoden implementiert, die unabhängig von der Logik der Clients der Spieler sind.
*/
abstract class AbstractClient @Throws(IOException::class) constructor(
abstract class AbstractClient(
host: String,
port: Int,
private val type: PlayerType
Expand All @@ -31,6 +30,10 @@ abstract class AbstractClient @Throws(IOException::class) constructor(
companion object {
private val logger = LoggerFactory.getLogger(AbstractClient::class.java);
private val gameType = GamePlugin.PLUGIN_UUID

init {
GamePlugin.registerXStream()
}
}

var isGameOver = false
Expand All @@ -47,13 +50,13 @@ abstract class AbstractClient @Throws(IOException::class) constructor(
}

/** Storage for the reason of a rule violation, if any occurs. */
private var error: String? = null
fun getError() = error
var error: String? = null
private set

/** Current room of the player. */
private lateinit var roomId: String

/** The team the client belongs to in order to connect client and player. */
/** The team the client belongs to. Needed to connect client and player. */
private var team: Team? = when (type) {
PlayerType.PLAYER_ONE -> Team.ONE
PlayerType.PLAYER_TWO -> Team.TWO
Expand All @@ -66,11 +69,9 @@ abstract class AbstractClient @Throws(IOException::class) constructor(

/** Called for any new message sent to the game room, e.g., move requests. */
override fun onRoomMessage(roomId: String, data: ProtocolMessage) {
if (data is MoveRequest) {
handler?.onRequestAction()
}
if (data is WelcomeMessage) {
team = Team.valueOf(data.color.toUpperCase())
when(data) {
is MoveRequest -> handler?.onRequestAction()
is WelcomeMessage -> team = Team.valueOf(data.color.toUpperCase())
}
this.roomId = roomId
}
Expand All @@ -95,21 +96,23 @@ abstract class AbstractClient @Throws(IOException::class) constructor(

if (type == PlayerType.OBSERVER) return

handler?.onUpdate(gameState)
if (gameState.orderedColors.isNotEmpty()) {
if (gameState.currentTeam == team) {
handler?.onUpdate(gameState.currentPlayer, gameState.otherPlayer)
} else {
handler?.onUpdate(gameState.otherPlayer, gameState.currentPlayer)
}
handler?.onUpdate(gameState)
}
}

/** Start the LobbyClient [client] and listen to it. */
private fun start() {
client.start()
client.addListener(this)
}

/** [start] and join any game with the appropriate [gameType]. */
fun joinAnyGame() {
start()
client.joinRoomRequest(gameType)
Expand Down
18 changes: 11 additions & 7 deletions plugin/src/server/sc/plugin2021/GamePlugin.kt
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
package sc.plugin2021

import com.thoughtworks.xstream.XStream
import sc.api.plugins.IGameInstance
import sc.api.plugins.IGamePlugin
import sc.helpers.xStream
import sc.plugin2021.xstream.BoardConverter
import sc.plugins.PluginDescriptor
import sc.protocol.helpers.LobbyProtocol
import sc.shared.ScoreAggregation
import sc.shared.ScoreDefinition
import sc.shared.ScoreFragment
import sc.helpers.xStream as xstream
import java.util.concurrent.atomic.AtomicBoolean

@PluginDescriptor(name = "Blokus", uuid = "swc_2021_blokus")
class GamePlugin: IGamePlugin {

companion object {
val PLUGIN_UUID = "swc_2021_blokus"
val loaded = AtomicBoolean(false)

val SCORE_DEFINITION = ScoreDefinition(arrayOf(
ScoreFragment("Gewinner"),
Expand All @@ -28,15 +31,16 @@ class GamePlugin: IGamePlugin {
Color::class.java, Team::class.java)

fun registerXStream() {
LobbyProtocol.registerAdditionalMessages(xstream, classesToRegister)

xstream.registerConverter(BoardConverter())
if (loaded.compareAndSet(false, true)) {
LobbyProtocol.registerAdditionalMessages(xStream, classesToRegister)
xStream.registerConverter(BoardConverter())
}
}

@JvmStatic
val xStream by lazy {
fun loadXStream(): XStream {
registerXStream()
xstream
return xStream
}
}

Expand Down
9 changes: 3 additions & 6 deletions plugin/src/shared/sc/plugin2021/Color.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias

/** Die vier verschiedenen Farben im Spiel. */
@XStreamAlias(value = "color")
enum class Color() {
enum class Color {
BLUE,
YELLOW,
RED,
Expand All @@ -15,10 +15,7 @@ enum class Color() {
GREEN.next = BLUE
}};

/**
* Die Farbe, die als nächstes am Zug ist, sofern sie noch im Spiel ist.
* Achtung: Da die Farbe den Spielstand nicht kennt, werden auch Farben ausgegeben, die nicht mehr im Spiel sind.
*/
/** Die nächste Farbe in der Reihenfolge. */
lateinit var next: Color
private set

Expand All @@ -29,7 +26,7 @@ enum class Color() {
YELLOW, GREEN -> Team.TWO
}

/** Konvertiert die Farbe zu einem entsprechenden [FieldContent]. */
/** @return [FieldContent], der dieser Farbe entspricht. */
operator fun unaryPlus(): FieldContent = when(this) {
BLUE -> FieldContent.BLUE
YELLOW -> FieldContent.YELLOW
Expand Down
Loading

0 comments on commit e91714f

Please sign in to comment.