game generation process
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
@@ -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])
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user