game generation process

This commit is contained in:
Ilia Denisov
2025-09-25 02:13:16 +03:00
parent 99035fd95d
commit 46066d890b
12 changed files with 206 additions and 101 deletions
+1 -1
View File
@@ -22,7 +22,7 @@ func Generate(cfg ...func(*MapSetting)) (Map, error) {
freePlanets := ms.NobodysPlanets()
createPlanets := func(pc PlanetClass, ps PlanetSetting) error {
return m.CreatePlanets(pc, rand.Intn(ps.MaxCount(freePlanets))+1, float64(ps.MinDistanceHW), RandIFn(ps.MinSize, ps.MaxSize), RandIFn(ps.MinResource, ps.MaxResource))
return m.CreatePlanets(pc, ps.Number(freePlanets), float64(ps.MinDistanceHW), RandIFn(ps.MinSize, ps.MaxSize), RandIFn(ps.MinResource, ps.MaxResource))
}
// 1. Place Giant planets
+5 -4
View File
@@ -21,11 +21,11 @@ func TestGenerator(t *testing.T) {
t.Fatalf("generate: %s", err)
return
}
assert.Equal(t, players, len(m.HomePlanets), "hw count")
assert.Equal(t, players, len(m.HomePlanets), "hw-s count")
for hw := range m.HomePlanets {
assert.Equal(t, s.HWSize, m.HomePlanets[hw].HW.Size, "hw #%d: size", hw)
assert.Equal(t, s.HWResources, m.HomePlanets[hw].HW.Resources, "hw #%d: resources", hw)
assert.Equal(t, int(s.DWCount), len(m.HomePlanets[hw].DW), "hw #%d: dw count", hw)
assert.Equal(t, int(s.DWCount), len(m.HomePlanets[hw].DW), "hw #%d: dw-s count", hw)
for dw := range m.HomePlanets[hw].DW {
assert.Equal(t, s.DWSize, m.HomePlanets[hw].DW[dw].Size, "hw #%d dw #%d: size", hw, dw)
assert.Equal(t, s.DWResources, m.HomePlanets[hw].DW[dw].Resources, "hw #%d dw #%d: resources", hw, dw)
@@ -38,6 +38,7 @@ func TestGenerator(t *testing.T) {
m.HomePlanets[hw].DW[dw].Position.X, m.HomePlanets[hw].DW[dw].Position.Y)
}
}
assert.LessOrEqualf(t, int(s.NobodysPlanets()), len(m.FreePlanets), "free planets clount")
freePlanetCount := make(map[generator.PlanetClass]int)
for fp := range m.FreePlanets {
ps := planetSettings(t, m.FreePlanets[fp].PlanetClass, s)
@@ -67,8 +68,8 @@ func TestGenerator(t *testing.T) {
}
for pc, num := range freePlanetCount {
ps := planetSettings(t, pc, s)
maxNum := ps.MaxCount(s.NobodysPlanets())
assert.LessOrEqualf(t, num, maxNum, "planet_class=%v probability=%f of total %d", pc, ps.Probability, s.NobodysPlanets())
maxNum := ps.Number(s.NobodysPlanets())
assert.Equalf(t, num, maxNum, "planet_class=%v ratio=%f of total %d", pc, ps.Ratio, s.NobodysPlanets())
}
})
}
-33
View File
@@ -20,30 +20,6 @@ type Coordinate struct {
X, Y float64
}
type PlanetClass int
const (
PlanetClassHW PlanetClass = iota
PlanetClassDW
PlanetClassGiant
PlanetClassBig
PlanetClassNormal
PlanetClassRich
PlanetClassAsterioid
)
type Planet struct {
PlanetClass PlanetClass
Position Coordinate
Size float64
Resources float64 // Сырьё
}
type PlanetarySystem struct {
HW Planet
DW []Planet
}
func NewMap(width, height, players uint32) (*Map, error) {
p, err := plotter.NewPlotter(width, height, defaultFactor)
if err != nil {
@@ -93,15 +69,6 @@ func (m Map) ShortDistance(from, to Coordinate) float64 {
return math.Sqrt(math.Pow(dx, 2) + math.Pow(dy, 2))
}
func NewPlanet(pc PlanetClass, c Coordinate, size, resources float64) Planet {
return Planet{
PlanetClass: pc,
Position: c,
Size: size,
Resources: resources,
}
}
// RandI returns a random float64 value between min and max
func RandI(min, max float64) float64 {
return min + rand.Float64()*(max-min)
+43
View File
@@ -0,0 +1,43 @@
package generator
import (
"fmt"
"math/rand"
)
type PlanetClass string
const (
PlanetClassHW PlanetClass = "HW"
PlanetClassDW PlanetClass = "DW"
PlanetClassGiant PlanetClass = "Giant"
PlanetClassBig PlanetClass = "Big"
PlanetClassNormal PlanetClass = "Normal"
PlanetClassRich PlanetClass = "Rich"
PlanetClassAsterioid PlanetClass = "Asteroid"
)
type Planet struct {
PlanetClass PlanetClass
Position Coordinate
Size float64
Resources float64 // Сырьё
}
type PlanetarySystem struct {
HW Planet
DW []Planet
}
func (p Planet) RandomName() string {
return fmt.Sprintf("%s-%04d-%04d", p.PlanetClass, rand.Intn(1000), rand.Intn(1000))
}
func NewPlanet(pc PlanetClass, c Coordinate, size, resources float64) Planet {
return Planet{
PlanetClass: pc,
Position: c,
Size: size,
Resources: resources,
}
}
+30
View File
@@ -0,0 +1,30 @@
package generator_test
import (
"regexp"
"testing"
g "github.com/iliadenisov/galaxy/pkg/generator"
"github.com/stretchr/testify/assert"
)
func TestPlanetRandomName(t *testing.T) {
re, err := regexp.Compile(`^([a-zA-Z]+)-(\d{4})-(\d{4})$`)
assert.NoError(t, err)
if err != nil {
return
}
for _, pc := range []g.PlanetClass{g.PlanetClassHW, g.PlanetClassDW, g.PlanetClassGiant, g.PlanetClassBig, g.PlanetClassNormal, g.PlanetClassRich, g.PlanetClassAsterioid} {
t.Run(string(pc), func(t *testing.T) {
name := g.NewPlanet(pc, g.Coordinate{0, 0}, 0, 0).RandomName()
g := re.FindStringSubmatch(name)
assert.NotNilf(t, g, "cannot parse: %q", name)
if g == nil {
return
}
assert.Equalf(t, 4, len(g), "regexp groups")
assert.Equal(t, string(pc), g[1])
assert.NotEqual(t, g[2], g[3])
})
}
}
+9 -9
View File
@@ -31,7 +31,6 @@ func (ms MapSetting) String() string {
}
func (ms MapSetting) ExpectedSize() uint32 {
// 1.5 coefficient is enough if all free planet probability will be 1.0
return uint32(math.Sqrt(float64(ms.Players)) * float64(ms.HWMinDistance) * 1.5)
}
@@ -49,11 +48,12 @@ type PlanetSetting struct {
MaxSize float64
MinResource float64
MaxResource float64
Probability float64
Ratio float64 // The proportion of the total number of free planets in the galaxy
}
func (ps PlanetSetting) MaxCount(freePlanets uint32) int {
return int(math.Ceil(float64(freePlanets) * ps.Probability))
// Number of planets need to be placed within freePlanets amount
func (ps PlanetSetting) Number(freePlanets uint32) int {
return int(math.Ceil(float64(freePlanets) * ps.Ratio))
}
func DefaultMapSetting() MapSetting {
@@ -73,7 +73,7 @@ func DefaultMapSetting() MapSetting {
MaxSize: 2500,
MinResource: 0,
MaxResource: 3,
Probability: 0.06,
Ratio: 0.06,
},
BigPlanets: PlanetSetting{
MinDistanceHW: 10,
@@ -81,7 +81,7 @@ func DefaultMapSetting() MapSetting {
MaxSize: 2000,
MinResource: 1,
MaxResource: 10,
Probability: 0.18,
Ratio: 0.18,
},
OthersMinDistance: defaultFactor, // min. is 1 pixel on the plotter
NormalPlanets: PlanetSetting{
@@ -90,7 +90,7 @@ func DefaultMapSetting() MapSetting {
MaxSize: 1000,
MinResource: 0,
MaxResource: 10,
Probability: 0.5,
Ratio: 0.5,
},
RichPlanets: PlanetSetting{
MinDistanceHW: 0,
@@ -98,7 +98,7 @@ func DefaultMapSetting() MapSetting {
MaxSize: 500,
MinResource: 5,
MaxResource: 25,
Probability: 0.18,
Ratio: 0.18,
},
Asterioids: PlanetSetting{
MinDistanceHW: 0,
@@ -106,7 +106,7 @@ func DefaultMapSetting() MapSetting {
MaxSize: 0,
MinResource: 0,
MaxResource: 0,
Probability: 0.08,
Ratio: 0.08,
},
}
}