fix: production with free P.I.
This commit is contained in:
@@ -199,11 +199,10 @@ func (c *Cache) PlanetProductionCapacity(planetNumber uint) float64 {
|
||||
return p.ProductionCapacity() - busyResources
|
||||
}
|
||||
|
||||
// TODO: test upgrade & upgrade cancel
|
||||
func (c *Cache) TurnPlanetProductions() {
|
||||
// cancel upgrade for groups on wiped planets
|
||||
for sgi := range c.ShipGroupsIndex() {
|
||||
sg := c.ShipGroup(sgi)
|
||||
// cancel upgrade for groups on wiped planets
|
||||
if sg.State() == game.StateUpgrade && !c.MustPlanet(sg.Destination).Owned() {
|
||||
sg.StateUpgrade = nil
|
||||
}
|
||||
@@ -215,7 +214,7 @@ func (c *Cache) TurnPlanetProductions() {
|
||||
r := &c.g.Race[ri]
|
||||
|
||||
// upgrade groups and return to in_orbit state
|
||||
productionAvailable := p.ProductionCapacity()
|
||||
productionAvailable := c.PlanetProductionCapacity(pn)
|
||||
for sg := range c.shipGroupsInUpgrade(p.Number) {
|
||||
cost := sg.StateUpgrade.Cost()
|
||||
if productionAvailable >= cost {
|
||||
@@ -235,19 +234,19 @@ func (c *Cache) TurnPlanetProductions() {
|
||||
}
|
||||
case game.ResearchScience:
|
||||
sc := c.mustScience(ri, *p.Production.SubjectID)
|
||||
ResearchTech(r, p.ProductionCapacity(), sc.Drive.F(), sc.Weapons.F(), sc.Shields.F(), sc.Cargo.F())
|
||||
ResearchTech(r, productionAvailable, sc.Drive.F(), sc.Weapons.F(), sc.Shields.F(), sc.Cargo.F())
|
||||
case game.ResearchDrive:
|
||||
ResearchTech(r, p.ProductionCapacity(), 1., 0, 0, 0)
|
||||
ResearchTech(r, productionAvailable, 1., 0, 0, 0)
|
||||
case game.ResearchWeapons:
|
||||
ResearchTech(r, p.ProductionCapacity(), 0, 1., 0, 0)
|
||||
ResearchTech(r, productionAvailable, 0, 1., 0, 0)
|
||||
case game.ResearchShields:
|
||||
ResearchTech(r, p.ProductionCapacity(), 0, 0, 1., 0)
|
||||
ResearchTech(r, productionAvailable, 0, 0, 1., 0)
|
||||
case game.ResearchCargo:
|
||||
ResearchTech(r, p.ProductionCapacity(), 0, 0, 0, 1.)
|
||||
ResearchTech(r, productionAvailable, 0, 0, 0, 1.)
|
||||
case game.ProductionMaterial:
|
||||
p.ProduceMaterial()
|
||||
p.ProduceMaterial(productionAvailable)
|
||||
case game.ProductionCapital:
|
||||
p.ProduceIndustry()
|
||||
p.ProduceIndustry(productionAvailable)
|
||||
default:
|
||||
panic(fmt.Sprintf("unprocessed production type: '%v' for planet: #%d owner=%v", pt, pn, p.Owner))
|
||||
}
|
||||
|
||||
@@ -173,6 +173,33 @@ func TestProduceShips(t *testing.T) {
|
||||
assert.Equal(t, uint(106), c.ShipGroup(0).Number)
|
||||
progress = *c.MustPlanet(R0_Planet_0_num).Production.Progress
|
||||
assert.InDelta(t, 0.0099, progress.F(), 0.00001) // 1.(0099) drones with no CAP on planet
|
||||
|
||||
//
|
||||
// groups is upgrade state
|
||||
//
|
||||
|
||||
assert.NoError(t, g.PlanetProduction(Race_0.Name, int(R0_Planet_0_num), "MAT", ""))
|
||||
assert.NoError(t, g.PlanetProduction(Race_0.Name, int(R0_Planet_2_num), "CAP", ""))
|
||||
assert.NoError(t, c.CreateShips(Race_0_idx, "Drone", R0_Planet_2_num, 5))
|
||||
c.MustPlanet(R0_Planet_2_num).Resources = 5
|
||||
c.MustPlanet(R0_Planet_2_num).Population = 100
|
||||
c.MustPlanet(R0_Planet_2_num).Industry = 100
|
||||
c.RaceTechLevel(Race_0_idx, game.TechDrive, 1.5)
|
||||
assert.NoError(t, g.UpgradeGroup(Race_0.Name, 2, "Drive", 0, 0))
|
||||
assert.NoError(t, g.UpgradeGroup(Race_0.Name, 1, "Drive", 0, 0))
|
||||
assert.Equal(t, game.StateUpgrade, c.ShipGroup(0).State())
|
||||
assert.Equal(t, game.StateUpgrade, c.ShipGroup(1).State())
|
||||
|
||||
c.MustPlanet(R0_Planet_2_num).Free() // wipe planet as battle result
|
||||
c.TurnPlanetProductions()
|
||||
|
||||
assert.Equal(t, game.StateInOrbit, c.ShipGroup(1).State())
|
||||
assert.Equal(t, 1.1, c.ShipGroup(1).TechLevel(game.TechDrive).F())
|
||||
|
||||
assert.Equal(t, game.StateInOrbit, c.ShipGroup(0).State())
|
||||
assert.Equal(t, 1.5, c.ShipGroup(0).TechLevel(game.TechDrive).F())
|
||||
|
||||
assert.Equal(t, 4346.676567656759, c.MustPlanet(R0_Planet_0_num).Material.F())
|
||||
}
|
||||
|
||||
func TestProduceShip(t *testing.T) {
|
||||
|
||||
@@ -423,7 +423,7 @@ func (c *Cache) ReportLocalPlanet(ri int, rep *mr.Report) {
|
||||
}
|
||||
|
||||
sliceIndexValidate(&rep.LocalPlanet, i)
|
||||
c.localPlanet(&rep.LocalPlanet[i], p, rep)
|
||||
c.localPlanet(&rep.LocalPlanet[i], p)
|
||||
// rep.LocalPlanet[i].UnidentifiedPlanet.Number = p.Number
|
||||
// rep.LocalPlanet[i].UnidentifiedPlanet.X = mr.F(p.X.F())
|
||||
// rep.LocalPlanet[i].UnidentifiedPlanet.Y = mr.F(p.Y.F())
|
||||
@@ -466,7 +466,7 @@ func (c *Cache) ReportOtherPlanet(ri int, rep *mr.Report) {
|
||||
}
|
||||
|
||||
sliceIndexValidate(&rep.OtherPlanet, i)
|
||||
c.localPlanet(&rep.OtherPlanet[i].LocalPlanet, p, rep)
|
||||
c.localPlanet(&rep.OtherPlanet[i].LocalPlanet, p)
|
||||
rep.OtherPlanet[i].Owner = c.g.Race[c.RaceIndex(*p.Owner)].Name
|
||||
i++
|
||||
}
|
||||
@@ -728,21 +728,14 @@ func (c *Cache) otherGroup(v *mr.OtherGroup, sg *game.ShipGroup, st *game.ShipTy
|
||||
v.Mass = mr.F(st.EmptyMass())
|
||||
}
|
||||
|
||||
func (c *Cache) localPlanet(v *mr.LocalPlanet, p *game.Planet, rep *mr.Report) {
|
||||
func (c *Cache) localPlanet(v *mr.LocalPlanet, p *game.Planet) {
|
||||
uninhabitedPlanet(&v.UninhabitedPlanet, p)
|
||||
v.Industry = mr.F(p.Industry.F())
|
||||
v.Population = mr.F(p.Population.F())
|
||||
v.Colonists = mr.F(p.Colonists.F())
|
||||
v.Production = c.PlanetProductionDisplayName(p.Number)
|
||||
v.FreeIndustry = mr.F(p.ProductionCapacity())
|
||||
for _, sgi := range rep.OnPlanetGroupCache[p.Number] {
|
||||
sg := c.ShipGroup(sgi)
|
||||
if sg.StateUpgrade == nil {
|
||||
break
|
||||
}
|
||||
// between-turn report: ships upgrading on the planet decreases free indistrial potential
|
||||
v.FreeIndustry -= mr.F(sg.StateUpgrade.Cost())
|
||||
}
|
||||
// between-turn report: ships upgrading on the planet decreases free indistrial potential
|
||||
v.FreeIndustry = mr.F(c.PlanetProductionCapacity(p.Number))
|
||||
}
|
||||
|
||||
func uninhabitedPlanet(v *mr.UninhabitedPlanet, p *game.Planet) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package controller
|
||||
import (
|
||||
"math"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
e "github.com/iliadenisov/galaxy/internal/error"
|
||||
"github.com/iliadenisov/galaxy/internal/model/game"
|
||||
@@ -35,14 +36,14 @@ func (c *Cache) UpgradeGroup(ri int, groupIndex uint, techInput string, limitShi
|
||||
}
|
||||
|
||||
upgradeValidTech := map[string]game.Tech{
|
||||
game.TechDrive.String(): game.TechDrive,
|
||||
game.TechWeapons.String(): game.TechWeapons,
|
||||
game.TechShields.String(): game.TechShields,
|
||||
game.TechCargo.String(): game.TechCargo,
|
||||
game.TechAll.String(): game.TechAll,
|
||||
strings.ToLower(game.TechDrive.String()): game.TechDrive,
|
||||
strings.ToLower(game.TechWeapons.String()): game.TechWeapons,
|
||||
strings.ToLower(game.TechShields.String()): game.TechShields,
|
||||
strings.ToLower(game.TechCargo.String()): game.TechCargo,
|
||||
strings.ToLower(game.TechAll.String()): game.TechAll,
|
||||
}
|
||||
|
||||
techRequest, ok := upgradeValidTech[techInput]
|
||||
techRequest, ok := upgradeValidTech[strings.ToLower(techInput)]
|
||||
if !ok {
|
||||
return e.NewTechUnknownError(techInput)
|
||||
}
|
||||
|
||||
@@ -11,17 +11,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// var (
|
||||
// Cruiser = game.ShipType{
|
||||
// Name: "Cruiser",
|
||||
// Drive: 15,
|
||||
// Armament: 1,
|
||||
// Weapons: 15,
|
||||
// Shields: 15,
|
||||
// Cargo: 0,
|
||||
// }
|
||||
// )
|
||||
|
||||
func TestBlockUpgradeCost(t *testing.T) {
|
||||
assert.Equal(t, 00.0, controller.BlockUpgradeCost(1, 1.0, 1.0))
|
||||
assert.Equal(t, 25.0, controller.BlockUpgradeCost(5, 1.0, 2.0))
|
||||
|
||||
@@ -76,7 +76,7 @@ func (p Planet) Votes() float64 {
|
||||
return p.Population.F() / 1000.
|
||||
}
|
||||
|
||||
// Производственный потенциал
|
||||
// Производственный потенциал без учёта модернизации кораблей
|
||||
func (p Planet) ProductionCapacity() float64 {
|
||||
return PlanetProduction(p.Industry.F(), p.Population.F())
|
||||
}
|
||||
@@ -104,15 +104,14 @@ func ProducedMaterial(shipMass, progress float64) float64 {
|
||||
// [x] ind = (res * prod) / (5 * res + 1)
|
||||
// ind = 10 * 1000 / (5 * 10 + 1) = 10000 / 55 = 181.(81)
|
||||
// int = 10 * 500 / 55 = 5000 / 55
|
||||
func (p *Planet) ProduceIndustry() {
|
||||
production := p.ProductionCapacity()
|
||||
func (p *Planet) ProduceIndustry(freeProduction float64) {
|
||||
var ind float64
|
||||
if p.Material > 0 {
|
||||
ind = math.Min(production/5, p.Material.F())
|
||||
ind = math.Min(freeProduction/5, p.Material.F())
|
||||
p.Mat(p.Material.F() - ind)
|
||||
production -= ind * 5.
|
||||
freeProduction -= ind * 5.
|
||||
}
|
||||
ind += (production * p.Resources.F()) / (5.*p.Resources.F() + 1.)
|
||||
ind += (freeProduction * p.Resources.F()) / (5.*p.Resources.F() + 1.)
|
||||
p.Ind(p.Industry.F() + ind)
|
||||
if p.Industry > p.Population {
|
||||
p.Capital += p.Industry - p.Population
|
||||
@@ -121,8 +120,8 @@ func (p *Planet) ProduceIndustry() {
|
||||
}
|
||||
|
||||
// Производство материалов
|
||||
func (p *Planet) ProduceMaterial() {
|
||||
p.Material = p.Material.Add(p.ProductionCapacity() * p.Resources.F())
|
||||
func (p *Planet) ProduceMaterial(freeProduction float64) {
|
||||
p.Material = p.Material.Add(freeProduction * p.Resources.F())
|
||||
}
|
||||
|
||||
// Автоматическое увеличение населения на каждом ходу
|
||||
|
||||
@@ -27,23 +27,23 @@ func TestProduceIndustry(t *testing.T) {
|
||||
Population: 500,
|
||||
Industry: 500,
|
||||
}
|
||||
HW.ProduceIndustry()
|
||||
HW.ProduceIndustry(HW.ProductionCapacity())
|
||||
assert.InDelta(t, 196.078, HW.Capital.F(), 0.0005)
|
||||
|
||||
HW.Capital = 0
|
||||
HW.Material = 200
|
||||
|
||||
HW.ProduceIndustry()
|
||||
HW.ProduceIndustry(HW.ProductionCapacity())
|
||||
assert.Equal(t, 200., HW.Capital.F())
|
||||
assert.Equal(t, 0., HW.Material.F())
|
||||
|
||||
DW.ProduceIndustry()
|
||||
DW.ProduceIndustry(DW.ProductionCapacity())
|
||||
assert.InDelta(t, 98.039, DW.Capital.F(), 0.0003)
|
||||
|
||||
DW.Capital = 0
|
||||
DW.Material = 100
|
||||
|
||||
DW.ProduceIndustry()
|
||||
DW.ProduceIndustry(DW.ProductionCapacity())
|
||||
assert.Equal(t, 100., DW.Capital.F())
|
||||
assert.Equal(t, 0., DW.Material.F())
|
||||
}
|
||||
@@ -57,16 +57,16 @@ func TestProduceMaterial(t *testing.T) {
|
||||
}
|
||||
assert.Equal(t, 0., HW.Material.F())
|
||||
|
||||
HW.ProduceMaterial()
|
||||
HW.ProduceMaterial(HW.ProductionCapacity())
|
||||
assert.Equal(t, 10000., HW.Material.F())
|
||||
|
||||
HW.Industry = 500
|
||||
HW.Population = 500
|
||||
HW.ProduceMaterial()
|
||||
HW.ProduceMaterial(HW.ProductionCapacity())
|
||||
assert.Equal(t, 15000., HW.Material.F())
|
||||
|
||||
HW.Population = 1000
|
||||
HW.ProduceMaterial()
|
||||
HW.ProduceMaterial(HW.ProductionCapacity())
|
||||
assert.Equal(t, 21250., HW.Material.F())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user