Skip to content

Commit 0360fea

Browse files
committed
fix(plugin24): odd points
1 parent 27603a8 commit 0360fea

File tree

4 files changed

+49
-26
lines changed

4 files changed

+49
-26
lines changed

plugin/src/main/kotlin/sc/plugin2024/Board.kt

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,12 @@ data class Board(
2929
/** Corner coordinates, using offset system.
3030
* @return ((min-x, max-x), (min-y, max-y)) */
3131
val bounds
32-
get() = segments.fold(Pair(0 to 0, 0 to 0)) { acc, segment ->
33-
val center = segment.center
34-
val x = center.x / 2
35-
Pair(acc.first.first.coerceAtMost(x - 2) to acc.first.second.coerceAtLeast(x + 2),
36-
acc.second.first.coerceAtMost(center.r - 2) to acc.second.second.coerceAtLeast(center.r + 2))
37-
}
32+
get() = segments.bounds
3833

3934
/** Size of the map. */
4035
val rectangleSize: Coordinates
4136
get() = bounds.let { Coordinates(it.first.second - it.first.first + 1, it.second.second - it.second.first + 1) }
42-
37+
4338
override fun clone(): Board = copy(segments = this.segments.clone())
4439

4540
internal fun getNextDirection() =
@@ -68,17 +63,29 @@ data class Board(
6863
null
6964
}
7065

66+
// TODO check current on goal field
7167
fun doesFieldHaveCurrent(coords: CubeCoordinates): Boolean =
72-
segmentIndex(coords).let {
73-
if(it == -1)
74-
return@let false
75-
val segment = segments[it]
76-
val nextDirection = segments.getOrNull(it + 1)?.direction ?: nextDirection
77-
arrayOf(segment.center + segment.direction.opposite().vector,
68+
getFieldCurrentDirection(coords) != null
69+
70+
fun getFieldCurrentDirection(coords: CubeCoordinates): CubeDirection? =
71+
segmentIndex(coords).let { segmentIndex ->
72+
if(segmentIndex == -1)
73+
return null
74+
val segment = segments[segmentIndex]
75+
val nextDirection = segments.getOrNull(segmentIndex + 1)?.direction ?: nextDirection
76+
arrayOf(
77+
segment.center + segment.direction.opposite().vector,
7878
segment.center,
7979
segment.center + nextDirection.vector,
8080
segment.center + nextDirection.vector * 2
81-
).contains(coords)
81+
).indexOf(coords).let {
82+
when {
83+
it == -1 -> null
84+
segment[coords]?.isEmpty == false -> null
85+
it < 2 -> segment.direction.opposite()
86+
else -> nextDirection.opposite()
87+
}
88+
}
8289
}
8390

8491
/**

plugin/src/main/kotlin/sc/plugin2024/GameState.kt

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,22 +57,25 @@ data class GameState @JvmOverloads constructor(
5757
* 1. Weiter vorne
5858
* 2. Geschwindigkeit
5959
* 3. Kohle
60+
*
6061
* Ansonsten Startspieler zuerst.
6162
*/
6263
fun determineAheadTeam(): Team =
63-
ships.maxByOrNull {
64-
it.points * 100 +
65-
it.speed * 10 +
66-
it.coal
67-
}!!.team
64+
ships.maxByOrNull { ship ->
65+
shipAdvancePoints(ship) * 100 +
66+
ship.speed * 10 +
67+
ship.coal
68+
}?.team ?: startTeam
6869

69-
fun calculatePoints(ship: Ship) =
70+
fun shipAdvancePoints(ship: Ship) =
7071
board.segmentIndex(ship.position).let { segmentIndex ->
7172
segmentIndex * POINTS_PER_SEGMENT +
72-
board.segments[segmentIndex].globalToLocal(ship.position).arrayX + 1 +
73-
ship.passengers * PluginConstants.POINTS_PER_PASSENGER
73+
board.segments[segmentIndex].globalToLocal(ship.position).arrayX + 1
7474
}
7575

76+
fun calculatePoints(ship: Ship) =
77+
shipAdvancePoints(ship) + ship.passengers * PluginConstants.POINTS_PER_PASSENGER
78+
7679
fun isCurrentShipOnCurrent() =
7780
board.doesFieldHaveCurrent(currentShip.position)
7881

@@ -174,8 +177,7 @@ data class GameState @JvmOverloads constructor(
174177
if(move.isEmpty()) {
175178
state.getPossibleAccelerations().forEach { acc ->
176179
queue.add(state.copy(ships = ships.map { ship ->
177-
ship.takeUnless { it.team == state.currentTeam } ?:
178-
ship.clone().also { acc.accelerate(it) }
180+
ship.takeUnless { it.team == state.currentTeam } ?: ship.clone().also { acc.accelerate(it) }
179181
}) to listOf(acc))
180182
}
181183
}
@@ -330,7 +332,7 @@ data class GameState @JvmOverloads constructor(
330332
var currentPosition = start
331333
var totalCost = 0
332334
var hasCurrent = false
333-
val maxMovement = maxMovementPoints.coerceAtMost(PluginConstants.MAX_SPEED)
335+
val maxMovement = maxMovementPoints.coerceIn(0, PluginConstants.MAX_SPEED)
334336
val result = ArrayList<Int>(maxMovement)
335337

336338
fun result(condition: AdvanceProblem) =
@@ -384,6 +386,8 @@ data class GameState @JvmOverloads constructor(
384386
}
385387
}
386388

389+
// In rare cases this returns true on the server
390+
// even though the player cannot move because the target tile is not revealed yet
387391
fun canMove() = moveIterator().hasNext()
388392

389393
override val isOver: Boolean

plugin/src/main/kotlin/sc/plugin2024/Segment.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ typealias SegmentFields = Array<Array<Field>>
1919

2020
typealias Segments = List<Segment>
2121

22+
val Segments.bounds
23+
get() = fold(Pair(0 to 0, 0 to 0)) { acc, segment ->
24+
val center = segment.center
25+
val x = center.x / 2
26+
Pair(acc.first.first.coerceAtMost(x - 2) to acc.first.second.coerceAtLeast(x + 2),
27+
acc.second.first.coerceAtMost(center.r - 2) to acc.second.second.coerceAtLeast(center.r + 2))
28+
}
29+
2230
@XStreamAlias("segment")
2331
data class Segment(
2432
@XStreamAsAttribute val direction: CubeDirection,

plugin/src/main/kotlin/sc/plugin2024/actions/Advance.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,12 @@ data class Advance(
3333
): Action {
3434

3535
override fun perform(state: GameState): AdvanceProblem? {
36-
if(distance < PluginConstants.MIN_SPEED && state.board[state.currentShip.position] != Field.SANDBANK || distance > PluginConstants.MAX_SPEED)
36+
if(distance < PluginConstants.MIN_SPEED &&
37+
state.board[state.currentShip.position] != Field.SANDBANK ||
38+
distance > PluginConstants.MAX_SPEED)
3739
return AdvanceProblem.INVALID_DISTANCE
40+
if(distance > state.currentShip.movement)
41+
return AdvanceProblem.MOVEMENT_POINTS_MISSING
3842

3943
val result = state.checkAdvanceLimit(state.currentShip.position, if(distance > 0) state.currentShip.direction else state.currentShip.direction.opposite(), state.currentShip.movement)
4044
if(result.distance < distance.absoluteValue)

0 commit comments

Comments
 (0)