Skip to content

Commit

Permalink
fix(plugin24): odd points
Browse files Browse the repository at this point in the history
  • Loading branch information
xeruf committed Sep 9, 2023
1 parent 27603a8 commit 0360fea
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 26 deletions.
35 changes: 21 additions & 14 deletions plugin/src/main/kotlin/sc/plugin2024/Board.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,12 @@ data class Board(
/** Corner coordinates, using offset system.
* @return ((min-x, max-x), (min-y, max-y)) */
val bounds
get() = segments.fold(Pair(0 to 0, 0 to 0)) { acc, segment ->
val center = segment.center
val x = center.x / 2
Pair(acc.first.first.coerceAtMost(x - 2) to acc.first.second.coerceAtLeast(x + 2),
acc.second.first.coerceAtMost(center.r - 2) to acc.second.second.coerceAtLeast(center.r + 2))
}
get() = segments.bounds

/** Size of the map. */
val rectangleSize: Coordinates
get() = bounds.let { Coordinates(it.first.second - it.first.first + 1, it.second.second - it.second.first + 1) }

override fun clone(): Board = copy(segments = this.segments.clone())

internal fun getNextDirection() =
Expand Down Expand Up @@ -68,17 +63,29 @@ data class Board(
null
}

// TODO check current on goal field
fun doesFieldHaveCurrent(coords: CubeCoordinates): Boolean =
segmentIndex(coords).let {
if(it == -1)
return@let false
val segment = segments[it]
val nextDirection = segments.getOrNull(it + 1)?.direction ?: nextDirection
arrayOf(segment.center + segment.direction.opposite().vector,
getFieldCurrentDirection(coords) != null

fun getFieldCurrentDirection(coords: CubeCoordinates): CubeDirection? =
segmentIndex(coords).let { segmentIndex ->
if(segmentIndex == -1)
return null
val segment = segments[segmentIndex]
val nextDirection = segments.getOrNull(segmentIndex + 1)?.direction ?: nextDirection
arrayOf(
segment.center + segment.direction.opposite().vector,
segment.center,
segment.center + nextDirection.vector,
segment.center + nextDirection.vector * 2
).contains(coords)
).indexOf(coords).let {
when {
it == -1 -> null
segment[coords]?.isEmpty == false -> null
it < 2 -> segment.direction.opposite()
else -> nextDirection.opposite()
}
}
}

/**
Expand Down
26 changes: 15 additions & 11 deletions plugin/src/main/kotlin/sc/plugin2024/GameState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,22 +57,25 @@ data class GameState @JvmOverloads constructor(
* 1. Weiter vorne
* 2. Geschwindigkeit
* 3. Kohle
*
* Ansonsten Startspieler zuerst.
*/
fun determineAheadTeam(): Team =
ships.maxByOrNull {
it.points * 100 +
it.speed * 10 +
it.coal
}!!.team
ships.maxByOrNull { ship ->
shipAdvancePoints(ship) * 100 +
ship.speed * 10 +
ship.coal
}?.team ?: startTeam

fun calculatePoints(ship: Ship) =
fun shipAdvancePoints(ship: Ship) =
board.segmentIndex(ship.position).let { segmentIndex ->
segmentIndex * POINTS_PER_SEGMENT +
board.segments[segmentIndex].globalToLocal(ship.position).arrayX + 1 +
ship.passengers * PluginConstants.POINTS_PER_PASSENGER
board.segments[segmentIndex].globalToLocal(ship.position).arrayX + 1
}

fun calculatePoints(ship: Ship) =
shipAdvancePoints(ship) + ship.passengers * PluginConstants.POINTS_PER_PASSENGER

fun isCurrentShipOnCurrent() =
board.doesFieldHaveCurrent(currentShip.position)

Expand Down Expand Up @@ -174,8 +177,7 @@ data class GameState @JvmOverloads constructor(
if(move.isEmpty()) {
state.getPossibleAccelerations().forEach { acc ->
queue.add(state.copy(ships = ships.map { ship ->
ship.takeUnless { it.team == state.currentTeam } ?:
ship.clone().also { acc.accelerate(it) }
ship.takeUnless { it.team == state.currentTeam } ?: ship.clone().also { acc.accelerate(it) }
}) to listOf(acc))
}
}
Expand Down Expand Up @@ -330,7 +332,7 @@ data class GameState @JvmOverloads constructor(
var currentPosition = start
var totalCost = 0
var hasCurrent = false
val maxMovement = maxMovementPoints.coerceAtMost(PluginConstants.MAX_SPEED)
val maxMovement = maxMovementPoints.coerceIn(0, PluginConstants.MAX_SPEED)
val result = ArrayList<Int>(maxMovement)

fun result(condition: AdvanceProblem) =
Expand Down Expand Up @@ -384,6 +386,8 @@ data class GameState @JvmOverloads constructor(
}
}

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

override val isOver: Boolean
Expand Down
8 changes: 8 additions & 0 deletions plugin/src/main/kotlin/sc/plugin2024/Segment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ typealias SegmentFields = Array<Array<Field>>

typealias Segments = List<Segment>

val Segments.bounds
get() = fold(Pair(0 to 0, 0 to 0)) { acc, segment ->
val center = segment.center
val x = center.x / 2
Pair(acc.first.first.coerceAtMost(x - 2) to acc.first.second.coerceAtLeast(x + 2),
acc.second.first.coerceAtMost(center.r - 2) to acc.second.second.coerceAtLeast(center.r + 2))
}

@XStreamAlias("segment")
data class Segment(
@XStreamAsAttribute val direction: CubeDirection,
Expand Down
6 changes: 5 additions & 1 deletion plugin/src/main/kotlin/sc/plugin2024/actions/Advance.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ data class Advance(
): Action {

override fun perform(state: GameState): AdvanceProblem? {
if(distance < PluginConstants.MIN_SPEED && state.board[state.currentShip.position] != Field.SANDBANK || distance > PluginConstants.MAX_SPEED)
if(distance < PluginConstants.MIN_SPEED &&
state.board[state.currentShip.position] != Field.SANDBANK ||
distance > PluginConstants.MAX_SPEED)
return AdvanceProblem.INVALID_DISTANCE
if(distance > state.currentShip.movement)
return AdvanceProblem.MOVEMENT_POINTS_MISSING

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

0 comments on commit 0360fea

Please sign in to comment.