refactor: float64 types for storage and report
This commit is contained in:
@@ -65,9 +65,9 @@ func FilterBattleOpponents(c *Cache, attIdx, defIdx int, cacheProbability map[in
|
|||||||
|
|
||||||
p := DestructionProbability(
|
p := DestructionProbability(
|
||||||
c.ShipGroupShipClass(attIdx).Weapons,
|
c.ShipGroupShipClass(attIdx).Weapons,
|
||||||
c.ShipGroup(attIdx).TechLevel(game.TechWeapons),
|
c.ShipGroup(attIdx).TechLevel(game.TechWeapons).F(),
|
||||||
c.ShipGroupShipClass(defIdx).Shields,
|
c.ShipGroupShipClass(defIdx).Shields,
|
||||||
c.ShipGroup(defIdx).TechLevel(game.TechShields),
|
c.ShipGroup(defIdx).TechLevel(game.TechShields).F(),
|
||||||
c.ShipGroup(defIdx).FullMass(c.ShipGroupShipClass(defIdx)),
|
c.ShipGroup(defIdx).FullMass(c.ShipGroupShipClass(defIdx)),
|
||||||
)
|
)
|
||||||
// Exclude opponent's group which cannot be probably destroyed
|
// Exclude opponent's group which cannot be probably destroyed
|
||||||
|
|||||||
@@ -30,11 +30,11 @@ func TransformBattle(c *Cache, b *Battle) *report.BattleReport {
|
|||||||
NumberLeft: sg.Number,
|
NumberLeft: sg.Number,
|
||||||
ClassName: shipClass.Name,
|
ClassName: shipClass.Name,
|
||||||
LoadType: sg.CargoString(),
|
LoadType: sg.CargoString(),
|
||||||
LoadQuantity: sg.Load,
|
LoadQuantity: sg.Load.RF(),
|
||||||
Drive: sg.TechLevel(game.TechDrive),
|
Drive: sg.TechLevel(game.TechDrive).RF(),
|
||||||
Weapons: sg.TechLevel(game.TechWeapons),
|
Weapons: sg.TechLevel(game.TechWeapons).RF(),
|
||||||
Shields: sg.TechLevel(game.TechShields),
|
Shields: sg.TechLevel(game.TechShields).RF(),
|
||||||
Cargo: sg.TechLevel(game.TechCargo),
|
Cargo: sg.TechLevel(game.TechCargo).RF(),
|
||||||
}
|
}
|
||||||
cacheShipClass[shipClass.ID] = itemNumber
|
cacheShipClass[shipClass.ID] = itemNumber
|
||||||
return itemNumber
|
return itemNumber
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ func (c *Cache) bombingReport(p *game.Planet, ri int, groups []int) report.Bombi
|
|||||||
Owner: c.g.Race[c.RaceIndex(p.Owner)].Name,
|
Owner: c.g.Race[c.RaceIndex(p.Owner)].Name,
|
||||||
Attacker: c.g.Race[ri].Name,
|
Attacker: c.g.Race[ri].Name,
|
||||||
Production: c.PlanetProductionDisplayName(p.Number),
|
Production: c.PlanetProductionDisplayName(p.Number),
|
||||||
Industry: p.Industry,
|
Industry: p.Industry.RF(),
|
||||||
Population: p.Population,
|
Population: p.Population.RF(),
|
||||||
Colonists: p.Colonists,
|
Colonists: p.Colonists.RF(),
|
||||||
Capital: p.Capital,
|
Capital: p.Capital.RF(),
|
||||||
Material: p.Material,
|
Material: p.Material.RF(),
|
||||||
AttackPower: attackPower,
|
AttackPower: game.RF(attackPower),
|
||||||
}
|
}
|
||||||
bombPlanet(p, attackPower)
|
bombPlanet(p, attackPower)
|
||||||
r.Wiped = p.Population == 0
|
r.Wiped = p.Population == 0
|
||||||
@@ -61,23 +61,23 @@ func (c *Cache) ProduceBombings() []report.BombingPlanetReport {
|
|||||||
|
|
||||||
func bombPlanet(p *game.Planet, power float64) {
|
func bombPlanet(p *game.Planet, power float64) {
|
||||||
// Уничтожается население и колонисты в количестве равном [суммарной] мощности бомбардировки
|
// Уничтожается население и колонисты в количестве равном [суммарной] мощности бомбардировки
|
||||||
if power > p.Population {
|
if power > p.Population.F() {
|
||||||
p.Population = 0
|
p.Pop(0)
|
||||||
} else {
|
} else {
|
||||||
p.Population -= power
|
p.Pop(p.Population.F() - power)
|
||||||
}
|
}
|
||||||
if power > p.Colonists {
|
if power > p.Colonists.F() {
|
||||||
p.Colonists = 0
|
p.Col(0)
|
||||||
} else {
|
} else {
|
||||||
p.Colonists -= power
|
p.Col(p.Colonists.F() - power)
|
||||||
}
|
}
|
||||||
// Такое же количество промышленности превращается в сырье
|
// Такое же количество промышленности превращается в сырье
|
||||||
if power > p.Industry {
|
if power > p.Industry.F() {
|
||||||
p.Material += p.Industry
|
p.Mat(p.Material.F() + p.Industry.F())
|
||||||
p.Industry = 0
|
p.Ind(0)
|
||||||
} else {
|
} else {
|
||||||
p.Material += power
|
p.Mat(p.Material.F() + power)
|
||||||
p.Industry -= power
|
p.Ind(p.Industry.F() - power)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,25 +12,25 @@ import (
|
|||||||
func TestBombPlanet(t *testing.T) {
|
func TestBombPlanet(t *testing.T) {
|
||||||
p := controller.NewPlanet(0, "Planet_0", uuid.New(), 1, 1, 1000, 300, 200, 10, game.ResearchDrive.AsType(uuid.Nil))
|
p := controller.NewPlanet(0, "Planet_0", uuid.New(), 1, 1, 1000, 300, 200, 10, game.ResearchDrive.AsType(uuid.Nil))
|
||||||
(&p).Colonists = 100.
|
(&p).Colonists = 100.
|
||||||
assert.Equal(t, 0., p.Material)
|
assert.Equal(t, 0., p.Material.F())
|
||||||
|
|
||||||
controller.BombPlanet(&p, 55.)
|
controller.BombPlanet(&p, 55.)
|
||||||
assert.Equal(t, 245., p.Population)
|
assert.Equal(t, 245., p.Population.F())
|
||||||
assert.Equal(t, 45., p.Colonists)
|
assert.Equal(t, 45., p.Colonists.F())
|
||||||
assert.Equal(t, 145., p.Industry)
|
assert.Equal(t, 145., p.Industry.F())
|
||||||
assert.Equal(t, 55., p.Material)
|
assert.Equal(t, 55., p.Material.F())
|
||||||
|
|
||||||
controller.BombPlanet(&p, 56.)
|
controller.BombPlanet(&p, 56.)
|
||||||
assert.Equal(t, 189., p.Population)
|
assert.Equal(t, 189., p.Population.F())
|
||||||
assert.Equal(t, 0., p.Colonists)
|
assert.Equal(t, 0., p.Colonists.F())
|
||||||
assert.Equal(t, 89., p.Industry)
|
assert.Equal(t, 89., p.Industry.F())
|
||||||
assert.Equal(t, 111., p.Material)
|
assert.Equal(t, 111., p.Material.F())
|
||||||
|
|
||||||
controller.BombPlanet(&p, 200.)
|
controller.BombPlanet(&p, 200.)
|
||||||
assert.Equal(t, 0., p.Population)
|
assert.Equal(t, 0., p.Population.F())
|
||||||
assert.Equal(t, 0., p.Colonists)
|
assert.Equal(t, 0., p.Colonists.F())
|
||||||
assert.Equal(t, 0., p.Industry)
|
assert.Equal(t, 0., p.Industry.F())
|
||||||
assert.Equal(t, 200., p.Material)
|
assert.Equal(t, 200., p.Material.F())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCollectBombingGroups(t *testing.T) {
|
func TestCollectBombingGroups(t *testing.T) {
|
||||||
@@ -126,19 +126,19 @@ func TestProduceBombings(t *testing.T) {
|
|||||||
case R1_Planet_1_num:
|
case R1_Planet_1_num:
|
||||||
assert.Equal(t, Race_1.Name, r.Owner)
|
assert.Equal(t, Race_1.Name, r.Owner)
|
||||||
assert.Equal(t, Race_0.Name, r.Attacker)
|
assert.Equal(t, Race_0.Name, r.Attacker)
|
||||||
assert.InDelta(t, 697.857, r.AttackPower, 0.0003)
|
assert.InDelta(t, 697.857, r.AttackPower.F(), 0.0003)
|
||||||
assert.True(t, r.Wiped)
|
assert.True(t, r.Wiped)
|
||||||
assert.Equal(t, uuid.Nil, c.MustPlanet(pn).Owner)
|
assert.Equal(t, uuid.Nil, c.MustPlanet(pn).Owner)
|
||||||
assert.Empty(t, c.MustPlanet(pn).Route)
|
assert.Empty(t, c.MustPlanet(pn).Route)
|
||||||
assert.Equal(t, 0., c.MustPlanet(pn).Population)
|
assert.Equal(t, 0., c.MustPlanet(pn).Population.F())
|
||||||
case R0_Planet_2_num:
|
case R0_Planet_2_num:
|
||||||
assert.Equal(t, Race_0.Name, r.Owner)
|
assert.Equal(t, Race_0.Name, r.Owner)
|
||||||
assert.Equal(t, Race_1.Name, r.Attacker)
|
assert.Equal(t, Race_1.Name, r.Attacker)
|
||||||
assert.InDelta(t, 358.85596, r.AttackPower, 0.000001)
|
assert.Equal(t, 358.856, r.AttackPower.F())
|
||||||
assert.False(t, r.Wiped)
|
assert.False(t, r.Wiped)
|
||||||
assert.Equal(t, Race_0_ID, c.MustPlanet(pn).Owner)
|
assert.Equal(t, Race_0_ID, c.MustPlanet(pn).Owner)
|
||||||
assert.NotEmpty(t, c.MustPlanet(pn).Route)
|
assert.NotEmpty(t, c.MustPlanet(pn).Route)
|
||||||
assert.InDelta(t, 500.-358.85596, c.MustPlanet(pn).Population, 0.000001)
|
assert.InDelta(t, 500.-358.85596, c.MustPlanet(pn).Population.F(), 0.000001)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ func (c *Cache) SendFleet(ri, fi int, planetNumber uint) error {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return e.NewEntityNotExistsError("destination planet #%d", planetNumber)
|
return e.NewEntityNotExistsError("destination planet #%d", planetNumber)
|
||||||
}
|
}
|
||||||
rangeToDestination := util.ShortDistance(c.g.Map.Width, c.g.Map.Height, p1.X, p1.Y, p2.X, p2.Y)
|
rangeToDestination := util.ShortDistance(c.g.Map.Width, c.g.Map.Height, p1.X.F(), p1.Y.F(), p2.X.F(), p2.Y.F())
|
||||||
if rangeToDestination > c.g.Race[ri].FlightDistance() {
|
if rangeToDestination > c.g.Race[ri].FlightDistance() {
|
||||||
return e.NewSendUnreachableDestinationError("range=%.03f", rangeToDestination)
|
return e.NewSendUnreachableDestinationError("range=%.03f", rangeToDestination)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,16 +134,16 @@ func NewPlanet(num uint, name string, owner uuid.UUID, x, y, size, pop, ind, res
|
|||||||
PlanetReport: game.PlanetReport{
|
PlanetReport: game.PlanetReport{
|
||||||
UninhabitedPlanet: game.UninhabitedPlanet{
|
UninhabitedPlanet: game.UninhabitedPlanet{
|
||||||
UnidentifiedPlanet: game.UnidentifiedPlanet{
|
UnidentifiedPlanet: game.UnidentifiedPlanet{
|
||||||
X: x,
|
X: game.F(x),
|
||||||
Y: y,
|
Y: game.F(y),
|
||||||
Number: num,
|
Number: num,
|
||||||
},
|
},
|
||||||
Size: size,
|
Size: game.F(size),
|
||||||
Name: name,
|
Name: name,
|
||||||
Resources: res,
|
Resources: game.F(res),
|
||||||
},
|
},
|
||||||
Population: pop,
|
Population: game.F(pop),
|
||||||
Industry: ind,
|
Industry: game.F(ind),
|
||||||
Production: prod,
|
Production: prod,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ func (c *Cache) PlanetProduction(ri int, number int, prod game.ProductionType, s
|
|||||||
|
|
||||||
if p.Production.Type == game.ProductionShip && (prod != game.ProductionShip || *subjectID != *p.Production.SubjectID) {
|
if p.Production.Type == game.ProductionShip && (prod != game.ProductionShip || *subjectID != *p.Production.SubjectID) {
|
||||||
mat, _ := c.MustShipType(ri, *p.Production.SubjectID).ProductionCost()
|
mat, _ := c.MustShipType(ri, *p.Production.SubjectID).ProductionCost()
|
||||||
p.Material += mat * (*p.Production.Progress)
|
p.Mat(p.Material.F() + mat*(*p.Production.Progress))
|
||||||
*p.Production.Progress = 0.
|
*p.Production.Progress = 0.
|
||||||
} else if prod == game.ProductionShip {
|
} else if prod == game.ProductionShip {
|
||||||
// new ship class to produce; otherwise we must have been returned from the func earlier
|
// new ship class to produce; otherwise we must have been returned from the func earlier
|
||||||
@@ -265,15 +265,15 @@ func (c *Cache) listProducingPlanets() iter.Seq[uint] {
|
|||||||
// Internal funcs
|
// Internal funcs
|
||||||
|
|
||||||
func (c *Cache) putPopulation(pn uint, v float64) {
|
func (c *Cache) putPopulation(pn uint, v float64) {
|
||||||
c.MustPlanet(pn).Population = v
|
c.MustPlanet(pn).Pop(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) putColonists(pn uint, v float64) {
|
func (c *Cache) putColonists(pn uint, v float64) {
|
||||||
c.MustPlanet(pn).Colonists = v
|
c.MustPlanet(pn).Col(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) putMaterial(pn uint, v float64) {
|
func (c *Cache) putMaterial(pn uint, v float64) {
|
||||||
c.MustPlanet(pn).Material = v
|
c.MustPlanet(pn).Mat(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProduceShip(p *game.Planet, shipMass float64) uint {
|
func ProduceShip(p *game.Planet, shipMass float64) uint {
|
||||||
@@ -281,20 +281,20 @@ func ProduceShip(p *game.Planet, shipMass float64) uint {
|
|||||||
if productionAvailable <= 0 {
|
if productionAvailable <= 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
CAP_perShip := shipMass / p.Resources
|
CAP_perShip := shipMass / p.Resources.F()
|
||||||
productionForMass := shipMass * 10.
|
productionForMass := shipMass * 10.
|
||||||
ships := uint(0)
|
ships := uint(0)
|
||||||
flZero := 0.
|
flZero := 0.
|
||||||
p.Production.Progress = &flZero
|
p.Production.Progress = &flZero
|
||||||
for productionAvailable > 0 {
|
for productionAvailable > 0 {
|
||||||
var productionExtraCAP float64
|
var productionExtraCAP float64
|
||||||
if CAP_deficit := p.Capital - CAP_perShip; CAP_deficit < 0 {
|
if CAP_deficit := p.Capital.F() - CAP_perShip; CAP_deficit < 0 {
|
||||||
productionExtraCAP = -CAP_deficit
|
productionExtraCAP = -CAP_deficit
|
||||||
}
|
}
|
||||||
productionCost := productionExtraCAP + productionForMass
|
productionCost := productionExtraCAP + productionForMass
|
||||||
if productionAvailable >= productionCost {
|
if productionAvailable >= productionCost {
|
||||||
productionAvailable -= productionCost
|
productionAvailable -= productionCost
|
||||||
p.Capital = p.Capital - (CAP_perShip - productionExtraCAP)
|
p.Cap(p.Capital.F() - (CAP_perShip - productionExtraCAP))
|
||||||
ships++
|
ships++
|
||||||
} else {
|
} else {
|
||||||
progress := productionAvailable / productionCost
|
progress := productionAvailable / productionCost
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ func TestProduceShips(t *testing.T) {
|
|||||||
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 1)
|
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 1)
|
||||||
assert.Equal(t, uint(7), c.ShipGroup(0).Number)
|
assert.Equal(t, uint(7), c.ShipGroup(0).Number)
|
||||||
assert.NoError(t, g.PlanetProduction(Race_0.Name, pn, "SHIP", "Drone"))
|
assert.NoError(t, g.PlanetProduction(Race_0.Name, pn, "SHIP", "Drone"))
|
||||||
assert.InDelta(t, shipMass*progress, c.MustPlanet(R0_Planet_0_num).Material, 0.00001) // 99.(0099) material build
|
assert.InDelta(t, shipMass*progress, c.MustPlanet(R0_Planet_0_num).Material.F(), 0.00001) // 99.(0099) material build
|
||||||
|
|
||||||
c.MustPlanet(R0_Planet_0_num).Material = 0
|
c.MustPlanet(R0_Planet_0_num).Material = 0
|
||||||
c.MustPlanet(R0_Planet_0_num).Colonists = 0
|
c.MustPlanet(R0_Planet_0_num).Colonists = 0
|
||||||
@@ -197,7 +197,7 @@ func TestProduceShip(t *testing.T) {
|
|||||||
r = controller.ProduceShip(&p, Drone.EmptyMass())
|
r = controller.ProduceShip(&p, Drone.EmptyMass())
|
||||||
assert.Equal(t, uint(100), r)
|
assert.Equal(t, uint(100), r)
|
||||||
assert.Equal(t, 0., *p.Production.Progress)
|
assert.Equal(t, 0., *p.Production.Progress)
|
||||||
assert.Equal(t, 0., number.Fixed3(p.Capital)) // TODO: zero CAP is not actual '0.0' after series of decrements
|
assert.Equal(t, 0., number.Fixed3(p.Capital.F())) // TODO: zero CAP is not actual '0.0' after series of decrements
|
||||||
|
|
||||||
(&p).Production = game.ProductionShip.AsType(uuid.Nil)
|
(&p).Production = game.ProductionShip.AsType(uuid.Nil)
|
||||||
(&p).Capital = 0.
|
(&p).Capital = 0.
|
||||||
@@ -242,17 +242,17 @@ func TestTurnPlanetProductions(t *testing.T) {
|
|||||||
pn := int(R0_Planet_0_num)
|
pn := int(R0_Planet_0_num)
|
||||||
|
|
||||||
assert.NoError(t, g.PlanetProduction(Race_0.Name, pn, "CAP", ""))
|
assert.NoError(t, g.PlanetProduction(Race_0.Name, pn, "CAP", ""))
|
||||||
assert.Equal(t, 0.0, c.MustPlanet(R0_Planet_0_num).Capital)
|
assert.Equal(t, 0.0, c.MustPlanet(R0_Planet_0_num).Capital.F())
|
||||||
assert.Equal(t, 0.0, c.MustPlanet(R0_Planet_0_num).Colonists)
|
assert.Equal(t, 0.0, c.MustPlanet(R0_Planet_0_num).Colonists.F())
|
||||||
c.TurnPlanetProductions()
|
c.TurnPlanetProductions()
|
||||||
assert.InDelta(t, 196., c.MustPlanet(R0_Planet_0_num).Capital, 0.1)
|
assert.InDelta(t, 196., c.MustPlanet(R0_Planet_0_num).Capital.F(), 0.1)
|
||||||
assert.InDelta(t, 10.0, c.MustPlanet(R0_Planet_0_num).Colonists, 0.000001) // FIXME: should store more exact value
|
assert.InDelta(t, 10.0, c.MustPlanet(R0_Planet_0_num).Colonists.F(), 0.000001) // FIXME: should store more exact value
|
||||||
|
|
||||||
assert.NoError(t, g.PlanetProduction(Race_0.Name, pn, "MAT", ""))
|
assert.NoError(t, g.PlanetProduction(Race_0.Name, pn, "MAT", ""))
|
||||||
assert.Equal(t, 0.0, c.MustPlanet(R0_Planet_0_num).Material)
|
assert.Equal(t, 0.0, c.MustPlanet(R0_Planet_0_num).Material.F())
|
||||||
c.TurnPlanetProductions()
|
c.TurnPlanetProductions()
|
||||||
assert.Equal(t, 10000., c.MustPlanet(R0_Planet_0_num).Material)
|
assert.Equal(t, 10000., c.MustPlanet(R0_Planet_0_num).Material.F())
|
||||||
assert.InDelta(t, 20.0, c.MustPlanet(R0_Planet_0_num).Colonists, 0.000001)
|
assert.InDelta(t, 20.0, c.MustPlanet(R0_Planet_0_num).Colonists.F(), 0.000001)
|
||||||
|
|
||||||
assert.NoError(t, g.PlanetProduction(Race_0.Name, pn, "DRIVE", ""))
|
assert.NoError(t, g.PlanetProduction(Race_0.Name, pn, "DRIVE", ""))
|
||||||
assert.Equal(t, 1.1, c.Race(Race_0_idx).TechLevel(game.TechDrive))
|
assert.Equal(t, 1.1, c.Race(Race_0_idx).TechLevel(game.TechDrive))
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ func (c *Cache) SetRoute(ri int, rt game.RouteType, origin, destination uint) er
|
|||||||
if !ok {
|
if !ok {
|
||||||
return e.NewEntityNotExistsError("destination planet #%d", destination)
|
return e.NewEntityNotExistsError("destination planet #%d", destination)
|
||||||
}
|
}
|
||||||
rangeToDestination := util.ShortDistance(c.g.Map.Width, c.g.Map.Height, p1.X, p1.Y, p2.X, p2.Y)
|
rangeToDestination := util.ShortDistance(c.g.Map.Width, c.g.Map.Height, p1.X.F(), p1.Y.F(), p2.X.F(), p2.Y.F())
|
||||||
if rangeToDestination > c.g.Race[ri].FlightDistance() {
|
if rangeToDestination > c.g.Race[ri].FlightDistance() {
|
||||||
return e.NewSendUnreachableDestinationError("range=%.03f max=%.03f", rangeToDestination, c.g.Race[ri].FlightDistance())
|
return e.NewSendUnreachableDestinationError("range=%.03f max=%.03f", rangeToDestination, c.g.Race[ri].FlightDistance())
|
||||||
}
|
}
|
||||||
@@ -127,7 +127,7 @@ func (c *Cache) SendRoutedGroups() {
|
|||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var res *float64
|
var res *game.Float
|
||||||
var ct game.CargoType
|
var ct game.CargoType
|
||||||
switch rt {
|
switch rt {
|
||||||
case game.RouteColonist:
|
case game.RouteColonist:
|
||||||
@@ -152,7 +152,7 @@ func (c *Cache) SendRoutedGroups() {
|
|||||||
st := c.ShipGroupShipClass(sgi)
|
st := c.ShipGroupShipClass(sgi)
|
||||||
ships := sg.Number
|
ships := sg.Number
|
||||||
sgCapacity := sg.CargoCapacity(st)
|
sgCapacity := sg.CargoCapacity(st)
|
||||||
toLoad := *res
|
toLoad := (*res).F()
|
||||||
if toLoad > sgCapacity {
|
if toLoad > sgCapacity {
|
||||||
toLoad = sgCapacity
|
toLoad = sgCapacity
|
||||||
} else if maxShips := uint(math.Ceil(toLoad / (sgCapacity / float64(ships)))); maxShips < ships {
|
} else if maxShips := uint(math.Ceil(toLoad / (sgCapacity / float64(ships)))); maxShips < ships {
|
||||||
@@ -160,9 +160,9 @@ func (c *Cache) SendRoutedGroups() {
|
|||||||
sg = c.ShipGroup(newGroupIdx)
|
sg = c.ShipGroup(newGroupIdx)
|
||||||
}
|
}
|
||||||
// decrease planet resource
|
// decrease planet resource
|
||||||
*res = *res - toLoad
|
*res = (*res).Add(-toLoad)
|
||||||
// load group
|
// load group
|
||||||
sg.Load += toLoad
|
sg.Load = sg.Load.Add(toLoad)
|
||||||
sg.CargoType = &ct
|
sg.CargoType = &ct
|
||||||
c.LaunchShips(sg, dest)
|
c.LaunchShips(sg, dest)
|
||||||
groups = reorderGroups(groups)
|
groups = reorderGroups(groups)
|
||||||
@@ -214,7 +214,7 @@ func (c *Cache) RemoveUnreachableRoutes() {
|
|||||||
ri := c.RaceIndex(p1.Owner)
|
ri := c.RaceIndex(p1.Owner)
|
||||||
for rt, destination := range p1.Route {
|
for rt, destination := range p1.Route {
|
||||||
p2 := c.MustPlanet(destination)
|
p2 := c.MustPlanet(destination)
|
||||||
rangeToDestination := util.ShortDistance(c.g.Map.Width, c.g.Map.Height, p1.X, p1.Y, p2.X, p2.Y)
|
rangeToDestination := util.ShortDistance(c.g.Map.Width, c.g.Map.Height, p1.X.F(), p1.Y.F(), p2.X.F(), p2.Y.F())
|
||||||
if rangeToDestination > c.g.Race[ri].FlightDistance() {
|
if rangeToDestination > c.g.Race[ri].FlightDistance() {
|
||||||
delete(p1.Route, rt)
|
delete(p1.Route, rt)
|
||||||
}
|
}
|
||||||
@@ -224,7 +224,7 @@ func (c *Cache) RemoveUnreachableRoutes() {
|
|||||||
|
|
||||||
func (c *Cache) doUnload(groups iter.Seq[int]) {
|
func (c *Cache) doUnload(groups iter.Seq[int]) {
|
||||||
for sgi := range groups {
|
for sgi := range groups {
|
||||||
c.unsafeUnloadCargo(sgi, c.ShipGroup(sgi).Load)
|
c.unsafeUnloadCargo(sgi, c.ShipGroup(sgi).Load.F())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +255,7 @@ func (c *Cache) selectColUnloadGroup(groups []int) (result iter.Seq[int]) {
|
|||||||
sg := c.ShipGroup(i)
|
sg := c.ShipGroup(i)
|
||||||
ri := c.RaceIndex(sg.OwnerID)
|
ri := c.RaceIndex(sg.OwnerID)
|
||||||
groupByRace[ri] = append(groupByRace[ri], i)
|
groupByRace[ri] = append(groupByRace[ri], i)
|
||||||
loadByRace[ri] += sg.Load
|
loadByRace[ri] += sg.Load.F()
|
||||||
}
|
}
|
||||||
if len(loadByRace) < 2 {
|
if len(loadByRace) < 2 {
|
||||||
// only one race has to unload cargo
|
// only one race has to unload cargo
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ func TestListRoutedSendGroupIds(t *testing.T) {
|
|||||||
assert.Equal(t, Race_0_ID, sg.OwnerID)
|
assert.Equal(t, Race_0_ID, sg.OwnerID)
|
||||||
assert.Greater(t, sg.CargoCapacity(st), 0.)
|
assert.Greater(t, sg.CargoCapacity(st), 0.)
|
||||||
assert.Equal(t, game.StateInOrbit, sg.State())
|
assert.Equal(t, game.StateInOrbit, sg.State())
|
||||||
assert.Equal(t, 0., sg.Load)
|
assert.Equal(t, 0., sg.Load.F())
|
||||||
assert.Nil(t, sg.FleetID)
|
assert.Nil(t, sg.FleetID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,11 +149,11 @@ func TestEnrouteGroups_SplitGroup(t *testing.T) {
|
|||||||
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 2)
|
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 2)
|
||||||
assert.Equal(t, game.StateInOrbit, c.ShipGroup(0).State())
|
assert.Equal(t, game.StateInOrbit, c.ShipGroup(0).State())
|
||||||
assert.Equal(t, uint(1), c.ShipGroup(0).Number)
|
assert.Equal(t, uint(1), c.ShipGroup(0).Number)
|
||||||
assert.Equal(t, 0., c.ShipGroup(0).Load)
|
assert.Equal(t, 0., c.ShipGroup(0).Load.F())
|
||||||
assert.Equal(t, game.StateLaunched, c.ShipGroup(1).State())
|
assert.Equal(t, game.StateLaunched, c.ShipGroup(1).State())
|
||||||
assert.Equal(t, uint(4), c.ShipGroup(1).Number)
|
assert.Equal(t, uint(4), c.ShipGroup(1).Number)
|
||||||
assert.Equal(t, 65., c.ShipGroup(1).Load)
|
assert.Equal(t, 65., c.ShipGroup(1).Load.F())
|
||||||
assert.Equal(t, 0., c.MustPlanet(R0_Planet_0_num).Colonists)
|
assert.Equal(t, 0., c.MustPlanet(R0_Planet_0_num).Colonists.F())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEnrouteGroups_GroupSorting(t *testing.T) {
|
func TestEnrouteGroups_GroupSorting(t *testing.T) {
|
||||||
@@ -177,8 +177,8 @@ func TestEnrouteGroups_GroupSorting(t *testing.T) {
|
|||||||
assert.Equal(t, game.StateInOrbit, c.ShipGroup(0).State())
|
assert.Equal(t, game.StateInOrbit, c.ShipGroup(0).State())
|
||||||
assert.Equal(t, game.StateLaunched, c.ShipGroup(1).State())
|
assert.Equal(t, game.StateLaunched, c.ShipGroup(1).State())
|
||||||
|
|
||||||
assert.Equal(t, 100., c.ShipGroup(1).Load)
|
assert.Equal(t, 100., c.ShipGroup(1).Load.F())
|
||||||
assert.Equal(t, 0., c.MustPlanet(R0_Planet_0_num).Colonists)
|
assert.Equal(t, 0., c.MustPlanet(R0_Planet_0_num).Colonists.F())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEnrouteGroups_LaunchOrder(t *testing.T) {
|
func TestEnrouteGroups_LaunchOrder(t *testing.T) {
|
||||||
@@ -215,7 +215,7 @@ func TestEnrouteGroups_LaunchOrder(t *testing.T) {
|
|||||||
sgi := 0
|
sgi := 0
|
||||||
assert.Equal(t, game.StateLaunched, c.ShipGroup(sgi).State())
|
assert.Equal(t, game.StateLaunched, c.ShipGroup(sgi).State())
|
||||||
assert.Equal(t, R0_Planet_2_num, c.ShipGroup(sgi).Destination)
|
assert.Equal(t, R0_Planet_2_num, c.ShipGroup(sgi).Destination)
|
||||||
assert.Equal(t, 105., c.ShipGroup(sgi).Load)
|
assert.Equal(t, 105., c.ShipGroup(sgi).Load.F())
|
||||||
assert.NotNil(t, c.ShipGroup(sgi).CargoType)
|
assert.NotNil(t, c.ShipGroup(sgi).CargoType)
|
||||||
assert.Equal(t, game.CargoColonist, *c.ShipGroup(sgi).CargoType)
|
assert.Equal(t, game.CargoColonist, *c.ShipGroup(sgi).CargoType)
|
||||||
assert.Equal(t, uint(5), c.ShipGroup(sgi).Number)
|
assert.Equal(t, uint(5), c.ShipGroup(sgi).Number)
|
||||||
@@ -224,7 +224,7 @@ func TestEnrouteGroups_LaunchOrder(t *testing.T) {
|
|||||||
sgi = 3
|
sgi = 3
|
||||||
assert.Equal(t, game.StateLaunched, c.ShipGroup(sgi).State())
|
assert.Equal(t, game.StateLaunched, c.ShipGroup(sgi).State())
|
||||||
assert.Equal(t, R0_Planet_2_num, c.ShipGroup(sgi).Destination)
|
assert.Equal(t, R0_Planet_2_num, c.ShipGroup(sgi).Destination)
|
||||||
assert.Equal(t, 45., c.ShipGroup(sgi).Load)
|
assert.Equal(t, 45., c.ShipGroup(sgi).Load.F())
|
||||||
assert.NotNil(t, c.ShipGroup(sgi).CargoType)
|
assert.NotNil(t, c.ShipGroup(sgi).CargoType)
|
||||||
assert.Equal(t, game.CargoColonist, *c.ShipGroup(sgi).CargoType)
|
assert.Equal(t, game.CargoColonist, *c.ShipGroup(sgi).CargoType)
|
||||||
assert.Equal(t, uint(3), c.ShipGroup(sgi).Number)
|
assert.Equal(t, uint(3), c.ShipGroup(sgi).Number)
|
||||||
@@ -233,7 +233,7 @@ func TestEnrouteGroups_LaunchOrder(t *testing.T) {
|
|||||||
sgi = 2
|
sgi = 2
|
||||||
assert.Equal(t, game.StateLaunched, c.ShipGroup(sgi).State())
|
assert.Equal(t, game.StateLaunched, c.ShipGroup(sgi).State())
|
||||||
assert.Equal(t, R0_Planet_2_num, c.ShipGroup(sgi).Destination)
|
assert.Equal(t, R0_Planet_2_num, c.ShipGroup(sgi).Destination)
|
||||||
assert.Equal(t, 100., c.ShipGroup(sgi).Load)
|
assert.Equal(t, 100., c.ShipGroup(sgi).Load.F())
|
||||||
assert.NotNil(t, c.ShipGroup(sgi).CargoType)
|
assert.NotNil(t, c.ShipGroup(sgi).CargoType)
|
||||||
assert.Equal(t, game.CargoCapital, *c.ShipGroup(sgi).CargoType)
|
assert.Equal(t, game.CargoCapital, *c.ShipGroup(sgi).CargoType)
|
||||||
assert.Equal(t, uint(5), c.ShipGroup(sgi).Number)
|
assert.Equal(t, uint(5), c.ShipGroup(sgi).Number)
|
||||||
@@ -242,7 +242,7 @@ func TestEnrouteGroups_LaunchOrder(t *testing.T) {
|
|||||||
sgi = 4
|
sgi = 4
|
||||||
assert.Equal(t, game.StateLaunched, c.ShipGroup(sgi).State())
|
assert.Equal(t, game.StateLaunched, c.ShipGroup(sgi).State())
|
||||||
assert.Equal(t, R0_Planet_2_num, c.ShipGroup(sgi).Destination)
|
assert.Equal(t, R0_Planet_2_num, c.ShipGroup(sgi).Destination)
|
||||||
assert.Equal(t, 20., c.ShipGroup(sgi).Load)
|
assert.Equal(t, 20., c.ShipGroup(sgi).Load.F())
|
||||||
assert.NotNil(t, c.ShipGroup(sgi).CargoType)
|
assert.NotNil(t, c.ShipGroup(sgi).CargoType)
|
||||||
assert.Equal(t, game.CargoMaterial, *c.ShipGroup(sgi).CargoType)
|
assert.Equal(t, game.CargoMaterial, *c.ShipGroup(sgi).CargoType)
|
||||||
assert.Equal(t, uint(1), c.ShipGroup(sgi).Number)
|
assert.Equal(t, uint(1), c.ShipGroup(sgi).Number)
|
||||||
@@ -251,7 +251,7 @@ func TestEnrouteGroups_LaunchOrder(t *testing.T) {
|
|||||||
sgi = 1
|
sgi = 1
|
||||||
assert.Equal(t, game.StateLaunched, c.ShipGroup(sgi).State())
|
assert.Equal(t, game.StateLaunched, c.ShipGroup(sgi).State())
|
||||||
assert.Equal(t, R1_Planet_1_num, c.ShipGroup(sgi).Destination)
|
assert.Equal(t, R1_Planet_1_num, c.ShipGroup(sgi).Destination)
|
||||||
assert.Equal(t, 0., c.ShipGroup(sgi).Load)
|
assert.Equal(t, 0., c.ShipGroup(sgi).Load.F())
|
||||||
assert.Nil(t, c.ShipGroup(sgi).CargoType)
|
assert.Nil(t, c.ShipGroup(sgi).CargoType)
|
||||||
assert.Equal(t, uint(1), c.ShipGroup(sgi).Number)
|
assert.Equal(t, uint(1), c.ShipGroup(sgi).Number)
|
||||||
}
|
}
|
||||||
@@ -406,15 +406,15 @@ func TestTurnUnloadEnroutedGroups(t *testing.T) {
|
|||||||
|
|
||||||
c.TurnUnloadEnroutedGroups()
|
c.TurnUnloadEnroutedGroups()
|
||||||
|
|
||||||
assert.Equal(t, 0., c.ShipGroup(0).Load)
|
assert.Equal(t, 0., c.ShipGroup(0).Load.F())
|
||||||
assert.Equal(t, 222., c.MustPlanet(R0_Planet_0_num).Material)
|
assert.Equal(t, 222., c.MustPlanet(R0_Planet_0_num).Material.F())
|
||||||
assert.Equal(t, 0., c.ShipGroup(1).Load)
|
assert.Equal(t, 0., c.ShipGroup(1).Load.F())
|
||||||
assert.Equal(t, 11., c.MustPlanet(R0_Planet_0_num).Capital)
|
assert.Equal(t, 11., c.MustPlanet(R0_Planet_0_num).Capital.F())
|
||||||
assert.Equal(t, 0., c.ShipGroup(2).Load)
|
assert.Equal(t, 0., c.ShipGroup(2).Load.F())
|
||||||
assert.Equal(t, 96.8, c.MustPlanet(Uninhabited_Planet_4_num).Population)
|
assert.Equal(t, 96.8, c.MustPlanet(Uninhabited_Planet_4_num).Population.F())
|
||||||
assert.Equal(t, Race_1_ID, c.MustPlanet(Uninhabited_Planet_4_num).Owner)
|
assert.Equal(t, Race_1_ID, c.MustPlanet(Uninhabited_Planet_4_num).Owner)
|
||||||
assert.Equal(t, game.ProductionCapital, c.MustPlanet(Uninhabited_Planet_4_num).Production.Type)
|
assert.Equal(t, game.ProductionCapital, c.MustPlanet(Uninhabited_Planet_4_num).Production.Type)
|
||||||
assert.Equal(t, 17.3, c.ShipGroup(3).Load)
|
assert.Equal(t, 17.3, c.ShipGroup(3).Load.F())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRemoveUnreachableRoutes(t *testing.T) {
|
func TestRemoveUnreachableRoutes(t *testing.T) {
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ func (c *Cache) ShipGroupJoinFleet(groupIndex int, fID *uuid.UUID) {
|
|||||||
func (c *Cache) ShipGroupShipsNumber(groupIndex int, number uint) {
|
func (c *Cache) ShipGroupShipsNumber(groupIndex int, number uint) {
|
||||||
c.validateShipGroupIndex(groupIndex)
|
c.validateShipGroupIndex(groupIndex)
|
||||||
if c.g.ShipGroups[groupIndex].Number > 0 {
|
if c.g.ShipGroups[groupIndex].Number > 0 {
|
||||||
c.g.ShipGroups[groupIndex].Load = c.g.ShipGroups[groupIndex].Load / float64(c.g.ShipGroups[groupIndex].Number) * float64(number)
|
c.g.ShipGroups[groupIndex].Load = game.F(c.g.ShipGroups[groupIndex].Load.F() / float64(c.g.ShipGroups[groupIndex].Number) * float64(number))
|
||||||
}
|
}
|
||||||
c.g.ShipGroups[groupIndex].Number = number
|
c.g.ShipGroups[groupIndex].Number = number
|
||||||
}
|
}
|
||||||
@@ -228,20 +228,20 @@ func (c *Cache) DisassembleGroup(ri int, groupIndex, quantity uint) error {
|
|||||||
|
|
||||||
if c.ShipGroup(sgi).CargoType != nil {
|
if c.ShipGroup(sgi).CargoType != nil {
|
||||||
ct := *c.ShipGroup(sgi).CargoType
|
ct := *c.ShipGroup(sgi).CargoType
|
||||||
load := c.ShipGroup(sgi).Load
|
load := c.ShipGroup(sgi).Load.F()
|
||||||
switch ct {
|
switch ct {
|
||||||
case game.CargoColonist:
|
case game.CargoColonist:
|
||||||
if p.Owner == c.g.Race[ri].ID {
|
if p.Owner == c.g.Race[ri].ID {
|
||||||
p = game.UnloadColonists(p, load)
|
p = game.UnloadColonists(p, load)
|
||||||
}
|
}
|
||||||
case game.CargoMaterial:
|
case game.CargoMaterial:
|
||||||
p.Material += load
|
p.Material = p.Material.Add(load)
|
||||||
case game.CargoCapital:
|
case game.CargoCapital:
|
||||||
p.Capital += load
|
p.Capital = p.Capital.Add(load)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Material += c.ShipGroup(sgi).EmptyMass(st)
|
p.Material = p.Material.Add(c.ShipGroup(sgi).EmptyMass(st))
|
||||||
|
|
||||||
c.unsafeDeleteShipGroup(sgi)
|
c.unsafeDeleteShipGroup(sgi)
|
||||||
|
|
||||||
@@ -300,11 +300,11 @@ func (c *Cache) LoadCargo(ri int, groupIndex uint, ct game.CargoType, ships uint
|
|||||||
sgi = nsgi
|
sgi = nsgi
|
||||||
}
|
}
|
||||||
capacity := c.ShipGroup(sgi).CargoCapacity(st)
|
capacity := c.ShipGroup(sgi).CargoCapacity(st)
|
||||||
freeShipGroupCargoLoad := capacity - c.ShipGroup(sgi).Load
|
freeShipGroupCargoLoad := capacity - c.ShipGroup(sgi).Load.F()
|
||||||
if freeShipGroupCargoLoad == 0 {
|
if freeShipGroupCargoLoad == 0 {
|
||||||
return e.NewCargoLoadNoSpaceLeftError()
|
return e.NewCargoLoadNoSpaceLeftError()
|
||||||
}
|
}
|
||||||
var availableOnPlanet *float64
|
var availableOnPlanet *game.Float
|
||||||
switch ct {
|
switch ct {
|
||||||
case game.CargoMaterial:
|
case game.CargoMaterial:
|
||||||
availableOnPlanet = &p.Material
|
availableOnPlanet = &p.Material
|
||||||
@@ -315,18 +315,18 @@ func (c *Cache) LoadCargo(ri int, groupIndex uint, ct game.CargoType, ships uint
|
|||||||
default:
|
default:
|
||||||
return e.NewGameStateError("CargoType not accepted: %v", ct)
|
return e.NewGameStateError("CargoType not accepted: %v", ct)
|
||||||
}
|
}
|
||||||
if quantity > *availableOnPlanet || *availableOnPlanet == 0 {
|
if quantity > float64(*availableOnPlanet) || *availableOnPlanet == 0 {
|
||||||
return e.NewCargoLoadNotEnoughError("planet: #%d, %s=%.03f", p.Number, ct, *availableOnPlanet)
|
return e.NewCargoLoadNotEnoughError("planet: #%d, %s=%.03f", p.Number, ct, *availableOnPlanet)
|
||||||
}
|
}
|
||||||
toBeLoaded := quantity
|
toBeLoaded := quantity
|
||||||
if quantity == 0 {
|
if quantity == 0 {
|
||||||
toBeLoaded = *availableOnPlanet
|
toBeLoaded = float64(*availableOnPlanet)
|
||||||
}
|
}
|
||||||
if toBeLoaded > freeShipGroupCargoLoad {
|
if toBeLoaded > freeShipGroupCargoLoad {
|
||||||
toBeLoaded = freeShipGroupCargoLoad
|
toBeLoaded = freeShipGroupCargoLoad
|
||||||
}
|
}
|
||||||
*availableOnPlanet = *availableOnPlanet - toBeLoaded
|
*availableOnPlanet = (*availableOnPlanet).Add(-toBeLoaded)
|
||||||
c.ShipGroup(sgi).Load += toBeLoaded
|
c.ShipGroup(sgi).Load = c.ShipGroup(sgi).Load.Add(toBeLoaded)
|
||||||
if c.ShipGroup(sgi).Load > 0 {
|
if c.ShipGroup(sgi).Load > 0 {
|
||||||
c.ShipGroup(sgi).CargoType = &ct
|
c.ShipGroup(sgi).CargoType = &ct
|
||||||
}
|
}
|
||||||
@@ -379,9 +379,9 @@ func (c *Cache) UnloadCargo(ri int, groupIndex uint, ships uint, quantity float6
|
|||||||
|
|
||||||
toBeUnloaded := quantity
|
toBeUnloaded := quantity
|
||||||
if quantity == 0 {
|
if quantity == 0 {
|
||||||
toBeUnloaded = c.ShipGroup(sgi).Load
|
toBeUnloaded = c.ShipGroup(sgi).Load.F()
|
||||||
}
|
}
|
||||||
if toBeUnloaded > c.ShipGroup(sgi).Load {
|
if toBeUnloaded > c.ShipGroup(sgi).Load.F() {
|
||||||
return e.NewCargoUnoadNotEnoughError("load: %.03f", c.ShipGroup(sgi).Load)
|
return e.NewCargoUnoadNotEnoughError("load: %.03f", c.ShipGroup(sgi).Load)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,7 +401,7 @@ func (c *Cache) unsafeUnloadCargo(sgi int, q float64) {
|
|||||||
p := c.MustPlanet(c.ShipGroup(sgi).Destination)
|
p := c.MustPlanet(c.ShipGroup(sgi).Destination)
|
||||||
ct := *c.ShipGroup(sgi).CargoType
|
ct := *c.ShipGroup(sgi).CargoType
|
||||||
|
|
||||||
var availableOnPlanet *float64
|
var availableOnPlanet *game.Float
|
||||||
switch ct {
|
switch ct {
|
||||||
case game.CargoColonist:
|
case game.CargoColonist:
|
||||||
availableOnPlanet = &p.Colonists
|
availableOnPlanet = &p.Colonists
|
||||||
@@ -414,9 +414,9 @@ func (c *Cache) unsafeUnloadCargo(sgi int, q float64) {
|
|||||||
case game.CargoCapital:
|
case game.CargoCapital:
|
||||||
availableOnPlanet = &p.Capital
|
availableOnPlanet = &p.Capital
|
||||||
}
|
}
|
||||||
*availableOnPlanet += q
|
*availableOnPlanet = (*availableOnPlanet).Add(q)
|
||||||
|
|
||||||
c.ShipGroup(sgi).Load -= q // TODO: apply rounding for Load property?
|
c.ShipGroup(sgi).Load = c.ShipGroup(sgi).Load.Add(-q) // TODO: apply rounding for Load property?
|
||||||
if c.ShipGroup(sgi).Load == 0 {
|
if c.ShipGroup(sgi).Load == 0 {
|
||||||
c.ShipGroup(sgi).CargoType = nil
|
c.ShipGroup(sgi).CargoType = nil
|
||||||
}
|
}
|
||||||
@@ -532,7 +532,7 @@ func (c *Cache) breakGroupSafe(ri int, groupIndex uint, newGroupShips uint) (int
|
|||||||
func (c *Cache) breakGroupUnsafe(ri, sgi int, newGroupShips uint) int {
|
func (c *Cache) breakGroupUnsafe(ri, sgi int, newGroupShips uint) int {
|
||||||
newGroup := *c.ShipGroup(sgi)
|
newGroup := *c.ShipGroup(sgi)
|
||||||
if c.ShipGroup(sgi).CargoType != nil {
|
if c.ShipGroup(sgi).CargoType != nil {
|
||||||
newGroup.Load = c.ShipGroup(sgi).Load / float64(c.ShipGroup(sgi).Number) * float64(newGroupShips)
|
newGroup.Load = game.F(c.ShipGroup(sgi).Load.F() / float64(c.ShipGroup(sgi).Number) * float64(newGroupShips))
|
||||||
}
|
}
|
||||||
newGroup.Number = newGroupShips
|
newGroup.Number = newGroupShips
|
||||||
c.ShipGroupShipsNumber(sgi, c.ShipGroup(sgi).Number-newGroup.Number)
|
c.ShipGroupShipsNumber(sgi, c.ShipGroup(sgi).Number-newGroup.Number)
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ func (c *Cache) moveShipGroup(i int, delta float64) {
|
|||||||
destPlanet := c.MustPlanet(sg.Destination)
|
destPlanet := c.MustPlanet(sg.Destination)
|
||||||
arrived := false
|
arrived := false
|
||||||
sg.StateInSpace.X, sg.StateInSpace.Y, arrived =
|
sg.StateInSpace.X, sg.StateInSpace.Y, arrived =
|
||||||
util.NextTravelCoord(c.g.Map.Width, c.g.Map.Height, originX, originY, destPlanet.X, destPlanet.Y, delta)
|
util.NextTravelCoord(c.g.Map.Width, c.g.Map.Height, originX, originY, destPlanet.X.F(), destPlanet.Y.F(), delta)
|
||||||
if arrived {
|
if arrived {
|
||||||
sg.StateInSpace = nil
|
sg.StateInSpace = nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ func (c *Cache) SendGroup(ri int, groupIndex, planetNumber, quantity uint) error
|
|||||||
if !ok {
|
if !ok {
|
||||||
return e.NewEntityNotExistsError("destination planet #%d", planetNumber)
|
return e.NewEntityNotExistsError("destination planet #%d", planetNumber)
|
||||||
}
|
}
|
||||||
rangeToDestination := util.ShortDistance(c.g.Map.Width, c.g.Map.Height, p1.X, p1.Y, p2.X, p2.Y)
|
rangeToDestination := util.ShortDistance(c.g.Map.Width, c.g.Map.Height, p1.X.F(), p1.Y.F(), p2.X.F(), p2.Y.F())
|
||||||
if rangeToDestination > c.g.Race[ri].FlightDistance() {
|
if rangeToDestination > c.g.Race[ri].FlightDistance() {
|
||||||
return e.NewSendUnreachableDestinationError("range=%.03f", rangeToDestination)
|
return e.NewSendUnreachableDestinationError("range=%.03f", rangeToDestination)
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ func (c *Cache) LaunchShips(sg *game.ShipGroup, destination uint) *game.ShipGrou
|
|||||||
default:
|
default:
|
||||||
panic("state invalid")
|
panic("state invalid")
|
||||||
}
|
}
|
||||||
c.g.ShipGroups[i] = LaunchShips(*sg, destination, p.X, p.Y)
|
c.g.ShipGroups[i] = LaunchShips(*sg, destination, p.X.F(), p.Y.F())
|
||||||
return &c.g.ShipGroups[i]
|
return &c.g.ShipGroups[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ func TestSendGroup(t *testing.T) {
|
|||||||
assert.Equal(t, uint(3), c.ShipGroup(3).Number)
|
assert.Equal(t, uint(3), c.ShipGroup(3).Number)
|
||||||
assert.Equal(t, game.StateLaunched, c.ShipGroup(3).State())
|
assert.Equal(t, game.StateLaunched, c.ShipGroup(3).State())
|
||||||
assert.NotNil(t, c.ShipGroup(3).StateInSpace)
|
assert.NotNil(t, c.ShipGroup(3).StateInSpace)
|
||||||
assert.Equal(t, c.MustPlanet(R0_Planet_0_num).X, c.ShipGroup(3).StateInSpace.X)
|
assert.Equal(t, c.MustPlanet(R0_Planet_0_num).X.F(), c.ShipGroup(3).StateInSpace.X)
|
||||||
assert.Equal(t, c.MustPlanet(R0_Planet_0_num).Y, c.ShipGroup(3).StateInSpace.Y)
|
assert.Equal(t, c.MustPlanet(R0_Planet_0_num).Y.F(), c.ShipGroup(3).StateInSpace.Y)
|
||||||
|
|
||||||
assert.NoError(t, g.SendGroup(Race_0.Name, 4, R0_Planet_0_num, 2)) // un-send 2 of 3
|
assert.NoError(t, g.SendGroup(Race_0.Name, 4, R0_Planet_0_num, 2)) // un-send 2 of 3
|
||||||
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 4)
|
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 4)
|
||||||
@@ -61,8 +61,8 @@ func TestSendGroup(t *testing.T) {
|
|||||||
assert.Equal(t, uint(1), c.MustShipGroup(Race_0_idx, 4).Number)
|
assert.Equal(t, uint(1), c.MustShipGroup(Race_0_idx, 4).Number)
|
||||||
assert.Equal(t, game.StateLaunched, c.MustShipGroup(Race_0_idx, 4).State())
|
assert.Equal(t, game.StateLaunched, c.MustShipGroup(Race_0_idx, 4).State())
|
||||||
assert.NotNil(t, c.MustShipGroup(Race_0_idx, 4).StateInSpace)
|
assert.NotNil(t, c.MustShipGroup(Race_0_idx, 4).StateInSpace)
|
||||||
assert.Equal(t, c.MustPlanet(R0_Planet_0_num).X, c.MustShipGroup(Race_0_idx, 4).StateInSpace.X)
|
assert.Equal(t, c.MustPlanet(R0_Planet_0_num).X.F(), c.MustShipGroup(Race_0_idx, 4).StateInSpace.X)
|
||||||
assert.Equal(t, c.MustPlanet(R0_Planet_0_num).Y, c.MustShipGroup(Race_0_idx, 4).StateInSpace.Y)
|
assert.Equal(t, c.MustPlanet(R0_Planet_0_num).Y.F(), c.MustShipGroup(Race_0_idx, 4).StateInSpace.Y)
|
||||||
|
|
||||||
assert.NoError(t, g.SendGroup(Race_0.Name, 4, R0_Planet_0_num, 0)) // un-send the rest 1
|
assert.NoError(t, g.SendGroup(Race_0.Name, 4, R0_Planet_0_num, 0)) // un-send the rest 1
|
||||||
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3)
|
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3)
|
||||||
|
|||||||
@@ -142,9 +142,9 @@ func TestBreakGroup(t *testing.T) {
|
|||||||
assert.NotNil(t, c.ShipGroup(3).FleetID)
|
assert.NotNil(t, c.ShipGroup(3).FleetID)
|
||||||
|
|
||||||
assert.Equal(t, game.CargoColonist.Ref(), c.ShipGroup(0).CargoType)
|
assert.Equal(t, game.CargoColonist.Ref(), c.ShipGroup(0).CargoType)
|
||||||
assert.Equal(t, 24.6, number.Fixed3(c.ShipGroup(0).Load))
|
assert.Equal(t, 24.6, number.Fixed3(c.ShipGroup(0).Load.F()))
|
||||||
assert.Equal(t, game.CargoColonist.Ref(), c.ShipGroup(3).CargoType)
|
assert.Equal(t, game.CargoColonist.Ref(), c.ShipGroup(3).CargoType)
|
||||||
assert.Equal(t, 8.2, number.Fixed3(c.ShipGroup(3).Load))
|
assert.Equal(t, 8.2, number.Fixed3(c.ShipGroup(3).Load.F()))
|
||||||
|
|
||||||
// group #1 -> MAX 6 off the fleet
|
// group #1 -> MAX 6 off the fleet
|
||||||
assert.NoError(t, g.BreakGroup(Race_0.Name, 1, 6)) // group #1 (0)
|
assert.NoError(t, g.BreakGroup(Race_0.Name, 1, 6)) // group #1 (0)
|
||||||
@@ -295,48 +295,48 @@ func TestLoadCargo(t *testing.T) {
|
|||||||
|
|
||||||
// break group and load maximum
|
// break group and load maximum
|
||||||
assert.NoError(t, g.LoadCargo(Race_0.Name, 1, game.CargoMaterial.String(), 2, 0))
|
assert.NoError(t, g.LoadCargo(Race_0.Name, 1, game.CargoMaterial.String(), 2, 0))
|
||||||
assert.Equal(t, 58.0, c.MustPlanet(R0_Planet_0_num).Material)
|
assert.Equal(t, 58.0, c.MustPlanet(R0_Planet_0_num).Material.F())
|
||||||
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 6)
|
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 6)
|
||||||
assert.Nil(t, c.ShipGroup(0).CargoType)
|
assert.Nil(t, c.ShipGroup(0).CargoType)
|
||||||
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(5).CargoType)
|
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(5).CargoType)
|
||||||
assert.Equal(t, uint(9), c.ShipGroup(0).Number)
|
assert.Equal(t, uint(9), c.ShipGroup(0).Number)
|
||||||
assert.Equal(t, 0.0, c.ShipGroup(0).Load)
|
assert.Equal(t, 0.0, c.ShipGroup(0).Load.F())
|
||||||
assert.Equal(t, uint(2), c.ShipGroup(5).Number)
|
assert.Equal(t, uint(2), c.ShipGroup(5).Number)
|
||||||
assert.Equal(t, 42.0, c.ShipGroup(5).Load)
|
assert.Equal(t, 42.0, c.ShipGroup(5).Load.F())
|
||||||
|
|
||||||
// break group and load limited
|
// break group and load limited
|
||||||
assert.NoError(t, g.LoadCargo(Race_0.Name, 1, game.CargoMaterial.String(), 2, 18))
|
assert.NoError(t, g.LoadCargo(Race_0.Name, 1, game.CargoMaterial.String(), 2, 18))
|
||||||
assert.Equal(t, 40.0, c.MustPlanet(R0_Planet_0_num).Material)
|
assert.Equal(t, 40.0, c.MustPlanet(R0_Planet_0_num).Material.F())
|
||||||
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 7)
|
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 7)
|
||||||
assert.Nil(t, c.ShipGroup(0).CargoType)
|
assert.Nil(t, c.ShipGroup(0).CargoType)
|
||||||
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(6).CargoType)
|
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(6).CargoType)
|
||||||
assert.Equal(t, uint(7), c.ShipGroup(0).Number)
|
assert.Equal(t, uint(7), c.ShipGroup(0).Number)
|
||||||
assert.Equal(t, 0.0, c.ShipGroup(0).Load)
|
assert.Equal(t, 0.0, c.ShipGroup(0).Load.F())
|
||||||
assert.Equal(t, uint(2), c.ShipGroup(6).Number)
|
assert.Equal(t, uint(2), c.ShipGroup(6).Number)
|
||||||
assert.Equal(t, 18.0, c.ShipGroup(6).Load)
|
assert.Equal(t, 18.0, c.ShipGroup(6).Load.F())
|
||||||
|
|
||||||
// add cargo to planet
|
// add cargo to planet
|
||||||
c.PutMaterial(R0_Planet_0_num, 100)
|
c.PutMaterial(R0_Planet_0_num, 100)
|
||||||
// loading all available cargo
|
// loading all available cargo
|
||||||
assert.NoError(t, g.LoadCargo(Race_0.Name, 1, game.CargoMaterial.String(), 0, 0))
|
assert.NoError(t, g.LoadCargo(Race_0.Name, 1, game.CargoMaterial.String(), 0, 0))
|
||||||
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 7)
|
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 7)
|
||||||
assert.Equal(t, 0.0, c.MustPlanet(R0_Planet_0_num).Material)
|
assert.Equal(t, 0.0, c.MustPlanet(R0_Planet_0_num).Material.F())
|
||||||
assert.Equal(t, 100.0, c.ShipGroup(0).Load) // free: 131.0
|
assert.Equal(t, 100.0, c.ShipGroup(0).Load.F()) // free: 131.0
|
||||||
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(0).CargoType)
|
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(0).CargoType)
|
||||||
|
|
||||||
// add cargo to planet
|
// add cargo to planet
|
||||||
c.PutMaterial(R0_Planet_0_num, 200)
|
c.PutMaterial(R0_Planet_0_num, 200)
|
||||||
assert.NoError(t, g.LoadCargo(Race_0.Name, 1, game.CargoMaterial.String(), 11, 31))
|
assert.NoError(t, g.LoadCargo(Race_0.Name, 1, game.CargoMaterial.String(), 11, 31))
|
||||||
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 7)
|
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 7)
|
||||||
assert.Equal(t, 169.0, c.MustPlanet(R0_Planet_0_num).Material)
|
assert.Equal(t, 169.0, c.MustPlanet(R0_Planet_0_num).Material.F())
|
||||||
assert.Equal(t, 131.0, c.ShipGroup(0).Load) // free: 100.0
|
assert.Equal(t, 131.0, c.ShipGroup(0).Load.F()) // free: 100.0
|
||||||
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(0).CargoType)
|
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(0).CargoType)
|
||||||
|
|
||||||
// load to maximum cargo space left
|
// load to maximum cargo space left
|
||||||
assert.NoError(t, g.LoadCargo(Race_0.Name, 1, game.CargoMaterial.String(), 11, 0))
|
assert.NoError(t, g.LoadCargo(Race_0.Name, 1, game.CargoMaterial.String(), 11, 0))
|
||||||
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 7)
|
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 7)
|
||||||
assert.Equal(t, 153.0, c.MustPlanet(R0_Planet_0_num).Material)
|
assert.Equal(t, 153.0, c.MustPlanet(R0_Planet_0_num).Material.F())
|
||||||
assert.Equal(t, 147.0, c.ShipGroup(0).Load) // free: 0.0
|
assert.Equal(t, 147.0, c.ShipGroup(0).Load.F()) // free: 0.0
|
||||||
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(0).CargoType)
|
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(0).CargoType)
|
||||||
|
|
||||||
// ship group is full
|
// ship group is full
|
||||||
@@ -413,33 +413,33 @@ func TestUnloadCargo(t *testing.T) {
|
|||||||
|
|
||||||
// unload MAT on foreign planet / break group
|
// unload MAT on foreign planet / break group
|
||||||
assert.NoError(t, g.UnloadCargo(Race_0.Name, 6, 3, 0))
|
assert.NoError(t, g.UnloadCargo(Race_0.Name, 6, 3, 0))
|
||||||
assert.Equal(t, 27.273, number.Fixed3(c.MustPlanet(R1_Planet_1_num).Material))
|
assert.Equal(t, 27.273, number.Fixed3(c.MustPlanet(R1_Planet_1_num).Material.F()))
|
||||||
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 7)
|
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 7)
|
||||||
assert.Equal(t, uint(3), c.ShipGroup(6).Number)
|
assert.Equal(t, uint(3), c.ShipGroup(6).Number)
|
||||||
assert.Nil(t, c.ShipGroup(6).CargoType)
|
assert.Nil(t, c.ShipGroup(6).CargoType)
|
||||||
assert.Equal(t, 0.0, c.ShipGroup(6).Load)
|
assert.Equal(t, 0.0, c.ShipGroup(6).Load.F())
|
||||||
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(5).CargoType)
|
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(5).CargoType)
|
||||||
assert.Equal(t, uint(8), c.ShipGroup(5).Number)
|
assert.Equal(t, uint(8), c.ShipGroup(5).Number)
|
||||||
assert.Equal(t, 72.727, number.Fixed3(c.ShipGroup(5).Load))
|
assert.Equal(t, 72.727, number.Fixed3(c.ShipGroup(5).Load.F()))
|
||||||
|
|
||||||
// unload MAT on foreign planet / break group / limited MAT
|
// unload MAT on foreign planet / break group / limited MAT
|
||||||
assert.NoError(t, g.UnloadCargo(Race_0.Name, 6, 3, 20.0))
|
assert.NoError(t, g.UnloadCargo(Race_0.Name, 6, 3, 20.0))
|
||||||
assert.Equal(t, 47.273, number.Fixed3(c.MustPlanet(R1_Planet_1_num).Material))
|
assert.Equal(t, 47.273, number.Fixed3(c.MustPlanet(R1_Planet_1_num).Material.F()))
|
||||||
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 8)
|
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 8)
|
||||||
assert.Equal(t, uint(3), c.ShipGroup(7).Number)
|
assert.Equal(t, uint(3), c.ShipGroup(7).Number)
|
||||||
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(7).CargoType)
|
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(7).CargoType)
|
||||||
assert.Equal(t, 7.273, number.Fixed3(c.ShipGroup(7).Load))
|
assert.Equal(t, 7.273, number.Fixed3(c.ShipGroup(7).Load.F()))
|
||||||
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(5).CargoType)
|
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(5).CargoType)
|
||||||
assert.Equal(t, uint(5), c.ShipGroup(5).Number)
|
assert.Equal(t, uint(5), c.ShipGroup(5).Number)
|
||||||
assert.Equal(t, 45.455, number.Fixed3(c.ShipGroup(5).Load))
|
assert.Equal(t, 45.455, number.Fixed3(c.ShipGroup(5).Load.F()))
|
||||||
|
|
||||||
// unload ALL
|
// unload ALL
|
||||||
assert.NoError(t, g.UnloadCargo(Race_0.Name, 1, 0, 0))
|
assert.NoError(t, g.UnloadCargo(Race_0.Name, 1, 0, 0))
|
||||||
assert.Equal(t, 100.0, number.Fixed3(c.MustPlanet(R0_Planet_0_num).Colonists))
|
assert.Equal(t, 100.0, number.Fixed3(c.MustPlanet(R0_Planet_0_num).Colonists.F()))
|
||||||
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 8)
|
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 8)
|
||||||
assert.Equal(t, uint(10), c.ShipGroup(0).Number)
|
assert.Equal(t, uint(10), c.ShipGroup(0).Number)
|
||||||
assert.Nil(t, c.ShipGroup(0).CargoType)
|
assert.Nil(t, c.ShipGroup(0).CargoType)
|
||||||
assert.Equal(t, 0.0, number.Fixed3(c.ShipGroup(0).Load))
|
assert.Equal(t, 0.0, number.Fixed3(c.ShipGroup(0).Load.F()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDisassembleGroup(t *testing.T) {
|
func TestDisassembleGroup(t *testing.T) {
|
||||||
@@ -489,40 +489,40 @@ func TestDisassembleGroup(t *testing.T) {
|
|||||||
e.GenericErrorText(e.ErrBeakGroupNumberNotEnough))
|
e.GenericErrorText(e.ErrBeakGroupNumberNotEnough))
|
||||||
|
|
||||||
groupEmptyMass := c.ShipGroup(4).EmptyMass(c.MustShipClass(Race_0_idx, Race_0_Freighter))
|
groupEmptyMass := c.ShipGroup(4).EmptyMass(c.MustShipClass(Race_0_idx, Race_0_Freighter))
|
||||||
planetMAT := c.MustPlanet(R1_Planet_1_num).Material
|
planetMAT := c.MustPlanet(R1_Planet_1_num).Material.F()
|
||||||
planetCOL := c.MustPlanet(R1_Planet_1_num).Colonists
|
planetCOL := c.MustPlanet(R1_Planet_1_num).Colonists.F()
|
||||||
|
|
||||||
assert.NoError(t, g.DisassembleGroup(Race_0.Name, 5, 0))
|
assert.NoError(t, g.DisassembleGroup(Race_0.Name, 5, 0))
|
||||||
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 4)
|
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 4)
|
||||||
assert.Equal(t, planetMAT+groupEmptyMass, c.MustPlanet(R1_Planet_1_num).Material)
|
assert.Equal(t, planetMAT+groupEmptyMass, c.MustPlanet(R1_Planet_1_num).Material.F())
|
||||||
assert.Equal(t, planetCOL, c.MustPlanet(R1_Planet_1_num).Colonists)
|
assert.Equal(t, planetCOL, c.MustPlanet(R1_Planet_1_num).Colonists.F())
|
||||||
|
|
||||||
groupEmptyMass = c.ShipGroup(3).EmptyMass(c.MustShipClass(Race_0_idx, Race_0_Freighter))
|
groupEmptyMass = c.ShipGroup(3).EmptyMass(c.MustShipClass(Race_0_idx, Race_0_Freighter))
|
||||||
groupLoadMAT := c.ShipGroup(3).Load
|
groupLoadMAT := c.ShipGroup(3).Load.F()
|
||||||
planetMAT = c.MustPlanet(R1_Planet_1_num).Material
|
planetMAT = c.MustPlanet(R1_Planet_1_num).Material.F()
|
||||||
assert.NoError(t, g.DisassembleGroup(Race_0.Name, 4, 0))
|
assert.NoError(t, g.DisassembleGroup(Race_0.Name, 4, 0))
|
||||||
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3)
|
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3)
|
||||||
assert.Equal(t, planetMAT+groupEmptyMass+groupLoadMAT, c.MustPlanet(R1_Planet_1_num).Material)
|
assert.Equal(t, planetMAT+groupEmptyMass+groupLoadMAT, c.MustPlanet(R1_Planet_1_num).Material.F())
|
||||||
|
|
||||||
groupEmptyMass = c.ShipGroup(2).EmptyMass(c.MustShipClass(Race_0_idx, Race_0_Freighter))
|
groupEmptyMass = c.ShipGroup(2).EmptyMass(c.MustShipClass(Race_0_idx, Race_0_Freighter))
|
||||||
planetMAT = c.MustPlanet(R0_Planet_0_num).Material
|
planetMAT = c.MustPlanet(R0_Planet_0_num).Material.F()
|
||||||
planetCOL = c.MustPlanet(R0_Planet_0_num).Colonists
|
planetCOL = c.MustPlanet(R0_Planet_0_num).Colonists.F()
|
||||||
planetPOP := 90.0
|
planetPOP := 90.0
|
||||||
|
|
||||||
c.PutPopulation(R0_Planet_0_num, planetPOP)
|
c.PutPopulation(R0_Planet_0_num, planetPOP)
|
||||||
assert.Equal(t, planetPOP, c.MustPlanet(R0_Planet_0_num).Population)
|
assert.Equal(t, planetPOP, c.MustPlanet(R0_Planet_0_num).Population.F())
|
||||||
var quantity uint = 3
|
var quantity uint = 3
|
||||||
groupEmptyMass = groupEmptyMass / float64(c.ShipGroup(2).Number) * float64(quantity)
|
groupEmptyMass = groupEmptyMass / float64(c.ShipGroup(2).Number) * float64(quantity)
|
||||||
newGroupUnloadedCOL := c.ShipGroup(2).Load / float64(c.ShipGroup(2).Number) * float64(quantity)
|
newGroupUnloadedCOL := c.ShipGroup(2).Load.F() / float64(c.ShipGroup(2).Number) * float64(quantity)
|
||||||
expectPOPIncrease := newGroupUnloadedCOL * 8
|
expectPOPIncrease := newGroupUnloadedCOL * 8
|
||||||
freePOPLeft := c.MustPlanet(R0_Planet_0_num).Size - c.MustPlanet(R0_Planet_0_num).Population
|
freePOPLeft := c.MustPlanet(R0_Planet_0_num).Size.F() - c.MustPlanet(R0_Planet_0_num).Population.F()
|
||||||
expectAddedCOL := (expectPOPIncrease - freePOPLeft) / 8
|
expectAddedCOL := (expectPOPIncrease - freePOPLeft) / 8
|
||||||
expectAddedPOP := freePOPLeft
|
expectAddedPOP := freePOPLeft
|
||||||
assert.NoError(t, g.DisassembleGroup(Race_0.Name, 3, quantity))
|
assert.NoError(t, g.DisassembleGroup(Race_0.Name, 3, quantity))
|
||||||
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3)
|
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3)
|
||||||
assert.Equal(t, planetCOL+expectAddedCOL, c.MustPlanet(R0_Planet_0_num).Colonists)
|
assert.Equal(t, planetCOL+expectAddedCOL, c.MustPlanet(R0_Planet_0_num).Colonists.F())
|
||||||
assert.Equal(t, planetPOP+expectAddedPOP, c.MustPlanet(R0_Planet_0_num).Population)
|
assert.Equal(t, planetPOP+expectAddedPOP, c.MustPlanet(R0_Planet_0_num).Population.F())
|
||||||
assert.Equal(t, planetMAT+groupEmptyMass, c.MustPlanet(R0_Planet_0_num).Material)
|
assert.Equal(t, planetMAT+groupEmptyMass, c.MustPlanet(R0_Planet_0_num).Material.F())
|
||||||
assert.Equal(t, uint(7), c.ShipGroup(2).Number)
|
assert.Equal(t, uint(7), c.ShipGroup(2).Number)
|
||||||
assert.Equal(t, 56.0, c.ShipGroup(2).Load)
|
assert.Equal(t, 56.0, c.ShipGroup(2).Load.F())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ func (c *Cache) UpgradeGroup(ri int, groupIndex uint, techInput string, limitShi
|
|||||||
if c.g.Race[ri].TechLevel(tech) < limitLevel {
|
if c.g.Race[ri].TechLevel(tech) < limitLevel {
|
||||||
return e.NewUpgradeTechLevelInsufficientError("%s=%.03f < %.03f", tech.String(), c.g.Race[ri].TechLevel(tech), limitLevel)
|
return e.NewUpgradeTechLevelInsufficientError("%s=%.03f < %.03f", tech.String(), c.g.Race[ri].TechLevel(tech), limitLevel)
|
||||||
}
|
}
|
||||||
targetLevel[tech] = game.FutureUpgradeLevel(c.g.Race[ri].TechLevel(tech), c.ShipGroup(sgi).TechLevel(tech), limitLevel)
|
targetLevel[tech] = game.FutureUpgradeLevel(c.g.Race[ri].TechLevel(tech), c.ShipGroup(sgi).TechLevel(tech).F(), limitLevel)
|
||||||
} else {
|
} else {
|
||||||
targetLevel[tech] = game.CurrentUpgradingLevel(c.g.ShipGroups[sgi], tech)
|
targetLevel[tech] = game.CurrentUpgradingLevel(c.g.ShipGroups[sgi], tech)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ type ShipGroup struct {
|
|||||||
Number uint `json:"number"` // Number (quantity) ships of specific ShipType
|
Number uint `json:"number"` // Number (quantity) ships of specific ShipType
|
||||||
|
|
||||||
CargoType *CargoType `json:"loadType,omitempty"`
|
CargoType *CargoType `json:"loadType,omitempty"`
|
||||||
Load float64 `json:"load"` // Cargo loaded - "Масса груза"
|
Load Float `json:"load"` // Cargo loaded - "Масса груза"
|
||||||
|
|
||||||
Tech TechSet `json:"tech"`
|
Tech TechSet `json:"tech"`
|
||||||
|
|
||||||
@@ -117,8 +117,8 @@ type ShipGroup struct {
|
|||||||
StateUpgrade *InUpgrade `json:"stateUpgrade,omitempty"`
|
StateUpgrade *InUpgrade `json:"stateUpgrade,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sg ShipGroup) TechLevel(t Tech) float64 {
|
func (sg ShipGroup) TechLevel(t Tech) Float {
|
||||||
return sg.Tech.Value(t)
|
return F(sg.Tech.Value(t))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: refactor to separate method with *ShipGroup as parameter
|
// TODO: refactor to separate method with *ShipGroup as parameter
|
||||||
@@ -170,19 +170,19 @@ 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/float64(sg.Number) == other.Load/float64(other.Number) &&
|
sg.Load.F()/float64(sg.Number) == other.Load.F()/float64(other.Number) &&
|
||||||
sg.State() == other.State()
|
sg.State() == other.State()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Грузоподъёмность
|
// Грузоподъёмность
|
||||||
func (sg ShipGroup) CargoCapacity(st *ShipType) float64 {
|
func (sg ShipGroup) CargoCapacity(st *ShipType) float64 {
|
||||||
return sg.TechLevel(TechCargo) * (st.Cargo + (st.Cargo*st.Cargo)/20) * float64(sg.Number)
|
return sg.TechLevel(TechCargo).F() * (st.Cargo + (st.Cargo*st.Cargo)/20) * float64(sg.Number)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Масса перевозимого груза -
|
// Масса перевозимого груза -
|
||||||
// общее количество единиц груза, деленное на технологический уровень Грузоперевозок
|
// общее количество единиц груза, деленное на технологический уровень Грузоперевозок
|
||||||
func (sg ShipGroup) CarryingMass() float64 {
|
func (sg ShipGroup) CarryingMass() float64 {
|
||||||
return sg.Load / sg.TechLevel(TechCargo)
|
return sg.Load.F() / sg.TechLevel(TechCargo).F()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Масса группы без учёта груза
|
// Масса группы без учёта груза
|
||||||
@@ -199,7 +199,7 @@ func (sg ShipGroup) FullMass(st *ShipType) float64 {
|
|||||||
// Эффективность двигателя -
|
// Эффективность двигателя -
|
||||||
// равна мощности Двигателей, умноженной на технологический уровень блока Двигателей
|
// равна мощности Двигателей, умноженной на технологический уровень блока Двигателей
|
||||||
func (sg ShipGroup) DriveEffective(st *ShipType) float64 {
|
func (sg ShipGroup) DriveEffective(st *ShipType) float64 {
|
||||||
return st.Drive * sg.TechLevel(TechDrive)
|
return st.Drive * sg.TechLevel(TechDrive).F()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Корабли перемещаются за один ход на количество световых лет, равное
|
// Корабли перемещаются за один ход на количество световых лет, равное
|
||||||
@@ -209,27 +209,27 @@ func (sg ShipGroup) Speed(st *ShipType) float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sg ShipGroup) UpgradeDriveCost(st *ShipType, drive float64) float64 {
|
func (sg ShipGroup) UpgradeDriveCost(st *ShipType, drive float64) float64 {
|
||||||
return (1 - sg.TechLevel(TechDrive)/drive) * 10 * st.Drive
|
return (1 - sg.TechLevel(TechDrive).F()/drive) * 10 * st.Drive
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: test on other values
|
// TODO: test on other values
|
||||||
func (sg ShipGroup) UpgradeWeaponsCost(st *ShipType, weapons float64) float64 {
|
func (sg ShipGroup) UpgradeWeaponsCost(st *ShipType, weapons float64) float64 {
|
||||||
return (1 - sg.TechLevel(TechWeapons)/weapons) * 10 * st.WeaponsBlockMass()
|
return (1 - sg.TechLevel(TechWeapons).F()/weapons) * 10 * st.WeaponsBlockMass()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sg ShipGroup) UpgradeShieldsCost(st *ShipType, shields float64) float64 {
|
func (sg ShipGroup) UpgradeShieldsCost(st *ShipType, shields float64) float64 {
|
||||||
return (1 - sg.TechLevel(TechShields)/shields) * 10 * st.Shields
|
return (1 - sg.TechLevel(TechShields).F()/shields) * 10 * st.Shields
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sg ShipGroup) UpgradeCargoCost(st *ShipType, cargo float64) float64 {
|
func (sg ShipGroup) UpgradeCargoCost(st *ShipType, cargo float64) float64 {
|
||||||
return (1 - sg.TechLevel(TechCargo)/cargo) * 10 * st.Cargo
|
return (1 - sg.TechLevel(TechCargo).F()/cargo) * 10 * st.Cargo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Мощность бомбардировки
|
// Мощность бомбардировки
|
||||||
func (sg ShipGroup) BombingPower(st *ShipType) float64 {
|
func (sg ShipGroup) BombingPower(st *ShipType) float64 {
|
||||||
return (math.Sqrt(st.Weapons*sg.TechLevel(TechWeapons))/10. + 1.) *
|
return (math.Sqrt(st.Weapons*sg.TechLevel(TechWeapons).F())/10. + 1.) *
|
||||||
st.Weapons *
|
st.Weapons *
|
||||||
sg.TechLevel(TechWeapons) *
|
sg.TechLevel(TechWeapons).F() *
|
||||||
float64(st.Armament) *
|
float64(st.Armament) *
|
||||||
float64(sg.Number)
|
float64(sg.Number)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -228,22 +228,22 @@ func TestShipGroupEqual(t *testing.T) {
|
|||||||
|
|
||||||
right = *left
|
right = *left
|
||||||
left.SetTechLevel(game.TechDrive, 1.1)
|
left.SetTechLevel(game.TechDrive, 1.1)
|
||||||
assert.Equal(t, 1.1, left.TechLevel(game.TechDrive))
|
assert.Equal(t, 1.1, left.TechLevel(game.TechDrive).F())
|
||||||
assert.False(t, left.Equal(right))
|
assert.False(t, left.Equal(right))
|
||||||
|
|
||||||
right = *left
|
right = *left
|
||||||
left.SetTechLevel(game.TechWeapons, 1.1)
|
left.SetTechLevel(game.TechWeapons, 1.1)
|
||||||
assert.Equal(t, 1.1, left.TechLevel(game.TechWeapons))
|
assert.Equal(t, 1.1, left.TechLevel(game.TechWeapons).F())
|
||||||
assert.False(t, left.Equal(right))
|
assert.False(t, left.Equal(right))
|
||||||
|
|
||||||
right = *left
|
right = *left
|
||||||
left.SetTechLevel(game.TechShields, 1.1)
|
left.SetTechLevel(game.TechShields, 1.1)
|
||||||
assert.Equal(t, 1.1, left.TechLevel(game.TechShields))
|
assert.Equal(t, 1.1, left.TechLevel(game.TechShields).F())
|
||||||
assert.False(t, left.Equal(right))
|
assert.False(t, left.Equal(right))
|
||||||
|
|
||||||
right = *left
|
right = *left
|
||||||
left.SetTechLevel(game.TechCargo, 1.1)
|
left.SetTechLevel(game.TechCargo, 1.1)
|
||||||
assert.Equal(t, 1.1, left.TechLevel(game.TechCargo))
|
assert.Equal(t, 1.1, left.TechLevel(game.TechCargo).F())
|
||||||
assert.False(t, left.Equal(right))
|
assert.False(t, left.Equal(right))
|
||||||
|
|
||||||
// non-essential properties
|
// non-essential properties
|
||||||
@@ -254,6 +254,6 @@ func TestShipGroupEqual(t *testing.T) {
|
|||||||
|
|
||||||
// dirty hack to equalize loads
|
// dirty hack to equalize loads
|
||||||
left.Number = 5
|
left.Number = 5
|
||||||
left.Load = right.Load / float64(right.Number) * float64(left.Number)
|
left.Load = game.F(right.Load.F() / float64(right.Number) * float64(left.Number))
|
||||||
assert.True(t, left.Equal(right))
|
assert.True(t, left.Equal(right))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,16 +32,16 @@ func BlockUpgradeCost(blockMass, currentBlockTech, targetBlockTech float64) floa
|
|||||||
func GroupUpgradeCost(sg ShipGroup, st ShipType, drive, weapons, shields, cargo float64) UpgradeCalc {
|
func GroupUpgradeCost(sg ShipGroup, st ShipType, drive, weapons, shields, cargo float64) UpgradeCalc {
|
||||||
uc := &UpgradeCalc{Cost: make(map[Tech]float64)}
|
uc := &UpgradeCalc{Cost: make(map[Tech]float64)}
|
||||||
if drive > 0 {
|
if drive > 0 {
|
||||||
uc.Cost[TechDrive] = BlockUpgradeCost(st.DriveBlockMass(), sg.TechLevel(TechDrive), drive)
|
uc.Cost[TechDrive] = BlockUpgradeCost(st.DriveBlockMass(), sg.TechLevel(TechDrive).F(), drive)
|
||||||
}
|
}
|
||||||
if weapons > 0 {
|
if weapons > 0 {
|
||||||
uc.Cost[TechWeapons] = BlockUpgradeCost(st.WeaponsBlockMass(), sg.TechLevel(TechWeapons), weapons)
|
uc.Cost[TechWeapons] = BlockUpgradeCost(st.WeaponsBlockMass(), sg.TechLevel(TechWeapons).F(), weapons)
|
||||||
}
|
}
|
||||||
if shields > 0 {
|
if shields > 0 {
|
||||||
uc.Cost[TechShields] = BlockUpgradeCost(st.ShieldsBlockMass(), sg.TechLevel(TechShields), shields)
|
uc.Cost[TechShields] = BlockUpgradeCost(st.ShieldsBlockMass(), sg.TechLevel(TechShields).F(), shields)
|
||||||
}
|
}
|
||||||
if cargo > 0 {
|
if cargo > 0 {
|
||||||
uc.Cost[TechCargo] = BlockUpgradeCost(st.CargoBlockMass(), sg.TechLevel(TechCargo), cargo)
|
uc.Cost[TechCargo] = BlockUpgradeCost(st.CargoBlockMass(), sg.TechLevel(TechCargo).F(), cargo)
|
||||||
}
|
}
|
||||||
return *uc
|
return *uc
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ func FutureUpgradeLevel(raceLevel, groupLevel, limit float64) float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func UpgradeGroupPreference(sg ShipGroup, st ShipType, tech Tech, v float64) ShipGroup {
|
func UpgradeGroupPreference(sg ShipGroup, st ShipType, tech Tech, v float64) ShipGroup {
|
||||||
if v <= 0 || st.BlockMass(tech) == 0 || sg.TechLevel(tech) >= v {
|
if v <= 0 || st.BlockMass(tech) == 0 || sg.TechLevel(tech).F() >= v {
|
||||||
return sg
|
return sg
|
||||||
}
|
}
|
||||||
var su InUpgrade
|
var su InUpgrade
|
||||||
@@ -84,7 +84,7 @@ func UpgradeGroupPreference(sg ShipGroup, st ShipType, tech Tech, v float64) Shi
|
|||||||
ti = len(su.UpgradeTech) - 1
|
ti = len(su.UpgradeTech) - 1
|
||||||
}
|
}
|
||||||
su.UpgradeTech[ti].Level = v
|
su.UpgradeTech[ti].Level = v
|
||||||
su.UpgradeTech[ti].Cost = BlockUpgradeCost(st.BlockMass(tech), sg.TechLevel(tech), v) * float64(sg.Number)
|
su.UpgradeTech[ti].Cost = BlockUpgradeCost(st.BlockMass(tech), sg.TechLevel(tech).F(), v) * float64(sg.Number)
|
||||||
|
|
||||||
sg.StateUpgrade = &su
|
sg.StateUpgrade = &su
|
||||||
return sg
|
return sg
|
||||||
|
|||||||
@@ -7,25 +7,25 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type UnidentifiedPlanet struct {
|
type UnidentifiedPlanet struct {
|
||||||
X float64 `json:"x"`
|
X Float `json:"x"`
|
||||||
Y float64 `json:"y"`
|
Y Float `json:"y"`
|
||||||
Number uint `json:"number"`
|
Number uint `json:"number"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UninhabitedPlanet struct {
|
type UninhabitedPlanet struct {
|
||||||
UnidentifiedPlanet
|
UnidentifiedPlanet
|
||||||
Size float64 `json:"size"`
|
Size Float `json:"size"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Resources float64 `json:"resources"` // R - Ресурсы
|
Resources Float `json:"resources"` // R - Ресурсы
|
||||||
Capital float64 `json:"capital"` // CAP $ - Запасы промышленности
|
Capital Float `json:"capital"` // CAP $ - Запасы промышленности
|
||||||
Material float64 `json:"material"` // MAT M - Запасы ресурсов / сырьё
|
Material Float `json:"material"` // MAT M - Запасы ресурсов / сырьё
|
||||||
}
|
}
|
||||||
|
|
||||||
type PlanetReport struct {
|
type PlanetReport struct {
|
||||||
UninhabitedPlanet
|
UninhabitedPlanet
|
||||||
Industry float64 `json:"industry"` // I - Промышленность
|
Industry Float `json:"industry"` // I - Промышленность
|
||||||
Population float64 `json:"population"` // P - Население
|
Population Float `json:"population"` // P - Население
|
||||||
Colonists float64 `json:"colonists"` // COL C - Количество колонистов
|
Colonists Float `json:"colonists"` // COL C - Количество колонистов
|
||||||
Production Production `json:"production"` // TODO: internal/report format
|
Production Production `json:"production"` // TODO: internal/report format
|
||||||
// Параметр "L" - Свободный производственный потенциал
|
// Параметр "L" - Свободный производственный потенциал
|
||||||
}
|
}
|
||||||
@@ -41,13 +41,33 @@ type PlanetReportForeign struct {
|
|||||||
PlanetReport
|
PlanetReport
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Planet) Mat(v float64) {
|
||||||
|
p.Material = F(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Planet) Pop(v float64) {
|
||||||
|
p.Population = F(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Planet) Col(v float64) {
|
||||||
|
p.Colonists = F(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Planet) Ind(v float64) {
|
||||||
|
p.Industry = F(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Planet) Cap(v float64) {
|
||||||
|
p.Capital = F(v)
|
||||||
|
}
|
||||||
|
|
||||||
func (p Planet) Votes() float64 {
|
func (p Planet) Votes() float64 {
|
||||||
return p.Population / 1000.
|
return p.Population.F() / 1000.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Производственный потенциал
|
// Производственный потенциал
|
||||||
func (p Planet) ProductionCapacity() float64 {
|
func (p Planet) ProductionCapacity() float64 {
|
||||||
return PlanetProduction(p.Industry, p.Population)
|
return PlanetProduction(p.Industry.F(), p.Population.F())
|
||||||
}
|
}
|
||||||
|
|
||||||
func PlanetProduction(industry, population float64) float64 {
|
func PlanetProduction(industry, population float64) float64 {
|
||||||
@@ -64,12 +84,12 @@ func (p *Planet) ProduceIndustry() {
|
|||||||
production := p.ProductionCapacity()
|
production := p.ProductionCapacity()
|
||||||
var ind float64
|
var ind float64
|
||||||
if p.Material > 0 {
|
if p.Material > 0 {
|
||||||
ind = math.Min(production/5, p.Material)
|
ind = math.Min(production/5, p.Material.F())
|
||||||
p.Material -= ind
|
p.Mat(p.Material.F() - ind)
|
||||||
production -= ind * 5.
|
production -= ind * 5.
|
||||||
}
|
}
|
||||||
ind += (production * p.Resources) / (5.*p.Resources + 1.)
|
ind += (production * p.Resources.F()) / (5.*p.Resources.F() + 1.)
|
||||||
p.Industry += ind
|
p.Ind(p.Industry.F() + ind)
|
||||||
if p.Industry > p.Population {
|
if p.Industry > p.Population {
|
||||||
p.Capital += p.Industry - p.Population
|
p.Capital += p.Industry - p.Population
|
||||||
p.Industry = p.Population
|
p.Industry = p.Population
|
||||||
@@ -78,7 +98,7 @@ func (p *Planet) ProduceIndustry() {
|
|||||||
|
|
||||||
// Производство материалов
|
// Производство материалов
|
||||||
func (p *Planet) ProduceMaterial() {
|
func (p *Planet) ProduceMaterial() {
|
||||||
p.Material += p.ProductionCapacity() * p.Resources
|
p.Material = p.Material.Add(p.ProductionCapacity() * p.Resources.F())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Автоматическое увеличение населения на каждом ходу
|
// Автоматическое увеличение населения на каждом ходу
|
||||||
@@ -115,10 +135,10 @@ func (p *Planet) UnpackColonists() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func UnloadColonists(p Planet, v float64) Planet {
|
func UnloadColonists(p Planet, v float64) Planet {
|
||||||
p.Population += v * 8
|
p.Pop(p.Population.F() + v*8)
|
||||||
if p.Population > p.Size {
|
if p.Population > p.Size {
|
||||||
p.Colonists += (p.Population - p.Size) / 8
|
p.Col(p.Colonists.F() + (p.Population.F()-p.Size.F())/8.)
|
||||||
p.Population = p.Size
|
p.Pop(p.Size.F())
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,24 +36,24 @@ func TestProduceIndustry(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
HW.ProduceIndustry()
|
HW.ProduceIndustry()
|
||||||
assert.InDelta(t, 196.078, HW.Capital, 0.0005)
|
assert.InDelta(t, 196.078, HW.Capital.F(), 0.0005)
|
||||||
|
|
||||||
HW.Capital = 0
|
HW.Capital = 0
|
||||||
HW.Material = 200
|
HW.Material = 200
|
||||||
|
|
||||||
HW.ProduceIndustry()
|
HW.ProduceIndustry()
|
||||||
assert.Equal(t, 200., HW.Capital)
|
assert.Equal(t, 200., HW.Capital.F())
|
||||||
assert.Equal(t, 0., HW.Material)
|
assert.Equal(t, 0., HW.Material.F())
|
||||||
|
|
||||||
DW.ProduceIndustry()
|
DW.ProduceIndustry()
|
||||||
assert.InDelta(t, 98.039, DW.Capital, 0.0003)
|
assert.InDelta(t, 98.039, DW.Capital.F(), 0.0003)
|
||||||
|
|
||||||
DW.Capital = 0
|
DW.Capital = 0
|
||||||
DW.Material = 100
|
DW.Material = 100
|
||||||
|
|
||||||
DW.ProduceIndustry()
|
DW.ProduceIndustry()
|
||||||
assert.Equal(t, 100., DW.Capital)
|
assert.Equal(t, 100., DW.Capital.F())
|
||||||
assert.Equal(t, 0., DW.Material)
|
assert.Equal(t, 0., DW.Material.F())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestProduceMaterial(t *testing.T) {
|
func TestProduceMaterial(t *testing.T) {
|
||||||
@@ -67,19 +67,19 @@ func TestProduceMaterial(t *testing.T) {
|
|||||||
Industry: 1000,
|
Industry: 1000,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
assert.Equal(t, 0., HW.Material)
|
assert.Equal(t, 0., HW.Material.F())
|
||||||
|
|
||||||
HW.ProduceMaterial()
|
HW.ProduceMaterial()
|
||||||
assert.Equal(t, 10000., HW.Material)
|
assert.Equal(t, 10000., HW.Material.F())
|
||||||
|
|
||||||
HW.Industry = 500
|
HW.Industry = 500
|
||||||
HW.Population = 500
|
HW.Population = 500
|
||||||
HW.ProduceMaterial()
|
HW.ProduceMaterial()
|
||||||
assert.Equal(t, 15000., HW.Material)
|
assert.Equal(t, 15000., HW.Material.F())
|
||||||
|
|
||||||
HW.Population = 1000
|
HW.Population = 1000
|
||||||
HW.ProduceMaterial()
|
HW.ProduceMaterial()
|
||||||
assert.Equal(t, 21250., HW.Material)
|
assert.Equal(t, 21250., HW.Material.F())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnpackCapital(t *testing.T) {
|
func TestUnpackCapital(t *testing.T) {
|
||||||
@@ -93,28 +93,28 @@ func TestUnpackCapital(t *testing.T) {
|
|||||||
Industry: 1000,
|
Industry: 1000,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
assert.Equal(t, 0., HW.Capital)
|
assert.Equal(t, 0., HW.Capital.F())
|
||||||
|
|
||||||
HW.UnpackCapital()
|
HW.UnpackCapital()
|
||||||
assert.Equal(t, 1000., HW.Industry)
|
assert.Equal(t, 1000., HW.Industry.F())
|
||||||
assert.Equal(t, 0., HW.Capital)
|
assert.Equal(t, 0., HW.Capital.F())
|
||||||
|
|
||||||
HW.Capital = 123.
|
HW.Capital = 123.
|
||||||
HW.UnpackCapital()
|
HW.UnpackCapital()
|
||||||
assert.Equal(t, 1000., HW.Industry)
|
assert.Equal(t, 1000., HW.Industry.F())
|
||||||
assert.Equal(t, 123., HW.Capital)
|
assert.Equal(t, 123., HW.Capital.F())
|
||||||
|
|
||||||
HW.Industry = 987.
|
HW.Industry = 987.
|
||||||
HW.UnpackCapital()
|
HW.UnpackCapital()
|
||||||
assert.Equal(t, 1000., HW.Industry)
|
assert.Equal(t, 1000., HW.Industry.F())
|
||||||
assert.Equal(t, 110., HW.Capital)
|
assert.Equal(t, 110., HW.Capital.F())
|
||||||
|
|
||||||
HW.Population = 876.
|
HW.Population = 876.
|
||||||
HW.Industry = 800.
|
HW.Industry = 800.
|
||||||
HW.UnpackCapital()
|
HW.UnpackCapital()
|
||||||
assert.Equal(t, 876., HW.Population)
|
assert.Equal(t, 876., HW.Population.F())
|
||||||
assert.Equal(t, 876., HW.Industry)
|
assert.Equal(t, 876., HW.Industry.F())
|
||||||
assert.Equal(t, 34., HW.Capital)
|
assert.Equal(t, 34., HW.Capital.F())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnpackColonists(t *testing.T) {
|
func TestUnpackColonists(t *testing.T) {
|
||||||
@@ -128,26 +128,26 @@ func TestUnpackColonists(t *testing.T) {
|
|||||||
Industry: 1000,
|
Industry: 1000,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
assert.Equal(t, 0., HW.Colonists)
|
assert.Equal(t, 0., HW.Colonists.F())
|
||||||
|
|
||||||
HW.UnpackColonists()
|
HW.UnpackColonists()
|
||||||
assert.Equal(t, 1000., HW.Population)
|
assert.Equal(t, 1000., HW.Population.F())
|
||||||
assert.Equal(t, 0., HW.Colonists)
|
assert.Equal(t, 0., HW.Colonists.F())
|
||||||
|
|
||||||
HW.Colonists = 1.05
|
HW.Colonists = 1.05
|
||||||
HW.UnpackColonists()
|
HW.UnpackColonists()
|
||||||
assert.Equal(t, 1000., HW.Population)
|
assert.Equal(t, 1000., HW.Population.F())
|
||||||
assert.Equal(t, 1.05, HW.Colonists)
|
assert.Equal(t, 1.05, HW.Colonists.F())
|
||||||
|
|
||||||
HW.Population = 996.0
|
HW.Population = 996.0
|
||||||
HW.UnpackColonists()
|
HW.UnpackColonists()
|
||||||
assert.Equal(t, 1000., HW.Population)
|
assert.Equal(t, 1000., HW.Population.F())
|
||||||
assert.Equal(t, 0.55, HW.Colonists)
|
assert.Equal(t, 0.55, HW.Colonists.F())
|
||||||
|
|
||||||
HW.Population = 0.0
|
HW.Population = 0.0
|
||||||
HW.UnpackColonists()
|
HW.UnpackColonists()
|
||||||
assert.Equal(t, 4.4, HW.Population)
|
assert.Equal(t, 4.4, HW.Population.F())
|
||||||
assert.Equal(t, 0., HW.Colonists)
|
assert.Equal(t, 0., HW.Colonists.F())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestProducePopulation(t *testing.T) {
|
func TestProducePopulation(t *testing.T) {
|
||||||
@@ -161,15 +161,15 @@ func TestProducePopulation(t *testing.T) {
|
|||||||
Industry: 1000,
|
Industry: 1000,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
assert.Equal(t, 500., HW.Population)
|
assert.Equal(t, 500., HW.Population.F())
|
||||||
assert.Equal(t, 0., HW.Colonists)
|
assert.Equal(t, 0., HW.Colonists.F())
|
||||||
|
|
||||||
HW.ProducePopulation()
|
HW.ProducePopulation()
|
||||||
assert.Equal(t, 540., HW.Population)
|
assert.Equal(t, 540., HW.Population.F())
|
||||||
assert.Equal(t, 0., HW.Colonists)
|
assert.Equal(t, 0., HW.Colonists.F())
|
||||||
|
|
||||||
HW.Population = 1000.
|
HW.Population = 1000.
|
||||||
HW.ProducePopulation()
|
HW.ProducePopulation()
|
||||||
assert.Equal(t, 1000., HW.Population)
|
assert.Equal(t, 1000., HW.Population.F())
|
||||||
assert.Equal(t, 10., HW.Colonists)
|
assert.Equal(t, 10., HW.Colonists.F())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ type BattleReportGroup struct {
|
|||||||
NumberLeft uint `json:"numLeft"`
|
NumberLeft uint `json:"numLeft"`
|
||||||
ClassName string `json:"className"`
|
ClassName string `json:"className"`
|
||||||
LoadType string `json:"loadType"`
|
LoadType string `json:"loadType"`
|
||||||
LoadQuantity float64 `json:"loadQuantity"`
|
LoadQuantity Float `json:"loadQuantity"`
|
||||||
Drive float64 `json:"drive"`
|
Drive Float `json:"drive"`
|
||||||
Weapons float64 `json:"wwapons"`
|
Weapons Float `json:"wwapons"`
|
||||||
Shields float64 `json:"shields"`
|
Shields Float `json:"shields"`
|
||||||
Cargo float64 `json:"cargo"`
|
Cargo Float `json:"cargo"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type BattleActionReport struct {
|
type BattleActionReport struct {
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ type BombingPlanetReport struct {
|
|||||||
Owner string `json:"owner"`
|
Owner string `json:"owner"`
|
||||||
Attacker string `json:"attacker"`
|
Attacker string `json:"attacker"`
|
||||||
Production string `json:"production"`
|
Production string `json:"production"`
|
||||||
Industry float64 `json:"industry"` // I - Промышленность
|
Industry Float `json:"industry"` // I - Промышленность
|
||||||
Population float64 `json:"population"` // P - Население
|
Population Float `json:"population"` // P - Население
|
||||||
Colonists float64 `json:"colonists"` // COL C - Количество колонистов
|
Colonists Float `json:"colonists"` // COL C - Количество колонистов
|
||||||
Capital float64 `json:"capital"` // CAP $ - Запасы промышленности
|
Capital Float `json:"capital"` // CAP $ - Запасы промышленности
|
||||||
Material float64 `json:"material"` // MAT M - Запасы ресурсов / сырья
|
Material Float `json:"material"` // MAT M - Запасы ресурсов / сырья
|
||||||
AttackPower float64 `json:"attack"`
|
AttackPower Float `json:"attack"`
|
||||||
Wiped bool `json:"wiped"`
|
Wiped bool `json:"wiped"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,18 +38,9 @@ func saveTurn(s Storage, t uint, g *game.Game) error {
|
|||||||
if err := s.Write(path, g); err != nil {
|
if err := s.Write(path, g); err != nil {
|
||||||
return NewStorageError(err)
|
return NewStorageError(err)
|
||||||
}
|
}
|
||||||
// TODO: save reports
|
|
||||||
for i := range g.Race {
|
|
||||||
saveRace(s, g, i)
|
|
||||||
}
|
|
||||||
// TODO: save battles
|
|
||||||
return saveState(s, g) // FIXME: either save it here, or in tre repo controller
|
return saveState(s, g) // FIXME: either save it here, or in tre repo controller
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveRace(s Storage, g *game.Game, i int) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *repo) SaveState(g *game.Game) error {
|
func (r *repo) SaveState(g *game.Game) error {
|
||||||
return saveState(r.s, g)
|
return saveState(r.s, g)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user