mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-28 21:35:42 +00:00
Expose recommended Shardok placements (#8559)
This commit is contained in:
@@ -133,6 +133,20 @@ Shardok update with no available commands clears the previous command list.
|
||||
|
||||
Use `shardok-commands-json` or `shardok-units-json` when the concise output omits a needed field.
|
||||
|
||||
During battle setup, `shardok-commands` prints any server-recommended unit placements in order and identifies the
|
||||
ordinary current command index for the next recommendation:
|
||||
|
||||
```text
|
||||
recommended-starting-positions (ordered):
|
||||
[0] unit=12 target=(3,4)
|
||||
[1] unit=15 target=(4,4)
|
||||
use next: post-shardok <shardok-game-id> 17
|
||||
```
|
||||
|
||||
The list is advice, not an automatic placement batch. Review it against `shardok-map`, choose whether to use the first
|
||||
recommendation, and submit that one placement with the printed `post-shardok` command. After every placement, wait for
|
||||
the updated state and run `shardok-commands` again; the legal command indices and remaining recommendations may change.
|
||||
|
||||
The client synchronizes Shardok map definitions when it connects. To inspect the
|
||||
base terrain together with current tile modifiers and occupying units, use:
|
||||
|
||||
|
||||
@@ -1164,21 +1164,39 @@ final class ClientState {
|
||||
s"battle ${battle.shardokGameId} token=${battle.token} status=${battle.status.map(_.status).getOrElse("-")}"
|
||||
battle.availableCommands match {
|
||||
case Some(commands) =>
|
||||
val currentLines =
|
||||
val currentLines =
|
||||
if commands.currentCommand.nonEmpty then
|
||||
"current:" +: commands.currentCommand.zipWithIndex.map {
|
||||
case (cmd, index) =>
|
||||
s" [$index] ${shardokCommandSummary(cmd, rawJson)}"
|
||||
}
|
||||
else Vector("current: none")
|
||||
val previewLines =
|
||||
val previewLines =
|
||||
if commands.previewCommand.nonEmpty then
|
||||
"preview:" +: commands.previewCommand.zipWithIndex.map {
|
||||
case (cmd, index) =>
|
||||
s" [$index] ${shardokCommandSummary(cmd, rawJson)}"
|
||||
}
|
||||
else Vector.empty
|
||||
Vector(header) ++ currentLines ++ previewLines
|
||||
val recommendedLines =
|
||||
if commands.recommendedStartingPositions.nonEmpty then
|
||||
val next = commands.recommendedStartingPositions.head
|
||||
val commandIndex = commands.currentCommand.indexWhere { command =>
|
||||
command.actor.contains(next.unitId) &&
|
||||
command.target.exists(target => target.row == next.row && target.column == next.column)
|
||||
}
|
||||
val placements = commands.recommendedStartingPositions.zipWithIndex.map {
|
||||
case (placement, index) =>
|
||||
val summary =
|
||||
s" [$index] unit=${placement.unitId} target=(${placement.row},${placement.column})"
|
||||
if rawJson then s"$summary ${JsonFormat.toJsonString(placement)}" else summary
|
||||
}
|
||||
val useNext =
|
||||
if commandIndex >= 0 then s"use next: post-shardok ${battle.shardokGameId} $commandIndex"
|
||||
else "next recommended placement is not present in the current command list"
|
||||
Vector("recommended-starting-positions (ordered):") ++ placements ++ Vector(useNext)
|
||||
else Vector.empty
|
||||
Vector(header) ++ currentLines ++ previewLines ++ recommendedLines
|
||||
case None =>
|
||||
Vector(header, "current: no command payload")
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import net.eagle0.eagle.views.tutorial_dialogue.{TutorialDialogue, TutorialDialo
|
||||
import net.eagle0.shardok.api.action_result_view.ActionResultView as ShardokActionResultView
|
||||
import net.eagle0.shardok.api.command_descriptor.{AvailableCommands, CommandDescriptor}
|
||||
import net.eagle0.shardok.api.game_state_view.GameStateViewDiff as ShardokGameStateViewDiff
|
||||
import net.eagle0.shardok.api.placement_command.PlacementCommand
|
||||
import net.eagle0.shardok.api.unit_view.{BattalionView, HeroView as ShardokHeroView, UnitView}
|
||||
import net.eagle0.shardok.common.coords.Coords
|
||||
import net.eagle0.shardok.common.game_status.GameStatus
|
||||
@@ -378,6 +379,39 @@ class ClientStateTest extends AnyFlatSpec with Matchers {
|
||||
state.shardokCommandPost(Some("battle-1"), index = 0) shouldBe None
|
||||
}
|
||||
|
||||
it should "describe recommended starting positions and identify the next ordinary command" in {
|
||||
val state = new ClientState
|
||||
val placements = Vector(
|
||||
PlacementCommand(unitId = 12, row = 3, column = 4),
|
||||
PlacementCommand(unitId = 15, row = 4, column = 4)
|
||||
)
|
||||
state.handle(startingState("battle-1"))
|
||||
state.handle(
|
||||
shardokUpdate(
|
||||
"battle-1",
|
||||
Some(
|
||||
AvailableCommands(
|
||||
currentCommand = Vector(
|
||||
CommandDescriptor(player = 3),
|
||||
CommandDescriptor(
|
||||
player = 3,
|
||||
actor = Some(12),
|
||||
target = Some(Coords(row = 3, column = 4))
|
||||
)
|
||||
),
|
||||
recommendedStartingPositions = placements
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val output = state.describeShardokCommands(rawJson = false)
|
||||
output should include("recommended-starting-positions (ordered):")
|
||||
output should include("[0] unit=12 target=(3,4)")
|
||||
output should include("[1] unit=15 target=(4,4)")
|
||||
output should include("use next: post-shardok battle-1 1")
|
||||
}
|
||||
|
||||
it should "describe tactical conditions, unit health, and temporary effects" in {
|
||||
val state = new ClientState
|
||||
val diff = ShardokGameStateViewDiff(
|
||||
|
||||
Reference in New Issue
Block a user