Replace EndGameCondition proto with Scala sealed trait (#5473)

Migrate ResolvedShardokPlayer to use native Scala EndGameCondition
instead of the proto type. This removes 1 transitive proto dependency
from library/ (75 → 74).

Changes:
- Add Scala EndGameCondition sealed trait with Victory, AllyVictory,
  Draw, and Loss cases
- Add DrawType enum for draw conditions
- Add EndGameConditionConverter in ShardokBattleConverter
- Update ResolvedShardokPlayer to use Scala EndGameCondition
- Move proto conversion to ShardokInterfaceGrpcClient boundary
- Update ResolveBattleAction to use Scala EndGameCondition API
- Update ResolveBattleActionTest to construct Scala EndGameCondition

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-20 17:06:12 -08:00
committed by GitHub
co-authored by Claude Opus 4.5
parent b7afd6d6ad
commit 5599d07247
10 changed files with 157 additions and 157 deletions
+2 -2
View File
@@ -1,3 +1,3 @@
# BUILD dependency baseline - updated Mon Jan 19 22:38:21 PST 2026
# BUILD dependency baseline - updated Tue Jan 20 07:20:54 PST 2026
# Do not increase these numbers - only decrease!
library_proto_deps=75
library_proto_deps=74
@@ -158,7 +158,7 @@ case class ResolveBattleAction(
battleResolution: BattleResolution
): Vector[ActionResultT] =
battleResolution.resolvedPlayers.toVector.partition(
_.endGameCondition.condition.isVictory
_.endGameCondition.isVictory
) match {
case (winners, losers) =>
winners
@@ -228,7 +228,6 @@ case class ResolveBattleAction(
.find(_.eagleFid == u.hero.factionId.get)
.get
.endGameCondition
.condition
.isVictory,
isAttacker = isAttacker,
startingState = startingState
@@ -277,7 +276,7 @@ case class ResolveBattleAction(
val (winningResolvedPlayers, losingResolvedPlayers) =
battleResolution.resolvedPlayers.toVector.partition(
_.endGameCondition.condition.isVictory
_.endGameCondition.isVictory
)
val battleEndedResults = actionResultApplier.applyActionResults(
@@ -537,7 +536,7 @@ case class ResolveBattleAction(
.toVector,
removedBattalionIds = destroyedBattalionIds,
fid = ma.army.factionId,
fleeProvinceId = Option.when(rsp.endGameCondition.condition.isAllyVictory)(
fleeProvinceId = Option.when(rsp.endGameCondition.isAllyVictory)(
ma.destinationProvinceId
)
)
@@ -616,11 +615,11 @@ case class ResolveBattleAction(
.army
.fleeProvinceId
.isDefined &&
!out.endGameCondition.condition.isVictory
!out.endGameCondition.isVictory
case UnitStatus.Captured =>
out.endGameCondition.condition.isDraw || out.endGameCondition.condition.isAllyVictory
out.endGameCondition.isDraw || out.endGameCondition.isAllyVictory
case UnitStatus.Normal =>
out.endGameCondition.condition.isDraw || out.endGameCondition.condition.isAllyVictory
out.endGameCondition.isDraw || out.endGameCondition.isAllyVictory
case UnitStatus.Retreated => false
case UnitStatus.Outlawed => false
}
@@ -22,5 +22,6 @@ scala_library(
"//src/main/scala/net/eagle0/eagle/model/proto_converters:proto_conversion_exception",
"//src/main/scala/net/eagle0/eagle/model/state:army",
"//src/main/scala/net/eagle0/eagle/model/state/shardok_battle",
"//src/main/scala/net/eagle0/eagle/model/state/shardok_battle:end_game_condition",
],
)
@@ -1,6 +1,10 @@
package net.eagle0.eagle.model.proto_converters.shardok_battle
import net.eagle0.common.victory_condition.VictoryCondition as VictoryConditionProto
import net.eagle0.common.victory_condition.{
DrawType as DrawTypeProto,
EndGameCondition as EndGameConditionProto,
VictoryCondition as VictoryConditionProto
}
import net.eagle0.eagle.{GameId, ProvinceId, RoundId, ShardokGameId}
import net.eagle0.eagle.internal.army.HostileArmyGroup as HostileArmyGroupProto
import net.eagle0.eagle.internal.shardok_battle.{
@@ -8,7 +12,14 @@ import net.eagle0.eagle.internal.shardok_battle.{
ShardokPlayer as ShardokPlayerProto
}
import net.eagle0.eagle.model.proto_converters.{ArmyConverter, ProtoConversionException}
import net.eagle0.eagle.model.state.shardok_battle.{BattleType, ShardokBattle, ShardokPlayer, VictoryCondition}
import net.eagle0.eagle.model.state.shardok_battle.{
BattleType,
DrawType,
EndGameCondition,
ShardokBattle,
ShardokPlayer,
VictoryCondition
}
object ShardokBattleConverter {
@@ -141,7 +152,7 @@ object ShardokBattleConverter {
VictoryConditionProto.VICTORY_CONDITION_LAST_ALLIANCE_STANDING
}
private def fromProto(
private[shardok_battle] def victoryConditionFromProto(
victoryConditionProto: VictoryConditionProto
): VictoryCondition =
victoryConditionProto match {
@@ -162,4 +173,39 @@ object ShardokBattleConverter {
s"Unknown VictoryCondition value: $value"
)
}
private def fromProto(
victoryConditionProto: VictoryConditionProto
): VictoryCondition = victoryConditionFromProto(victoryConditionProto)
}
object EndGameConditionConverter {
def fromProto(proto: EndGameConditionProto): EndGameCondition =
proto.condition match {
case EndGameConditionProto.Condition.Victory(vc) =>
EndGameCondition.Victory(
ShardokBattleConverter.victoryConditionFromProto(vc)
)
case EndGameConditionProto.Condition.AllyVictory(vc) =>
EndGameCondition.AllyVictory(
ShardokBattleConverter.victoryConditionFromProto(vc)
)
case EndGameConditionProto.Condition.Draw(dt) =>
EndGameCondition.Draw(drawTypeFromProto(dt))
case EndGameConditionProto.Condition.Loss(vc) =>
EndGameCondition.Loss(
ShardokBattleConverter.victoryConditionFromProto(vc)
)
case EndGameConditionProto.Condition.Empty =>
throw new ProtoConversionException("EndGameCondition has empty condition")
}
private def drawTypeFromProto(proto: DrawTypeProto): DrawType =
proto match {
case DrawTypeProto.UNKNOWN_DRAW_TYPE => DrawType.Unknown
case DrawTypeProto.DRAW_AFTER_MAX_ROUNDS => DrawType.AfterMaxRounds
case DrawTypeProto.Unrecognized(value) =>
throw new ProtoConversionException(s"Unknown DrawType value: $value")
}
}
@@ -1,5 +1,18 @@
load("@rules_scala//scala:scala.bzl", "scala_library")
scala_library(
name = "end_game_condition",
srcs = ["EndGameCondition.scala"],
visibility = [
"//src/main/scala/net/eagle0/eagle/model/proto_converters/shardok_battle:__pkg__",
"//src/main/scala/net/eagle0/eagle/shardok_interface:__pkg__",
"//src/test/scala/net/eagle0/eagle/library/actions/impl/action:__pkg__",
],
deps = [
":shardok_battle",
],
)
scala_library(
name = "shardok_battle",
srcs = ["ShardokBattle.scala"],
@@ -0,0 +1,32 @@
package net.eagle0.eagle.model.state.shardok_battle
enum DrawType {
case Unknown, AfterMaxRounds
}
enum EndGameCondition {
case Victory(condition: VictoryCondition)
case AllyVictory(condition: VictoryCondition)
case Draw(drawType: DrawType)
case Loss(condition: VictoryCondition)
def isVictory: Boolean = this match {
case Victory(_) => true
case _ => false
}
def isAllyVictory: Boolean = this match {
case AllyVictory(_) => true
case _ => false
}
def isDraw: Boolean = this match {
case Draw(_) => true
case _ => false
}
def isLoss: Boolean = this match {
case Loss(_) => true
case _ => false
}
}
@@ -109,12 +109,12 @@ scala_library(
"//src/test/scala/net/eagle0/eagle:__subpackages__",
],
exports = [
"//src/main/protobuf/net/eagle0/common:victory_condition_scala_proto",
"//src/main/scala/net/eagle0/eagle/model/state/shardok_battle:end_game_condition",
],
deps = [
":resolved_eagle_unit",
"//src/main/protobuf/net/eagle0/common:victory_condition_scala_proto",
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
"//src/main/scala/net/eagle0/eagle/model/state/shardok_battle:end_game_condition",
],
)
@@ -1,6 +1,6 @@
package net.eagle0.eagle.shardok_interface
import net.eagle0.common.victory_condition.EndGameCondition
import net.eagle0.eagle.model.state.shardok_battle.EndGameCondition
import net.eagle0.eagle.FactionId
case class ResolvedShardokPlayer(
@@ -27,7 +27,7 @@ import net.eagle0.eagle.library.util.faction_utils.FactionUtils
import net.eagle0.eagle.library.util.hero.HeroUtils
import net.eagle0.eagle.model.proto_converters.faction.FactionConverter
import net.eagle0.eagle.model.proto_converters.hero.HeroConverter
import net.eagle0.eagle.model.proto_converters.shardok_battle.ShardokBattleConverter
import net.eagle0.eagle.model.proto_converters.shardok_battle.{EndGameConditionConverter, ShardokBattleConverter}
import net.eagle0.eagle.model.proto_converters.BattalionConverter
import net.eagle0.eagle.model.state.unit_status.UnitStatus
import net.eagle0.shardok.api.placement_command.PlacementCommand
@@ -175,7 +175,7 @@ class ShardokInterfaceGrpcClient(
resolvedPlayers = gameOverResponse.userInfos.map(ui =>
ResolvedShardokPlayer(
eagleFid = ui.eagleFactionId,
endGameCondition = ui.endGameCondition.get,
endGameCondition = EndGameConditionConverter.fromProto(ui.endGameCondition.get),
units = ui.units.map { ru =>
val commonUnit = ru.unit.get
val eagleUnit = fromCommon(commonUnit)
@@ -1,6 +1,5 @@
package net.eagle0.eagle.library.actions.impl.action
import net.eagle0.common.victory_condition.{DrawType, EndGameCondition, VictoryCondition}
import net.eagle0.common.ProtoMatchers
import net.eagle0.eagle.common.action_result_type.ActionResultType.{
BATTLE_ENDED,
@@ -54,6 +53,7 @@ import net.eagle0.eagle.model.proto_converters.hero.HeroConverter
import net.eagle0.eagle.model.proto_converters.shardok_battle.ShardokBattleConverter
import net.eagle0.eagle.model.proto_converters.ActionResultProtoConverter
import net.eagle0.eagle.model.proto_converters.BattalionConverter
import net.eagle0.eagle.model.state.shardok_battle.{DrawType, EndGameCondition, VictoryCondition}
import net.eagle0.eagle.model.state.unit_status.UnitStatus
import net.eagle0.eagle.shardok_interface.{BattleResolution, EagleUnit, ResolvedEagleUnit, ResolvedShardokPlayer}
import net.eagle0.eagle.views.battalion_view.BattalionView
@@ -367,7 +367,7 @@ class ResolveBattleActionTest
private def resolvedPlayers(
units: Vector[ResolvedEagleUnit],
resolution: FactionId => EndGameCondition.Condition
resolution: FactionId => EndGameCondition
): Vector[ResolvedShardokPlayer] =
units
.groupBy(_.hero.factionId.get)
@@ -376,7 +376,7 @@ class ResolveBattleActionTest
ResolvedShardokPlayer(
eagleFid = fid,
units = units,
endGameCondition = EndGameCondition(resolution(fid))
endGameCondition = resolution(fid)
)
}
.toVector
@@ -384,39 +384,27 @@ class ResolveBattleActionTest
private val resolvedPlayersWithAttackerVictory = resolvedPlayers(
resolvedExpandedUnits,
Map(
attackerFid -> EndGameCondition.Condition
.Victory(VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING),
defenderFid -> EndGameCondition.Condition
.Loss(VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING),
allyFid -> EndGameCondition.Condition.AllyVictory(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
attackerFid -> EndGameCondition.Victory(VictoryCondition.LastPlayerStanding),
defenderFid -> EndGameCondition.Loss(VictoryCondition.LastPlayerStanding),
allyFid -> EndGameCondition.AllyVictory(VictoryCondition.LastPlayerStanding)
)
)
private val resolvedPlayersWithDefenderVictory = resolvedPlayers(
resolvedExpandedUnits,
Map(
attackerFid -> EndGameCondition.Condition
.Loss(VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING),
defenderFid -> EndGameCondition.Condition
.Victory(VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING),
allyFid -> EndGameCondition.Condition.Loss(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
attackerFid -> EndGameCondition.Loss(VictoryCondition.LastPlayerStanding),
defenderFid -> EndGameCondition.Victory(VictoryCondition.LastPlayerStanding),
allyFid -> EndGameCondition.Loss(VictoryCondition.LastPlayerStanding)
)
)
private val resolvedPlayersWithAttackerVictoryWithAllies = resolvedPlayers(
resolvedExpandedUnitsWithAllies,
Map(
attackerFid -> EndGameCondition.Condition
.Victory(VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING),
defenderFid -> EndGameCondition.Condition
.Loss(VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING),
allyFid -> EndGameCondition.Condition.AllyVictory(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
attackerFid -> EndGameCondition.Victory(VictoryCondition.LastPlayerStanding),
defenderFid -> EndGameCondition.Loss(VictoryCondition.LastPlayerStanding),
allyFid -> EndGameCondition.AllyVictory(VictoryCondition.LastPlayerStanding)
)
)
@@ -424,13 +412,9 @@ class ResolveBattleActionTest
resolvedPlayers(
resolvedExpandedUnitsWithCapturedAlly,
Map(
attackerFid -> EndGameCondition.Condition
.Victory(VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING),
defenderFid -> EndGameCondition.Condition
.Loss(VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING),
allyFid -> EndGameCondition.Condition.AllyVictory(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
attackerFid -> EndGameCondition.Victory(VictoryCondition.LastPlayerStanding),
defenderFid -> EndGameCondition.Loss(VictoryCondition.LastPlayerStanding),
allyFid -> EndGameCondition.AllyVictory(VictoryCondition.LastPlayerStanding)
)
)
@@ -660,13 +644,9 @@ class ResolveBattleActionTest
UnitStatus.Outlawed
),
Map(
attackerFid -> EndGameCondition.Condition
.Victory(VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING),
defenderFid -> EndGameCondition.Condition
.Loss(VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING),
allyFid -> EndGameCondition.Condition.AllyVictory(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
attackerFid -> EndGameCondition.Victory(VictoryCondition.LastPlayerStanding),
defenderFid -> EndGameCondition.Loss(VictoryCondition.LastPlayerStanding),
allyFid -> EndGameCondition.AllyVictory(VictoryCondition.LastPlayerStanding)
)
)
@@ -737,15 +717,9 @@ class ResolveBattleActionTest
ResolvedShardokPlayer(
eagleFid = fid,
units = units,
endGameCondition = EndGameCondition(
if fid == attackerFid then
EndGameCondition.Condition.Victory(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
else
EndGameCondition.Condition
.Loss(VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING)
)
endGameCondition =
if fid == attackerFid then EndGameCondition.Victory(VictoryCondition.LastPlayerStanding)
else EndGameCondition.Loss(VictoryCondition.LastPlayerStanding)
)
}
.toVector
@@ -811,15 +785,9 @@ class ResolveBattleActionTest
ResolvedShardokPlayer(
eagleFid = fid,
units = units,
endGameCondition = EndGameCondition(
if fid == attackerFid then
EndGameCondition.Condition.Victory(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
else
EndGameCondition.Condition
.Loss(VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING)
)
endGameCondition =
if fid == attackerFid then EndGameCondition.Victory(VictoryCondition.LastPlayerStanding)
else EndGameCondition.Loss(VictoryCondition.LastPlayerStanding)
)
}
.toVector
@@ -880,13 +848,9 @@ class ResolveBattleActionTest
UnitStatus.Outlawed
),
Map(
attackerFid -> EndGameCondition.Condition
.Victory(VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING),
defenderFid -> EndGameCondition.Condition
.Loss(VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING),
allyFid -> EndGameCondition.Condition.AllyVictory(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
attackerFid -> EndGameCondition.Victory(VictoryCondition.LastPlayerStanding),
defenderFid -> EndGameCondition.Loss(VictoryCondition.LastPlayerStanding),
allyFid -> EndGameCondition.AllyVictory(VictoryCondition.LastPlayerStanding)
)
)
@@ -1109,17 +1073,9 @@ class ResolveBattleActionTest
ResolvedShardokPlayer(
eagleFid = fid,
units = units,
endGameCondition = EndGameCondition(
if fid == attackerFid then
EndGameCondition.Condition.Victory(
VictoryCondition.VICTORY_CONDITION_HOLDS_CRITICAL_TILES
)
else
EndGameCondition.Condition
.Loss(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
)
endGameCondition =
if fid == attackerFid then EndGameCondition.Victory(VictoryCondition.HoldsCriticalTiles)
else EndGameCondition.Loss(VictoryCondition.LastPlayerStanding)
)
}
.toVector
@@ -1173,17 +1129,9 @@ class ResolveBattleActionTest
ResolvedShardokPlayer(
eagleFid = fid,
units = units,
endGameCondition = EndGameCondition(
if fid == attackerFid then
EndGameCondition.Condition.Victory(
VictoryCondition.VICTORY_CONDITION_HOLDS_CRITICAL_TILES
)
else
EndGameCondition.Condition
.Loss(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
)
endGameCondition =
if fid == attackerFid then EndGameCondition.Victory(VictoryCondition.HoldsCriticalTiles)
else EndGameCondition.Loss(VictoryCondition.LastPlayerStanding)
)
}
.toVector
@@ -1335,15 +1283,9 @@ class ResolveBattleActionTest
ResolvedShardokPlayer(
eagleFid = fid,
units = units,
endGameCondition = EndGameCondition(
if fid == defenderFid then
EndGameCondition.Condition.Victory(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
else
EndGameCondition.Condition
.Loss(VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING)
)
endGameCondition =
if fid == defenderFid then EndGameCondition.Victory(VictoryCondition.LastPlayerStanding)
else EndGameCondition.Loss(VictoryCondition.LastPlayerStanding)
)
}
.toVector
@@ -1412,15 +1354,9 @@ class ResolveBattleActionTest
ResolvedShardokPlayer(
eagleFid = fid,
units = units,
endGameCondition = EndGameCondition(
if fid == defenderFid then
EndGameCondition.Condition.Victory(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
else
EndGameCondition.Condition
.Loss(VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING)
)
endGameCondition =
if fid == defenderFid then EndGameCondition.Victory(VictoryCondition.LastPlayerStanding)
else EndGameCondition.Loss(VictoryCondition.LastPlayerStanding)
)
}
.toVector
@@ -1490,17 +1426,9 @@ class ResolveBattleActionTest
ResolvedShardokPlayer(
eagleFid = fid,
units = units,
endGameCondition = EndGameCondition(
if fid == defenderFid then
EndGameCondition.Condition.Victory(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
else
EndGameCondition.Condition
.Loss(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
)
endGameCondition =
if fid == defenderFid then EndGameCondition.Victory(VictoryCondition.LastPlayerStanding)
else EndGameCondition.Loss(VictoryCondition.LastPlayerStanding)
)
}
.toVector
@@ -1554,17 +1482,9 @@ class ResolveBattleActionTest
ResolvedShardokPlayer(
eagleFid = fid,
units = units,
endGameCondition = EndGameCondition(
if fid == defenderFid then
EndGameCondition.Condition.Victory(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
else
EndGameCondition.Condition
.Loss(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
)
endGameCondition =
if fid == defenderFid then EndGameCondition.Victory(VictoryCondition.LastPlayerStanding)
else EndGameCondition.Loss(VictoryCondition.LastPlayerStanding)
)
}
.toVector
@@ -1673,11 +1593,7 @@ class ResolveBattleActionTest
ResolvedShardokPlayer(
eagleFid = fid,
units = units,
endGameCondition = EndGameCondition(
EndGameCondition.Condition.Draw(
DrawType.DRAW_AFTER_MAX_ROUNDS
)
)
endGameCondition = EndGameCondition.Draw(DrawType.AfterMaxRounds)
)
}
.toVector
@@ -1999,16 +1915,9 @@ class ResolveBattleActionTest
ResolvedShardokPlayer(
eagleFid = fid,
units = units,
endGameCondition = EndGameCondition(
if fid == defenderFid then
EndGameCondition.Condition.Victory(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
else
EndGameCondition.Condition.Loss(
VictoryCondition.VICTORY_CONDITION_LAST_PLAYER_STANDING
)
)
endGameCondition =
if fid == defenderFid then EndGameCondition.Victory(VictoryCondition.LastPlayerStanding)
else EndGameCondition.Loss(VictoryCondition.LastPlayerStanding)
)
}
.toVector