1
- package sc.plugin2019
1
+ package sc.plugin2026
2
2
3
3
import com.thoughtworks.xstream.annotations.XStreamAlias
4
4
import com.thoughtworks.xstream.annotations.XStreamAsAttribute
5
- import sc.api.plugins.Direction
6
5
import sc.api.plugins.ITeam
7
6
import sc.api.plugins.Stat
8
7
import sc.api.plugins.Team
9
8
import sc.api.plugins.TwoPlayerGameState
10
- import sc.plugin2026.Board
11
- import sc.plugin2026.FieldState
12
- import sc.plugin2026.Move
13
- import sc.plugin2026.PiranhaMoveMistake
9
+ import sc.framework.plugins.maxByNoEqual
14
10
import sc.plugin2026.util.GameRuleLogic
15
11
import sc.plugin2026.util.PiranhaConstants
16
- import sc.shared.IMoveMistake
12
+ import sc.plugin2026.util.PiranhasWinReason
17
13
import sc.shared.InvalidMoveException
18
- import sc.shared.MoveMistake
19
14
import sc.shared.WinCondition
15
+ import sc.shared.WinReasonTie
20
16
21
17
/* *
22
18
* The GameState class represents the current state of the game.
@@ -37,19 +33,31 @@ data class GameState @JvmOverloads constructor(
37
33
/* * Der zuletzt gespielte Zug. */
38
34
override var lastMove : Move ? = null ,
39
35
): TwoPlayerGameState<Move>(Team .ONE ) {
40
-
36
+
41
37
override fun getPointsForTeam (team : ITeam ): IntArray =
42
- GameRuleLogic .greatestSwarmSize(board, team) // TODO important
38
+ intArrayOf( GameRuleLogic .greatestSwarmSize(board, team))
43
39
44
40
// TODO test if one player is surrounded he loses
45
41
override val isOver: Boolean
46
- get() = players.any { it.inGoal } && turn.mod(2 ) == 0 || turn / 2 >= PiranhaConstants .ROUND_LIMIT
42
+ get() = Team .values().any { GameRuleLogic .isSwarmConnected(board, it) } && turn.mod(2 ) == 0 ||
43
+ turn / 2 >= PiranhaConstants .ROUND_LIMIT
47
44
48
45
override val winCondition: WinCondition ?
49
- get() = TODO (" Not yet implemented" )
46
+ get() {
47
+ val winners = Team .values().filter { team -> GameRuleLogic .isSwarmConnected(board, team) }
48
+ return when (winners.size) {
49
+ 0 -> null
50
+ 1 -> WinCondition (winners.single(), PiranhasWinReason .SOLE_SWARM )
51
+ else ->
52
+ winners.maxByNoEqual { team -> GameRuleLogic .greatestSwarmSize(board, team) }
53
+ ?.let {
54
+ WinCondition (it, PiranhasWinReason .BIGGER_SWARM )
55
+ } ? : WinCondition (null , WinReasonTie )
56
+ }
57
+ }
50
58
51
59
override fun performMoveDirectly (move : Move ) {
52
- if (board.getTeam(move.from) != currentTeam) {
60
+ if (board.getTeam(move.from) != currentTeam) {
53
61
throw InvalidMoveException (PiranhaMoveMistake .WRONG_START , move)
54
62
}
55
63
GameRuleLogic .checkMove(board, move)?.let { throw InvalidMoveException (it, move) }
@@ -59,12 +67,12 @@ data class GameState @JvmOverloads constructor(
59
67
}
60
68
61
69
override fun getSensibleMoves (): List <Move > {
62
- val piranhas = board.filterValues { field -> field.state.team == currentTeam }
63
- val moves = ArrayList <Move >(piranhas.size * 2 )
64
- for (piranha in piranhas) {
65
- moves.addAll(GameRuleLogic .possibleMovesFor(board, piranha.key))
66
- }
67
- return moves
70
+ val piranhas = board.filterValues { field -> field.state.team == currentTeam }
71
+ val moves = ArrayList <Move >(piranhas.size * 2 )
72
+ for (piranha in piranhas) {
73
+ moves.addAll(GameRuleLogic .possibleMovesFor(board, piranha.key))
74
+ }
75
+ return moves
68
76
}
69
77
70
78
override fun moveIterator (): Iterator <Move > =
@@ -73,7 +81,10 @@ data class GameState @JvmOverloads constructor(
73
81
override fun clone (): TwoPlayerGameState <Move > =
74
82
copy(board = board.clone())
75
83
76
- override fun teamStats (team : ITeam ): List <Stat > = listOf () // TODO
77
-
84
+ override fun teamStats (team : ITeam ): List <Stat > =
85
+ listOf (
86
+ Stat (" Fische" , board.fieldsForTeam(team).size),
87
+ Stat (" Schwarmgröße" , GameRuleLogic .greatestSwarmSize(board, team))
88
+ )
78
89
79
90
}
0 commit comments