Skip to content

Commit 8272310

Browse files
committed
fix(plugin): remove issues caused by turn increments
1 parent 8544776 commit 8272310

File tree

9 files changed

+32
-22
lines changed

9 files changed

+32
-22
lines changed

plugin/src/server/sc/plugin2021/Game.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,8 @@ class Game(UUID: String = GamePlugin.PLUGIN_UUID): RoundBasedGameInstance<Player
156156
logger.debug("Current State: $gameState")
157157
logger.debug("Performing Move $data")
158158
GameRuleLogic.performMove(gameState, data)
159-
gameState.turn++
159+
next(if(gameState.orderedColors.isNotEmpty()) gameState.currentPlayer else null)
160160
logger.debug("Current Board:\n${gameState.board}")
161-
next(gameState.currentPlayer)
162161
} catch(e: InvalidMoveException) {
163162
super.catchInvalidMove(e, fromPlayer)
164163
}

plugin/src/shared/sc/plugin2020/GameState.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ class GameState @JvmOverloads constructor(
2020
override var lastMove: Move? = null
2121
): TwoPlayerGameState<Player>(Team.RED) {
2222

23+
override val round: Int
24+
get() = turn / 2
25+
2326
@XStreamOmitField
2427
private var allPieces: Collection<Piece> = undeployedBluePieces + undeployedRedPieces + board.getPieces()
2528

plugin/src/shared/sc/plugin2021/GameState.kt

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package sc.plugin2021
22

33
import com.thoughtworks.xstream.annotations.XStreamAlias
44
import com.thoughtworks.xstream.annotations.XStreamAsAttribute
5+
import org.slf4j.LoggerFactory
56
import sc.api.plugins.TwoPlayerGameState
67
import sc.framework.plugins.Player
78
import sc.api.plugins.ITeam
9+
import sc.api.plugins.exceptions.GameLogicException
810
import sc.plugin2021.util.Constants
911
import sc.plugin2021.util.GameRuleLogic
1012

@@ -13,11 +15,15 @@ class GameState @JvmOverloads constructor(
1315
override var first: Player = Player(Team.ONE),
1416
override var second: Player = Player(Team.TWO),
1517
override var lastMove: Move? = null,
16-
startTurn: Int = 1,
18+
startTurn: Int = 0,
1719
val startColor: Color = Color.BLUE,
1820
@XStreamAsAttribute val startPiece: PieceShape = GameRuleLogic.getRandomPentomino()
1921
): TwoPlayerGameState<Player>(Team.ONE) {
2022

23+
companion object {
24+
val logger = LoggerFactory.getLogger(GameState::class.java)
25+
}
26+
2127
@XStreamAsAttribute
2228
override val board: Board = Board()
2329

@@ -44,7 +50,7 @@ class GameState @JvmOverloads constructor(
4450
get() = orderedColors[currentColorIndex]
4551

4652
@XStreamAsAttribute
47-
override var turn: Int = 1
53+
override var turn: Int = 0
4854
set(value) {
4955
advance(value - field)
5056
field = value
@@ -65,6 +71,9 @@ class GameState @JvmOverloads constructor(
6571
private fun advance(turns: Int) {
6672
if (turns < 0) throw IndexOutOfBoundsException("Can't go back in turns (Request was $turns), expected value bigger than $turn")
6773

74+
if (orderedColors.isEmpty())
75+
throw GameLogicException("Game has already ended - can't proceed to next turn")
76+
6877
val roundIncrementHelper = currentColorIndex + turns
6978
currentColorIndex = roundIncrementHelper % orderedColors.size
7079
round += (roundIncrementHelper - currentColorIndex) / orderedColors.size
@@ -91,7 +100,8 @@ class GameState @JvmOverloads constructor(
91100
*/
92101
fun removeActiveColor() {
93102
orderedColors.remove(currentColor)
94-
currentColorIndex = (currentColorIndex + orderedColors.size - 1) % orderedColors.size
103+
if (orderedColors.isNotEmpty())
104+
currentColorIndex = (currentColorIndex + orderedColors.size - 1) % orderedColors.size
95105
}
96106

97107
override fun toString(): String = "GameState $round/$turn -> $currentColor"

plugin/src/shared/sc/plugin2021/util/GameRuleLogic.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package sc.plugin2021.util
22

3+
import org.slf4j.LoggerFactory
34
import sc.plugin2021.*
45
import sc.shared.InvalidMoveException
56

67
object GameRuleLogic {
8+
val logger = LoggerFactory.getLogger(GameRuleLogic::class.java)
9+
710
const val SMALLEST_SCORE_POSSIBLE = -89
811

912
// TODO: Add all the needed logic as static (@JvmStatic) functions here
@@ -47,6 +50,9 @@ object GameRuleLogic {
4750
gameState.removeActiveColor()
4851
}
4952
}
53+
if (gameState.orderedColors.isNotEmpty())
54+
gameState.turn++
55+
gameState.lastMove = move
5056
}
5157

5258
/** Checks if the given [move] has the right [Color]. */

plugin/src/test/sc/plugin2021/GameRuleLogicTest.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,13 @@ class GameRuleLogicTest: StringSpec({
6767
assertThrows<InvalidMoveException> {
6868
invalidPieces.forEach {
6969
GameRuleLogic.performMove(gameState, SetMove(it))
70-
gameState.turn++
7170
}
7271
}
7372
}
7473
assertDoesNotThrow {
7574
val gameState = GameState(startPiece = PieceShape.PENTO_S)
7675
validPieces.forEach {
7776
GameRuleLogic.performMove(gameState, SetMove(it))
78-
gameState.turn++
7977
}
8078
}
8179
}

plugin/src/test/sc/plugin2021/GameStateTest.kt

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,52 +75,46 @@ class GameStateTest: StringSpec({
7575
xstream.fromXML(xstream.toXML(state)) shouldBe state
7676
}
7777
"GameStates advance accordingly" {
78-
var gameState = GameState(startTurn = 3)
79-
gameState.turn shouldBe 3
78+
var gameState = GameState(startTurn = 2)
79+
gameState.turn shouldBe 2
8080
gameState.round shouldBe 1
8181
gameState.currentColor shouldBe Color.RED
8282

8383
gameState = GameState()
84-
gameState.turn shouldBe 1
84+
gameState.turn shouldBe 0
8585
gameState.round shouldBe 1
8686
gameState.currentColor shouldBe Color.BLUE
8787

8888
gameState.turn +=10
89-
gameState.turn shouldBe 11
89+
gameState.turn shouldBe 10
9090
gameState.round shouldBe 3
9191
gameState.currentColor shouldBe Color.RED
9292

9393
gameState.turn++
94-
gameState.turn shouldBe 12
94+
gameState.turn shouldBe 11
9595
gameState.round shouldBe 3
9696
gameState.currentColor shouldBe Color.GREEN
9797

9898
gameState.turn++
99-
gameState.turn shouldBe 13
99+
gameState.turn shouldBe 12
100100
gameState.round shouldBe 4
101101
gameState.currentColor shouldBe Color.BLUE
102102
}
103103
"Passed out colors behave correctly" {
104-
val gameState = GameState(startTurn = 3)
104+
val gameState = GameState(startTurn = 2)
105105
gameState.orderedColors shouldBe listOf(Color.BLUE, Color.YELLOW, Color.RED, Color.GREEN)
106106
gameState.currentColor shouldBe Color.RED
107107

108108
GameRuleLogic.performMove(gameState, PassMove(Color.RED))
109109
gameState.orderedColors shouldBe listOf(Color.BLUE, Color.YELLOW, Color.GREEN)
110-
gameState.currentColor shouldBe Color.YELLOW
111-
gameState.turn++
112110
gameState.currentColor shouldBe Color.GREEN
113111

114112
GameRuleLogic.performMove(gameState, PassMove(Color.GREEN))
115113
gameState.orderedColors shouldBe listOf(Color.BLUE, Color.YELLOW)
116-
gameState.currentColor shouldBe Color.YELLOW
117-
gameState.turn++
118114
gameState.currentColor shouldBe Color.BLUE
119115

120116
GameRuleLogic.performMove(gameState, PassMove(Color.BLUE))
121117
gameState.orderedColors shouldBe listOf(Color.YELLOW)
122118
gameState.currentColor shouldBe Color.YELLOW
123-
gameState.turn++
124-
gameState.currentColor shouldBe Color.YELLOW
125119
}
126120
})

server/test/sc/server/plugins/TestGameState.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import sc.server.helpers.TestTeam
66

77
class TestGameState: IGameState {
88
override var turn = 0
9+
override val round get() = turn / 2
910
var state = 0
1011
var lastPlayerIndex = 0
1112
var currentPlayer: TestTeam

socha-sdk/src/server-api/sc/api/plugins/IGameState.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,4 @@ interface IGameState : ProtocolMessage, Cloneable {
3131

3232
/** Aktuelle Rundenzahl */
3333
val round: Int
34-
get() = turn / 2
3534
}

socha-sdk/src/server-api/sc/api/plugins/TwoPlayerGameState.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ abstract class TwoPlayerGameState<P : Player>(
2424
abstract val currentTeam: ITeam<*>
2525

2626
/** The Player whose team's turn it is. */
27-
val currentPlayer: P
27+
open val currentPlayer: P
2828
get() = getPlayer(currentTeam)!!
2929

3030
/** The player opposite to the currently active one. */

0 commit comments

Comments
 (0)