diff --git a/pkg/game/game.go b/pkg/game/game.go index 7bc4b22..c14ba3e 100644 --- a/pkg/game/game.go +++ b/pkg/game/game.go @@ -7,6 +7,7 @@ import ( "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 { @@ -198,7 +199,7 @@ func (sg ShipGroup) BombingPower() float64 { sg.Weapons * float64(sg.Type.Armament) * float64(sg.Number) - return toFixed3(result) + return number.Fixed3(result) } // TODO: test this @@ -211,17 +212,3 @@ func (fl Fleet) Speed() float64 { } return result } - -func round(num float64) int { - return int(num + math.Copysign(0.5, num)) -} - -// TODO: move to more common place -func toFixed(num float64, precision int) float64 { - output := math.Pow(10, float64(precision)) - return float64(round(num*output)) / output -} - -func toFixed3(num float64) float64 { - return toFixed(num, 3) -} diff --git a/pkg/generator/generator.go b/pkg/generator/generator.go index d2079c8..faf56c5 100644 --- a/pkg/generator/generator.go +++ b/pkg/generator/generator.go @@ -37,18 +37,18 @@ func Generate(cfg ...func(*MapSetting)) (Map, error) { // 3. Place players' Home Worlds for player := 0; player < int(ms.Players); player++ { - coord, err := m.NewCoordinate(float64(ms.HWMinDistance)) + hwCoord, err := m.NewCoordinate(float64(ms.HWMinDistance)) if err != nil { return Map{}, fmt.Errorf("%s: hw new_coordinate: %s", ms, err) } - planet := NewPlanet(coord, float64(ms.HWSize), float64(ms.HWResources)) - m.HomePlanets[player] = PlanetarySystem{HW: planet, DW: make([]Planet, ms.DWCount)} + hwPlanet := NewPlanet(hwCoord, float64(ms.HWSize), float64(ms.HWResources)) + m.HomePlanets[player] = PlanetarySystem{HW: hwPlanet, DW: make([]Planet, ms.DWCount)} for dw := 0; dw < int(ms.DWCount); dw++ { p := rand.Float64()*(float64(ms.DWMaxDistance)-float64(ms.DWMinDistance)) + float64(ms.DWMinDistance) phi := rand.Float64() * 360 x := p * math.Cos(phi) y := p * math.Sin(phi) - dwPlanet := NewPlanet(Coordinate{x, y}, float64(ms.DWSize), float64(ms.DWResources)) + dwPlanet := NewPlanet(Coordinate{hwCoord.X + x, hwCoord.Y + y}, float64(ms.DWSize), float64(ms.DWResources)) m.HomePlanets[player].DW[dw] = dwPlanet } } diff --git a/pkg/generator/generator_test.go b/pkg/generator/generator_test.go index d318300..df1ef8f 100644 --- a/pkg/generator/generator_test.go +++ b/pkg/generator/generator_test.go @@ -22,6 +22,13 @@ func TestGenerator(t *testing.T) { assert.Equal(t, players, len(m.HomePlanets), "hw count") for i := range m.HomePlanets { assert.Equal(t, int(s.DWCount), len(m.HomePlanets[i].DW), "hw #%d: dw count", i) + for dw := range m.HomePlanets[i].DW { + d := m.ShortDistance(m.HomePlanets[i].HW.Position, m.HomePlanets[i].DW[dw].Position) + assert.LessOrEqualf(t, float64(s.DWMinDistance), d, "HW[%.04f,%04f] - DW[%.04f,%04f]", + m.HomePlanets[i].HW.Position.X, m.HomePlanets[i].HW.Position.Y, m.HomePlanets[i].DW[dw].Position.X, m.HomePlanets[i].DW[dw].Position.Y) + assert.GreaterOrEqualf(t, float64(s.DWMaxDistance), d, "HW[%.04f,%04f] - DW[%.04f,%04f]", + m.HomePlanets[i].HW.Position.X, m.HomePlanets[i].HW.Position.Y, m.HomePlanets[i].DW[dw].Position.X, m.HomePlanets[i].DW[dw].Position.Y) + } } } } diff --git a/pkg/generator/map.go b/pkg/generator/map.go index e128a32..16abd02 100644 --- a/pkg/generator/map.go +++ b/pkg/generator/map.go @@ -2,6 +2,7 @@ package generator import ( "fmt" + "math" "math/rand" "github.com/iliadenisov/galaxy/pkg/generator/plotter" @@ -67,6 +68,18 @@ func (m Map) NewCoordinate(deadZoneRaduis float64) (Coordinate, error) { } } +func (m Map) ShortDistance(from, to Coordinate) float64 { + dx := math.Abs(to.X - from.X) + dy := math.Abs(to.Y - from.Y) + if dx > float64(m.Width/2) { + dx = float64(m.Width) - dx + } + if dy > float64(m.Height/2) { + dy = float64(m.Height) - dy + } + return math.Sqrt(math.Pow(dx, 2) + math.Pow(dy, 2)) +} + func NewPlanet(c Coordinate, size, resources float64) Planet { return Planet{ Position: c, diff --git a/pkg/generator/map_test.go b/pkg/generator/map_test.go new file mode 100644 index 0000000..dd8c054 --- /dev/null +++ b/pkg/generator/map_test.go @@ -0,0 +1,27 @@ +package generator + +import ( + "fmt" + "testing" + + "github.com/iliadenisov/galaxy/pkg/number" + "github.com/stretchr/testify/assert" +) + +func TestShortDistance(t *testing.T) { + for i, tc := range []struct { + w, h uint32 + x1, y1, x2, y2, d float64 + }{ + {10, 10, 0, 0, 5, 5, 7.071}, + {10, 10, 0, 0, 5.01, 5.01, 7.057}, + {10, 10, 2, 2, 8, 2, 4.}, + {10, 10, 8, 7, 1, 7, 3.}, + } { + t.Run(fmt.Sprint(i), func(t *testing.T) { + m := Map{Width: tc.w, Height: tc.h} + d := m.ShortDistance(Coordinate{tc.x1, tc.y1}, Coordinate{tc.x2, tc.y2}) + assert.Equal(t, tc.d, number.Fixed3(d)) + }) + } +} diff --git a/pkg/model/game/ship.go b/pkg/model/game/ship.go index b7d7b0c..d21968d 100644 --- a/pkg/model/game/ship.go +++ b/pkg/model/game/ship.go @@ -1,6 +1,10 @@ package game -import "math" +import ( + "math" + + "github.com/iliadenisov/galaxy/pkg/number" +) type Ship struct { TypeName string @@ -103,7 +107,7 @@ func (sg ShipGroup) BombingPower() float64 { sg.Weapons * float64(sg.Type.Armament) * float64(sg.Number) - return toFixed3(result) + return number.Fixed3(result) } // TODO: test this @@ -116,17 +120,3 @@ func (fl Fleet) Speed() float64 { } return result } - -func toFixed3(num float64) float64 { - return toFixed(num, 3) -} - -// TODO: move to more common place -func toFixed(num float64, precision int) float64 { - output := math.Pow(10, float64(precision)) - return float64(round(num*output)) / output -} - -func round(num float64) int { - return int(num + math.Copysign(0.5, num)) -} diff --git a/pkg/number/number.go b/pkg/number/number.go new file mode 100644 index 0000000..51d5308 --- /dev/null +++ b/pkg/number/number.go @@ -0,0 +1,16 @@ +package number + +import "math" + +func Fixed3(num float64) float64 { + return fixed(num, 3) +} + +func fixed(num float64, precision int) float64 { + output := math.Pow(10, float64(precision)) + return float64(round(num*output)) / output +} + +func round(num float64) int { + return int(num + math.Copysign(0.5, num)) +}