diff --git a/pkg/game/game.go b/pkg/game/game.go index fed7ace..9277578 100644 --- a/pkg/game/game.go +++ b/pkg/game/game.go @@ -2,13 +2,11 @@ package game import ( "fmt" - "math" "math/rand/v2" "github.com/google/uuid" "github.com/iliadenisov/galaxy/pkg/generator" "github.com/iliadenisov/galaxy/pkg/model/game" - "github.com/iliadenisov/galaxy/pkg/number" ) type Repo interface { @@ -126,132 +124,3 @@ func newPlanet(num uint, name string, owner uuid.UUID, x, y, size, pop, ind, res Production: prod, } } - -func (r Race) FlightDistance() float64 { - return r.Drive * 40 -} - -func (r Race) VisibilityDistance() float64 { - return r.Drive * 30 -} - -// Производственный потенциал (I) -// промышленность * 0.75 + население * 0.25 -func (p Planet) ProductionCapacity() float64 { - return p.Industry*0.75 + p.Population*0.25 -} - -// Производство промышленности -// TODO: test on real values -func (p *Planet) IncreaseIndustry() { - prod := p.ProductionCapacity() / 5 - industryIncrement := math.Min(prod, p.Material) - p.Industry += industryIncrement - if p.Industry > p.Population { - p.Industry = p.Population - p.Capital += p.Population - p.Industry - } -} - -// Производство материалов -// TODO: test on real values -func (p *Planet) IncreaseMaterial() { - p.Material += p.ProductionCapacity() * p.Industry -} - -// Автоматическое увеличение населения на каждом ходу -func (p *Planet) IncreasePopulation() { - p.Population *= 1.08 - var extraPopulation = p.Size - p.Population - if extraPopulation > 0 { - p.Colonists += extraPopulation / 8 - p.Population -= extraPopulation - } -} - -// TODO: test on real values -func (st ShipType) EmptyMass() float64 { - shipMass := st.DriveMass() + st.ShieldsMass() + st.CargoMass() + st.WeaponsMass() - return shipMass -} - -func (st ShipType) DriveMass() float64 { - return st.Drive -} - -func (st ShipType) ShieldsMass() float64 { - return st.Shields -} - -func (st ShipType) CargoMass() float64 { - return st.Cargo -} - -func (st ShipType) WeaponsMass() float64 { - return float64(st.Armament)*(st.Weapons/2) + st.Weapons/2 -} - -// Грузоподъёмность -func (sg ShipGroup) CargoCapacity() float64 { - return sg.Drive * (sg.Type.Cargo + (sg.Type.Cargo*sg.Type.Cargo)/20) -} - -// "Масса перевозимого груза" -func (sg ShipGroup) CarryingMass() float64 { - return sg.Load / sg.Cargo -} - -func (sg ShipGroup) FullMass() float64 { - return sg.Type.EmptyMass() + sg.CarryingMass() -} - -// "Эффективность двигателя" -// равна мощности Двигателей умноженной на текущий технологический уровень блока Двигателей -func (sg ShipGroup) DriveEffective() float64 { - return sg.Type.Drive * sg.Drive -} - -// TODO: test this -func (sg ShipGroup) Speed() float64 { - return sg.DriveEffective() * 20 / sg.FullMass() -} - -func (sg ShipGroup) UpgradeDriveCost(drive float64) float64 { - return (1 - sg.Drive/drive) * 10 * sg.Type.Drive -} - -// TODO: test on other values -func (sg ShipGroup) UpgradeWeaponsCost(weapons float64) float64 { - return (1 - sg.Weapons/weapons) * 10 * sg.Type.WeaponsMass() -} - -func (sg ShipGroup) UpgradeShieldsCost(shields float64) float64 { - return (1 - sg.Shields/shields) * 10 * sg.Type.Shields -} - -func (sg ShipGroup) UpgradeCargoCost(cargo float64) float64 { - return (1 - sg.Cargo/cargo) * 10 * sg.Type.Cargo -} - -// Мощность бомбардировки -// TODO: maybe rounding must be done only for display? -func (sg ShipGroup) BombingPower() float64 { - // return math.Sqrt(sg.Type.Weapons * sg.Weapons) - result := (math.Sqrt(sg.Type.Weapons*sg.Weapons)/10. + 1.) * - sg.Type.Weapons * - sg.Weapons * - float64(sg.Type.Armament) * - float64(sg.Number) - return number.Fixed3(result) -} - -// TODO: test this -func (fl Fleet) Speed() float64 { - result := math.MaxFloat64 - for _, sg := range fl.ShipGroups { - if sg.Speed() < result { - result = sg.Speed() - } - } - return result -} diff --git a/pkg/game/game_data.go b/pkg/game/game_data.go deleted file mode 100644 index f479861..0000000 --- a/pkg/game/game_data.go +++ /dev/null @@ -1,100 +0,0 @@ -package game - -type GameIdentifier string -type RaceIdentifier string - -type Game struct { - Id GameIdentifier - Name string - Schedule string // TODO: implement somehow - Turn uint - Races []Race - Planets []Planet - WarState map[RaceIdentifier]RaceIdentifier -} - -type Race struct { - Id RaceIdentifier - Name string - Drive float64 - Weapons float64 - Shields float64 - Cargo float64 -} - -type PlanetProduction string - -const ( - ProductionMaterial PlanetProduction = "MAT" - ProductionCapital PlanetProduction = "CAP" - ProductionDrive PlanetProduction = "DRIVE" - ProductionWeapons PlanetProduction = "WEAPONS" - ProductionShields PlanetProduction = "SHIELDS" - ProductionCargo PlanetProduction = "CARGO" - - ProductionScience PlanetProduction = "SCIENCE" - ProductionShip PlanetProduction = "SHIP" -) - -type ProductionType struct { - Production PlanetProduction - SubjectName string -} - -type Planet struct { - Number uint - Name string - Position Coordinate - Size float64 - - Owner RaceIdentifier - Production ProductionType - Resources float64 // Сырьё - Industry float64 // Промышленность - Population float64 // Население - - Capital float64 // CAP $ - Запасы промышленности - Material float64 // MAT M - Запасы сырья - Colonists float64 // COL C - Количество колонистов - // Параметр "L" означает количество свободных производственных единиц. -} - -func (p *Planet) setOwner(id RaceIdentifier) { - p.Owner = id -} - -type Coordinate struct { - X, Y float64 -} - -type Science struct { - Name string - Drive float64 - Weapons float64 - Shields float64 - Cargo float64 -} - -type ShipType struct { - Name string - Drive float64 // [0], [1...] - Armament uint - Weapons float64 // [0], [1...] - Shields float64 // [0], [1...] - Cargo float64 // [0], [1...] -} - -type ShipGroup struct { - Type ShipType - Number uint - State string // TODO: kinda enum: In_Orbit, In_Space, Transfer_State, Upgrade - Load float64 // Cargo loaded - "Масса груза" - Drive float64 - Weapons float64 - Shields float64 - Cargo float64 -} - -type Fleet struct { - ShipGroups []ShipGroup -} diff --git a/pkg/game/game_init.go b/pkg/game/game_init.go deleted file mode 100644 index 4fe55ad..0000000 --- a/pkg/game/game_init.go +++ /dev/null @@ -1,39 +0,0 @@ -package game - -func CreateGame(id GameIdentifier, name string, races []Race, planets []Planet) Game { - return Game{ - Id: id, - Name: name, - Turn: 0, - Races: races, - Planets: planets, - } -} - -func CreateRace(id RaceIdentifier, name string) Race { - return Race{ - Id: id, - Name: name, - Drive: 1.0, - Weapons: 1.0, - Shields: 1.0, - Cargo: 1.0, - } -} - -func CreatePlanet(number uint, name string, position Coordinate, size float64, res float64, pop float64) Planet { - return Planet{ - Number: number, - Name: name, - Position: position, - Size: size, - Production: ProductionType{ProductionDrive, ""}, - Resources: res, - Population: pop, - - Industry: 0, - Capital: 0, - Material: 0, - Colonists: 0, - } -} diff --git a/pkg/game/game_test.go b/pkg/game/game_test.go index 18e5df1..d9b310e 100644 --- a/pkg/game/game_test.go +++ b/pkg/game/game_test.go @@ -3,7 +3,8 @@ package game_test import ( "testing" - "github.com/iliadenisov/galaxy/pkg/game" + "github.com/iliadenisov/galaxy/pkg/model/game" + "github.com/stretchr/testify/assert" ) func Test_ShipType(t *testing.T) { @@ -14,10 +15,7 @@ func Test_ShipType(t *testing.T) { Shields: 4, Cargo: 0, } - - if Gunship.EmptyMass() != 11. { - t.Errorf("Cruiser mass expected %.3f but %.3f given", 11., Gunship.EmptyMass()) - } + assert.Equal(t, Gunship.EmptyMass(), 11.) Cruiser := game.ShipType{ Drive: 15, @@ -26,10 +24,7 @@ func Test_ShipType(t *testing.T) { Shields: 15, Cargo: 0, } - - if Cruiser.EmptyMass() != 45. { - t.Errorf("Cruiser mass expected %.3f but %.3f given", 45., Cruiser.EmptyMass()) - } + assert.Equal(t, Cruiser.EmptyMass(), 45.) sg := game.ShipGroup{ Type: Cruiser, @@ -40,15 +35,11 @@ func Test_ShipType(t *testing.T) { Shields: 1.0, Cargo: 1.0, } - upgradeCost := sg.UpgradeDriveCost(2.0) + sg.UpgradeWeaponsCost(2.0) + sg.UpgradeShieldsCost(2.0) + sg.UpgradeCargoCost(2.0) - - if upgradeCost != 225. { - t.Errorf("Cruiser upgrade cost expected %.3f but %.3f given", 225., upgradeCost) - } + assert.Equal(t, upgradeCost, 225.) } func Test_CargoCapacity(t *testing.T) { @@ -69,9 +60,7 @@ func Test_CargoCapacity(t *testing.T) { Shields: 1.0, Cargo: 1.0, } - if sg.CargoCapacity() != expectCapacity { - t.Errorf("expected CargoCapacity=%.3f but %.3f given", expectCapacity, sg.CargoCapacity()) - } + assert.Equal(t, expectCapacity, sg.CargoCapacity()) } test(1, 1.05) test(5, 6.25) @@ -99,7 +88,5 @@ func Test_BombingPower(t *testing.T) { } expectedBombingPower := 139.295 result := sg.BombingPower() - if result != expectedBombingPower { - t.Errorf("expected BombingPower=%.3f but %.3f given", expectedBombingPower, result) - } + assert.Equal(t, expectedBombingPower, result) } diff --git a/pkg/model/game/science.go b/pkg/model/game/science.go new file mode 100644 index 0000000..1fc821c --- /dev/null +++ b/pkg/model/game/science.go @@ -0,0 +1,9 @@ +package game + +type Science struct { + Name string + Drive float64 + Weapons float64 + Shields float64 + Cargo float64 +} diff --git a/pkg/game/game_parameter.go b/pkg/model/game/settings.go similarity index 100% rename from pkg/game/game_parameter.go rename to pkg/model/game/settings.go diff --git a/pkg/model/game/ship.go b/pkg/model/game/ship.go index d21968d..e7db4de 100644 --- a/pkg/model/game/ship.go +++ b/pkg/model/game/ship.go @@ -6,10 +6,6 @@ import ( "github.com/iliadenisov/galaxy/pkg/number" ) -type Ship struct { - TypeName string -} - type ShipType struct { Name string Drive float64 // [0], [1...] diff --git a/pkg/number/number_test.go b/pkg/number/number_test.go new file mode 100644 index 0000000..f14a6c2 --- /dev/null +++ b/pkg/number/number_test.go @@ -0,0 +1,33 @@ +package number + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFixed(t *testing.T) { + for _, tc := range []struct { + precision int + source, expected float64 + }{ + {3, 0, 0}, + {3, -1, -1}, + {3, 1.5, 1.5}, + {3, 2.25, 2.25}, + {3, 3.275, 3.275}, + {3, 4.0004, 4.000}, + {5, 5.000005, 5.00001}, + {4, -6.00004, -6.}, + {4, -6.00005, -6.0001}, + } { + t.Run(fmt.Sprintf("%f", tc.source), func(t *testing.T) { + if tc.precision == 3 { + assert.Equal(t, tc.expected, Fixed3(tc.source)) + } else { + assert.Equal(t, tc.expected, fixed(tc.source, tc.precision)) + } + }) + } +}