From 1379241967faf7ae5b2f061eae94057309a4359b Mon Sep 17 00:00:00 2001 From: Ilia Denisov Date: Tue, 17 Feb 2026 19:06:26 +0200 Subject: [PATCH] fix: created ships exact tech level --- go.mod | 2 +- internal/controller/controller_export_test.go | 4 ++-- internal/controller/planet.go | 3 ++- internal/controller/ship_group.go | 22 ++++++------------ internal/controller/ship_group_test.go | 23 +++++++++++++++++++ internal/model/game/group.go | 3 +++ 6 files changed, 38 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 49ca40b..2c7fb3b 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/iliadenisov/galaxy -go 1.25.0 +go 1.26.0 require ( github.com/gin-gonic/gin v1.11.0 diff --git a/internal/controller/controller_export_test.go b/internal/controller/controller_export_test.go index deb3c6e..6c528d7 100644 --- a/internal/controller/controller_export_test.go +++ b/internal/controller/controller_export_test.go @@ -136,8 +136,8 @@ func VotingWinners(calc []*VoteGroup, gameVotes float64) []int { return votingWinners(calc, gameVotes) } -func (c *Cache) CreateShipsUnsafe_T(ri int, classID uuid.UUID, planet uint, quantity uint) { - c.unsafeCreateShips(ri, classID, planet, quantity) +func (c *Cache) CreateShipsUnsafe_T(ri int, classID uuid.UUID, planet uint, quantity uint) int { + return c.unsafeCreateShips(ri, classID, planet, quantity) } func (c *Cache) WipeRace(ri int) { diff --git a/internal/controller/planet.go b/internal/controller/planet.go index 83079c8..927c3ee 100644 --- a/internal/controller/planet.go +++ b/internal/controller/planet.go @@ -8,6 +8,7 @@ import ( "github.com/google/uuid" e "github.com/iliadenisov/galaxy/internal/error" "github.com/iliadenisov/galaxy/internal/model/game" + "github.com/iliadenisov/galaxy/internal/number" "github.com/iliadenisov/galaxy/internal/util" ) @@ -183,7 +184,7 @@ func (c *Cache) TurnPlanetProductions() { cost := sg.StateUpgrade.Cost() if productionAvailable >= cost { for i := range sg.StateUpgrade.UpgradeTech { - sg.Tech = sg.Tech.Set(sg.StateUpgrade.UpgradeTech[i].Tech, sg.StateUpgrade.UpgradeTech[i].Level.F()) + sg.Tech = sg.Tech.Set(sg.StateUpgrade.UpgradeTech[i].Tech, number.Fixed3(sg.StateUpgrade.UpgradeTech[i].Level.F())) } productionAvailable -= cost } diff --git a/internal/controller/ship_group.go b/internal/controller/ship_group.go index cc91cce..646bb12 100644 --- a/internal/controller/ship_group.go +++ b/internal/controller/ship_group.go @@ -10,6 +10,7 @@ import ( "github.com/google/uuid" e "github.com/iliadenisov/galaxy/internal/error" "github.com/iliadenisov/galaxy/internal/model/game" + "github.com/iliadenisov/galaxy/internal/number" ) // ShipGroup is a proxy func, nothing to cache @@ -525,33 +526,24 @@ func (c *Cache) validateShipGroupIndex(i int) { } } -/* -TODO: Точность тех. уровней корабля - -В целях избежания неточностей в расчетах, технологические уровни кораблей -округляются до третьего знака после запятой в момент постройки или -модернизации. Поэтому в отчетах у кораблей всегда указываются действительные, -а не округлённые уровни технологий. -*/ -func (c *Cache) unsafeCreateShips(ri int, classID uuid.UUID, planet uint, quantity uint) { +func (c *Cache) unsafeCreateShips(ri int, classID uuid.UUID, planet uint, quantity uint) int { st := c.MustShipType(ri, classID) - // TODO: test new group levels level := func(t game.Tech) float64 { if t == game.TechDrive && st.DriveBlockMass() > 0 { - return c.g.Race[ri].TechLevel(game.TechDrive) + return number.Fixed3(c.g.Race[ri].TechLevel(game.TechDrive)) } if t == game.TechWeapons && st.WeaponsBlockMass() > 0 { - return c.g.Race[ri].TechLevel(game.TechDrive) + return number.Fixed3(c.g.Race[ri].TechLevel(game.TechWeapons)) } if t == game.TechShields && st.ShieldsBlockMass() > 0 { - return c.g.Race[ri].TechLevel(game.TechDrive) + return number.Fixed3(c.g.Race[ri].TechLevel(game.TechShields)) } if t == game.TechCargo && st.CargoBlockMass() > 0 { - return c.g.Race[ri].TechLevel(game.TechDrive) + return number.Fixed3(c.g.Race[ri].TechLevel(game.TechCargo)) } return 0 } - c.appendShipGroup(ri, &game.ShipGroup{ + return c.appendShipGroup(ri, &game.ShipGroup{ OwnerID: c.g.Race[ri].ID, TypeID: classID, Destination: planet, diff --git a/internal/controller/ship_group_test.go b/internal/controller/ship_group_test.go index 0526a6f..775f4eb 100644 --- a/internal/controller/ship_group_test.go +++ b/internal/controller/ship_group_test.go @@ -35,6 +35,29 @@ func TestCreateShips(t *testing.T) { assert.Len(t, slices.Collect(c.RaceShipGroups(1)), 2) } +func TestUnsafeCreateShips(t *testing.T) { + c, _ := newCache() + r := c.Race(Race_0_idx) + r.Tech = r.Tech.Set(game.TechDrive, 1.001) + r.Tech = r.Tech.Set(game.TechWeapons, 2.999) + r.Tech = r.Tech.Set(game.TechShields, 3.1003) + r.Tech = r.Tech.Set(game.TechCargo, 4.0005001) + + sgi := c.CreateShipsUnsafe_T(Race_0_idx, c.MustShipClass(Race_0_idx, Race_0_Freighter).ID, R0_Planet_0_num, 1) + sg := c.ShipGroup(sgi) + assert.Equal(t, 1.001, sg.Tech.Value(game.TechDrive)) + assert.Equal(t, 0., sg.Tech.Value(game.TechWeapons)) + assert.Equal(t, 3.100, sg.Tech.Value(game.TechShields)) + assert.Equal(t, 4.001, sg.Tech.Value(game.TechCargo)) + + sgi = c.CreateShipsUnsafe_T(Race_0_idx, c.MustShipClass(Race_0_idx, Race_0_Gunship).ID, R0_Planet_0_num, 1) + sg = c.ShipGroup(sgi) + assert.Equal(t, 1.001, sg.Tech.Value(game.TechDrive)) + assert.Equal(t, 2.999, sg.Tech.Value(game.TechWeapons)) + assert.Equal(t, 3.100, sg.Tech.Value(game.TechShields)) + assert.Equal(t, 0., sg.Tech.Value(game.TechCargo)) +} + func TestShipGroupMerge(t *testing.T) { c, g := newCache() diff --git a/internal/model/game/group.go b/internal/model/game/group.go index 29fa90d..02627ed 100644 --- a/internal/model/game/group.go +++ b/internal/model/game/group.go @@ -187,6 +187,9 @@ func (sg ShipGroup) CargoCapacity(st *ShipType) float64 { // Масса перевозимого груза - // общее количество единиц груза, деленное на технологический уровень Грузоперевозок func (sg ShipGroup) CarryingMass() float64 { + if sg.Load.F() == 0 { + return 0 + } return sg.Load.F() / sg.TechLevel(TechCargo).F() }