refactor: fleet/group AtPlanet

This commit is contained in:
Ilia Denisov
2026-02-05 15:49:51 +02:00
parent e90218368c
commit fef1be577d
7 changed files with 24 additions and 21 deletions
+13 -14
View File
@@ -17,7 +17,7 @@ type FleetState struct {
State game.ShipGroupState State game.ShipGroupState
Destination uint Destination uint
InSpace func() (game.InSpace, bool) InSpace func() (game.InSpace, bool)
OnPlanet func() (uint, bool) AtPlanet func() (uint, bool)
} }
func (fs *FleetState) inSpace() bool { func (fs *FleetState) inSpace() bool {
@@ -25,16 +25,16 @@ func (fs *FleetState) inSpace() bool {
return ok return ok
} }
func (fs FleetState) OnSamePlanet(other FleetState) bool { func (fs FleetState) AtSamePlanet(other FleetState) bool {
op1, ok := fs.OnPlanet() pn1, ok := fs.AtPlanet()
if !ok { if !ok {
return false return false
} }
op2, ok := other.OnPlanet() pn2, ok := other.AtPlanet()
if !ok { if !ok {
return false return false
} }
return op1 == op2 return pn1 == pn2
} }
func (c *Cache) FleetState(fleetID uuid.UUID) FleetState { func (c *Cache) FleetState(fleetID uuid.UUID) FleetState {
@@ -43,16 +43,15 @@ func (c *Cache) FleetState(fleetID uuid.UUID) FleetState {
fs := &FleetState{ fs := &FleetState{
State: fleetStateNil, State: fleetStateNil,
InSpace: func() (game.InSpace, bool) { return game.InSpace{}, false }, InSpace: func() (game.InSpace, bool) { return game.InSpace{}, false },
OnPlanet: func() (uint, bool) { return 0, false }, AtPlanet: func() (uint, bool) { return 0, false },
} }
for sg := range c.FleetGroups(ri, fi) { for sg := range c.FleetGroups(ri, fi) {
if fs.State == fleetStateNil { if fs.State == fleetStateNil {
fs.State = sg.State() fs.State = sg.State()
fs.Destination = sg.Destination fs.Destination = sg.Destination
if planet, ok := sg.OnPlanet(); ok { if pn, ok := sg.AtPlanet(); ok {
fs.OnPlanet = func() (uint, bool) { return planet, ok } fs.AtPlanet = func() (uint, bool) { return pn, ok }
} } else if sg.StateInSpace != nil {
if sg.StateInSpace != nil {
fs.InSpace = func() (game.InSpace, bool) { return *sg.StateInSpace, true } fs.InSpace = func() (game.InSpace, bool) { return *sg.StateInSpace, true }
} }
continue continue
@@ -63,8 +62,8 @@ func (c *Cache) FleetState(fleetID uuid.UUID) FleetState {
if fs.Destination != sg.Destination { if fs.Destination != sg.Destination {
panic(fmt.Sprintf("FleetState: one or more ships in race's %q fleet %q has different destination", c.g.Race[ri].Name, c.g.Fleets[fi].Name)) panic(fmt.Sprintf("FleetState: one or more ships in race's %q fleet %q has different destination", c.g.Race[ri].Name, c.g.Fleets[fi].Name))
} }
if planet, ok := sg.OnPlanet(); ok { if planet, ok := sg.AtPlanet(); ok {
if onPlanet, ok := fs.OnPlanet(); ok && onPlanet != planet { if onPlanet, ok := fs.AtPlanet(); ok && onPlanet != planet {
panic(fmt.Sprintf("FleetState: one or more ships in race's %q fleet %q are on different planets: %d <> %d", c.g.Race[ri].Name, c.g.Fleets[fi].Name, onPlanet, planet)) panic(fmt.Sprintf("FleetState: one or more ships in race's %q fleet %q are on different planets: %d <> %d", c.g.Race[ri].Name, c.g.Fleets[fi].Name, onPlanet, planet))
} }
} }
@@ -142,7 +141,7 @@ func (c *Cache) JoinShipGroupToFleet(ri int, fleetName string, groupIndex, quant
} }
} else { } else {
fleetState := c.FleetState(c.g.Fleets[fi].ID) fleetState := c.FleetState(c.g.Fleets[fi].ID)
if onPlanet, ok := fleetState.OnPlanet(); (ok && onPlanet != c.ShipGroup(sgi).Destination) || fleetState.State != game.StateInOrbit { if onPlanet, ok := fleetState.AtPlanet(); (ok && onPlanet != c.ShipGroup(sgi).Destination) || fleetState.State != game.StateInOrbit {
return e.NewShipsNotOnSamePlanetError("fleet: %s", fleetName) return e.NewShipsNotOnSamePlanetError("fleet: %s", fleetName)
} }
} }
@@ -198,7 +197,7 @@ func (c *Cache) JoinFleets(ri int, fleetSourceName, fleetTargetName string) (err
} }
stateSrc := c.FleetState(c.g.Fleets[fiSource].ID) stateSrc := c.FleetState(c.g.Fleets[fiSource].ID)
stateDst := c.FleetState(c.g.Fleets[fiTarget].ID) stateDst := c.FleetState(c.g.Fleets[fiTarget].ID)
if !stateSrc.OnSamePlanet(stateDst) { if !stateSrc.AtSamePlanet(stateDst) {
return e.NewShipsNotOnSamePlanetError() return e.NewShipsNotOnSamePlanetError()
} }
+1 -1
View File
@@ -22,7 +22,7 @@ func (c *Cache) SendFleet(ri, fi int, planetNumber uint) error {
c.validateRaceIndex(ri) c.validateRaceIndex(ri)
c.validateFleetIndex(fi) c.validateFleetIndex(fi)
fleetState := c.FleetState(c.g.Fleets[fi].ID) fleetState := c.FleetState(c.g.Fleets[fi].ID)
sourcePlanet, ok := fleetState.OnPlanet() sourcePlanet, ok := fleetState.AtPlanet()
if !ok || game.StateInOrbit != fleetState.State && game.StateLaunched != fleetState.State { if !ok || game.StateInOrbit != fleetState.State && game.StateLaunched != fleetState.State {
return e.NewShipsBusyError() return e.NewShipsBusyError()
} }
+1 -1
View File
@@ -27,7 +27,7 @@ func (c *Cache) SendGroup(ri int, groupIndex, planetNumber, quantity uint) error
return e.NewSendShipHasNoDrivesError() return e.NewSendShipHasNoDrivesError()
} }
sourcePlanet, ok := c.ShipGroup(sgi).OnPlanet() sourcePlanet, ok := c.ShipGroup(sgi).AtPlanet()
if !ok { if !ok {
return e.NewShipsBusyError() return e.NewShipsBusyError()
} }
+2 -1
View File
@@ -6,6 +6,7 @@ import (
"maps" "maps"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/iliadenisov/galaxy/internal/number"
) )
type Float float64 type Float float64
@@ -19,7 +20,7 @@ func (f Float) Add(v float64) Float {
} }
func (f Float) F() float64 { func (f Float) F() float64 {
return float64(f) return number.Fixed12(float64(f))
} }
type TechSet map[Tech]Float type TechSet map[Tech]Float
+2 -3
View File
@@ -142,8 +142,7 @@ func (sg ShipGroup) State() ShipGroupState {
} }
} }
// FIXME: ambigous func, refactor func (sg ShipGroup) AtPlanet() (uint, bool) {
func (sg ShipGroup) OnPlanet() (uint, bool) {
switch sg.State() { switch sg.State() {
case StateInOrbit: case StateInOrbit:
return sg.Destination, true return sg.Destination, true
@@ -171,7 +170,7 @@ func (sg ShipGroup) Equal(other ShipGroup) bool {
sg.TechLevel(TechShields) == other.TechLevel(TechShields) && sg.TechLevel(TechShields) == other.TechLevel(TechShields) &&
sg.TechLevel(TechCargo) == other.TechLevel(TechCargo) && sg.TechLevel(TechCargo) == other.TechLevel(TechCargo) &&
sg.CargoType == other.CargoType && sg.CargoType == other.CargoType &&
sg.Load.F()/float64(sg.Number) == other.Load.F()/float64(other.Number) && (sg.Load/F(float64(sg.Number))).F() == (other.Load/F(float64(other.Number))).F() &&
sg.State() == other.State() sg.State() == other.State()
} }
+1 -1
View File
@@ -244,6 +244,6 @@ func TestShipGroupEqual(t *testing.T) {
// dirty hack to equalize loads // dirty hack to equalize loads
left.Number = 5 left.Number = 5
left.Load = game.F(right.Load.F() / float64(right.Number) * float64(left.Number)) left.Load = game.F(float64(right.Load) / float64(right.Number) * float64(left.Number))
assert.True(t, left.Equal(right)) assert.True(t, left.Equal(right))
} }
+4
View File
@@ -6,6 +6,10 @@ func Fixed3(num float64) float64 {
return fixed(num, 3) return fixed(num, 3)
} }
func Fixed12(num float64) float64 {
return fixed(num, 12)
}
func fixed(num float64, precision int) float64 { func fixed(num float64, precision int) float64 {
output := math.Pow(10, float64(precision)) output := math.Pow(10, float64(precision))
return float64(round(num*output)) / output return float64(round(num*output)) / output