game generation process
This commit is contained in:
+74
-31
@@ -3,6 +3,7 @@ package game
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"math/rand/v2"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/iliadenisov/galaxy/pkg/generator"
|
"github.com/iliadenisov/galaxy/pkg/generator"
|
||||||
@@ -15,9 +16,9 @@ type Repo interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewGame(r Repo, races []string) (uuid.UUID, error) {
|
func NewGame(r Repo, races []string) (uuid.UUID, error) {
|
||||||
id, err := uuid.NewRandom()
|
gameID, err := uuid.NewRandom()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return uuid.Nil, fmt.Errorf("generate uuid: %s", err)
|
return uuid.Nil, fmt.Errorf("generate game uuid: %s", err)
|
||||||
}
|
}
|
||||||
m, err := generator.Generate(func(ms *generator.MapSetting) {
|
m, err := generator.Generate(func(ms *generator.MapSetting) {
|
||||||
ms.Players = uint32(len(races))
|
ms.Players = uint32(len(races))
|
||||||
@@ -29,7 +30,7 @@ func NewGame(r Repo, races []string) (uuid.UUID, error) {
|
|||||||
return uuid.Nil, fmt.Errorf("generate map: wrong number of home planets: %d, expected: %d ", len(m.HomePlanets), len(races))
|
return uuid.Nil, fmt.Errorf("generate map: wrong number of home planets: %d, expected: %d ", len(m.HomePlanets), len(races))
|
||||||
}
|
}
|
||||||
g := &game.Game{
|
g := &game.Game{
|
||||||
ID: id,
|
ID: gameID,
|
||||||
Race: make([]game.Race, len(races)),
|
Race: make([]game.Race, len(races)),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,44 +39,71 @@ func NewGame(r Repo, races []string) (uuid.UUID, error) {
|
|||||||
Height: m.Height,
|
Height: m.Height,
|
||||||
Planet: make([]game.Planet, 0),
|
Planet: make([]game.Planet, 0),
|
||||||
}
|
}
|
||||||
for hw := range races {
|
var planetCount uint = 0
|
||||||
g.Race[hw] = game.Race{
|
for i := range races {
|
||||||
Name: races[hw],
|
raceID, err := uuid.NewRandom()
|
||||||
Votes: 1, // TODO: check with rules
|
if err != nil {
|
||||||
VoteFor: races[hw],
|
return uuid.Nil, fmt.Errorf("generate race uuid: %s", err)
|
||||||
|
}
|
||||||
|
g.Race[i] = game.Race{
|
||||||
|
ID: raceID,
|
||||||
|
Name: races[i],
|
||||||
|
Ally: raceID,
|
||||||
Drive: 1,
|
Drive: 1,
|
||||||
Weapons: 1,
|
Weapons: 1,
|
||||||
Shields: 1,
|
Shields: 1,
|
||||||
Cargo: 1,
|
Cargo: 1,
|
||||||
}
|
}
|
||||||
gameMap.Planet = append(gameMap.Planet, game.Planet{
|
gameMap.Planet = append(gameMap.Planet, newPlanet(
|
||||||
Owner: races[hw],
|
planetCount,
|
||||||
X: m.HomePlanets[hw].HW.Position.X,
|
m.HomePlanets[i].HW.RandomName(),
|
||||||
Y: m.HomePlanets[hw].HW.Position.Y,
|
raceID,
|
||||||
Size: m.HomePlanets[hw].HW.Size,
|
m.HomePlanets[i].HW.Position.X,
|
||||||
Resources: m.HomePlanets[hw].HW.Resources,
|
m.HomePlanets[i].HW.Position.Y,
|
||||||
Production: game.ProductionCapital.AsType(""), // TODO: check default production
|
m.HomePlanets[i].HW.Size,
|
||||||
})
|
m.HomePlanets[i].HW.Size, // HW's pop & ind = size
|
||||||
for dw := range m.HomePlanets[hw].DW {
|
m.HomePlanets[i].HW.Size,
|
||||||
gameMap.Planet = append(gameMap.Planet, game.Planet{
|
m.HomePlanets[i].HW.Resources,
|
||||||
X: m.HomePlanets[hw].DW[dw].Position.X,
|
game.ResearchDrive.AsType(""),
|
||||||
Y: m.HomePlanets[hw].DW[dw].Position.Y,
|
))
|
||||||
Size: m.HomePlanets[hw].DW[dw].Size,
|
planetCount++
|
||||||
Resources: m.HomePlanets[hw].DW[dw].Resources,
|
for dw := range m.HomePlanets[i].DW {
|
||||||
Production: game.ProductionNone.AsType(""),
|
gameMap.Planet = append(gameMap.Planet, newPlanet(
|
||||||
})
|
planetCount,
|
||||||
|
m.HomePlanets[i].DW[dw].RandomName(),
|
||||||
|
raceID,
|
||||||
|
m.HomePlanets[i].DW[dw].Position.X,
|
||||||
|
m.HomePlanets[i].DW[dw].Position.Y,
|
||||||
|
m.HomePlanets[i].DW[dw].Size,
|
||||||
|
m.HomePlanets[i].DW[dw].Size, // DW's pop & ind = size
|
||||||
|
m.HomePlanets[i].DW[dw].Size,
|
||||||
|
m.HomePlanets[i].DW[dw].Resources,
|
||||||
|
game.ResearchDrive.AsType(""),
|
||||||
|
))
|
||||||
|
planetCount++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := range m.FreePlanets {
|
for i := range m.FreePlanets {
|
||||||
gameMap.Planet = append(gameMap.Planet, game.Planet{
|
gameMap.Planet = append(gameMap.Planet, newPlanet(
|
||||||
X: m.FreePlanets[i].Position.X,
|
planetCount,
|
||||||
Y: m.FreePlanets[i].Position.Y,
|
m.FreePlanets[i].RandomName(),
|
||||||
Size: m.FreePlanets[i].Size,
|
uuid.Nil,
|
||||||
Resources: m.FreePlanets[i].Resources,
|
m.FreePlanets[i].Position.X,
|
||||||
Production: game.ProductionNone.AsType(""),
|
m.FreePlanets[i].Position.Y,
|
||||||
})
|
m.FreePlanets[i].Size,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
m.FreePlanets[i].Resources,
|
||||||
|
game.ProductionNone.AsType(""),
|
||||||
|
))
|
||||||
|
planetCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: check code below actually works
|
||||||
|
rand.Shuffle(len(gameMap.Planet), func(i, j int) {
|
||||||
|
gameMap.Planet[i].Number, gameMap.Planet[j].Number = gameMap.Planet[j].Number, gameMap.Planet[i].Number
|
||||||
|
})
|
||||||
|
|
||||||
g.Map = *gameMap
|
g.Map = *gameMap
|
||||||
|
|
||||||
if err := r.Persist(*g); err != nil {
|
if err := r.Persist(*g); err != nil {
|
||||||
@@ -84,6 +112,21 @@ func NewGame(r Repo, races []string) (uuid.UUID, error) {
|
|||||||
return g.ID, nil
|
return g.ID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newPlanet(num uint, name string, owner uuid.UUID, x, y, size, pop, ind, res float64, prod game.ProductionType) game.Planet {
|
||||||
|
return game.Planet{
|
||||||
|
Name: name,
|
||||||
|
Number: num,
|
||||||
|
Owner: owner,
|
||||||
|
X: x,
|
||||||
|
Y: y,
|
||||||
|
Size: size,
|
||||||
|
Population: pop,
|
||||||
|
Industry: ind,
|
||||||
|
Resources: res,
|
||||||
|
Production: prod,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (r Race) FlightDistance() float64 {
|
func (r Race) FlightDistance() float64 {
|
||||||
return r.Drive * 40
|
return r.Drive * 40
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func Generate(cfg ...func(*MapSetting)) (Map, error) {
|
|||||||
freePlanets := ms.NobodysPlanets()
|
freePlanets := ms.NobodysPlanets()
|
||||||
|
|
||||||
createPlanets := func(pc PlanetClass, ps PlanetSetting) error {
|
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
|
// 1. Place Giant planets
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ func TestGenerator(t *testing.T) {
|
|||||||
t.Fatalf("generate: %s", err)
|
t.Fatalf("generate: %s", err)
|
||||||
return
|
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 {
|
for hw := range m.HomePlanets {
|
||||||
assert.Equal(t, s.HWSize, m.HomePlanets[hw].HW.Size, "hw #%d: size", hw)
|
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, 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 {
|
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.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)
|
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)
|
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)
|
freePlanetCount := make(map[generator.PlanetClass]int)
|
||||||
for fp := range m.FreePlanets {
|
for fp := range m.FreePlanets {
|
||||||
ps := planetSettings(t, m.FreePlanets[fp].PlanetClass, s)
|
ps := planetSettings(t, m.FreePlanets[fp].PlanetClass, s)
|
||||||
@@ -67,8 +68,8 @@ func TestGenerator(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for pc, num := range freePlanetCount {
|
for pc, num := range freePlanetCount {
|
||||||
ps := planetSettings(t, pc, s)
|
ps := planetSettings(t, pc, s)
|
||||||
maxNum := ps.MaxCount(s.NobodysPlanets())
|
maxNum := ps.Number(s.NobodysPlanets())
|
||||||
assert.LessOrEqualf(t, num, maxNum, "planet_class=%v probability=%f of total %d", pc, ps.Probability, 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
|
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) {
|
func NewMap(width, height, players uint32) (*Map, error) {
|
||||||
p, err := plotter.NewPlotter(width, height, defaultFactor)
|
p, err := plotter.NewPlotter(width, height, defaultFactor)
|
||||||
if err != nil {
|
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))
|
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
|
// RandI returns a random float64 value between min and max
|
||||||
func RandI(min, max float64) float64 {
|
func RandI(min, max float64) float64 {
|
||||||
return min + rand.Float64()*(max-min)
|
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 {
|
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)
|
return uint32(math.Sqrt(float64(ms.Players)) * float64(ms.HWMinDistance) * 1.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,11 +48,12 @@ type PlanetSetting struct {
|
|||||||
MaxSize float64
|
MaxSize float64
|
||||||
MinResource float64
|
MinResource float64
|
||||||
MaxResource 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 {
|
// Number of planets need to be placed within freePlanets amount
|
||||||
return int(math.Ceil(float64(freePlanets) * ps.Probability))
|
func (ps PlanetSetting) Number(freePlanets uint32) int {
|
||||||
|
return int(math.Ceil(float64(freePlanets) * ps.Ratio))
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultMapSetting() MapSetting {
|
func DefaultMapSetting() MapSetting {
|
||||||
@@ -73,7 +73,7 @@ func DefaultMapSetting() MapSetting {
|
|||||||
MaxSize: 2500,
|
MaxSize: 2500,
|
||||||
MinResource: 0,
|
MinResource: 0,
|
||||||
MaxResource: 3,
|
MaxResource: 3,
|
||||||
Probability: 0.06,
|
Ratio: 0.06,
|
||||||
},
|
},
|
||||||
BigPlanets: PlanetSetting{
|
BigPlanets: PlanetSetting{
|
||||||
MinDistanceHW: 10,
|
MinDistanceHW: 10,
|
||||||
@@ -81,7 +81,7 @@ func DefaultMapSetting() MapSetting {
|
|||||||
MaxSize: 2000,
|
MaxSize: 2000,
|
||||||
MinResource: 1,
|
MinResource: 1,
|
||||||
MaxResource: 10,
|
MaxResource: 10,
|
||||||
Probability: 0.18,
|
Ratio: 0.18,
|
||||||
},
|
},
|
||||||
OthersMinDistance: defaultFactor, // min. is 1 pixel on the plotter
|
OthersMinDistance: defaultFactor, // min. is 1 pixel on the plotter
|
||||||
NormalPlanets: PlanetSetting{
|
NormalPlanets: PlanetSetting{
|
||||||
@@ -90,7 +90,7 @@ func DefaultMapSetting() MapSetting {
|
|||||||
MaxSize: 1000,
|
MaxSize: 1000,
|
||||||
MinResource: 0,
|
MinResource: 0,
|
||||||
MaxResource: 10,
|
MaxResource: 10,
|
||||||
Probability: 0.5,
|
Ratio: 0.5,
|
||||||
},
|
},
|
||||||
RichPlanets: PlanetSetting{
|
RichPlanets: PlanetSetting{
|
||||||
MinDistanceHW: 0,
|
MinDistanceHW: 0,
|
||||||
@@ -98,7 +98,7 @@ func DefaultMapSetting() MapSetting {
|
|||||||
MaxSize: 500,
|
MaxSize: 500,
|
||||||
MinResource: 5,
|
MinResource: 5,
|
||||||
MaxResource: 25,
|
MaxResource: 25,
|
||||||
Probability: 0.18,
|
Ratio: 0.18,
|
||||||
},
|
},
|
||||||
Asterioids: PlanetSetting{
|
Asterioids: PlanetSetting{
|
||||||
MinDistanceHW: 0,
|
MinDistanceHW: 0,
|
||||||
@@ -106,7 +106,7 @@ func DefaultMapSetting() MapSetting {
|
|||||||
MaxSize: 0,
|
MaxSize: 0,
|
||||||
MinResource: 0,
|
MinResource: 0,
|
||||||
MaxResource: 0,
|
MaxResource: 0,
|
||||||
Probability: 0.08,
|
Ratio: 0.08,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,18 @@ import "github.com/google/uuid"
|
|||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
ID uuid.UUID
|
ID uuid.UUID
|
||||||
|
Age uint // Game's turn number
|
||||||
Map Map
|
Map Map
|
||||||
Race []Race
|
Race []Race
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g Game) Votes(raceID uuid.UUID) float64 {
|
||||||
|
// XXX: calculate [Race]Population once when loading Game from Storage?
|
||||||
|
var pop float64
|
||||||
|
for i := range g.Map.Planet {
|
||||||
|
if g.Map.Planet[i].Owner == raceID {
|
||||||
|
pop += g.Map.Planet[i].Population
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pop / 1000.
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,5 @@ package game
|
|||||||
type Map struct {
|
type Map struct {
|
||||||
Width uint32
|
Width uint32
|
||||||
Height uint32
|
Height uint32
|
||||||
|
|
||||||
Planet []Planet
|
Planet []Planet
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,33 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
import "math"
|
import (
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
type Planet struct {
|
type Planet struct {
|
||||||
X, Y float64
|
X, Y float64
|
||||||
Size float64
|
Size float64
|
||||||
|
|
||||||
Name string
|
Name string
|
||||||
Owner string
|
Number uint
|
||||||
|
Owner uuid.UUID
|
||||||
|
|
||||||
Production ProductionType
|
Production ProductionType
|
||||||
Resources float64 // Сырьё
|
Population float64 // P - Население
|
||||||
Industry float64 // Промышленность
|
Industry float64 // I - Промышленность
|
||||||
Population float64 // Население
|
Resources float64 // R - Ресурсы / сырьё
|
||||||
|
|
||||||
Capital float64 // CAP $ - Запасы промышленности
|
Capital float64 // CAP $ - Запасы промышленности
|
||||||
Material float64 // MAT M - Запасы сырья
|
Material float64 // MAT M - Запасы ресурсов / сырья
|
||||||
Colonists float64 // COL C - Количество колонистов
|
Colonists float64 // COL C - Количество колонистов
|
||||||
// Параметр "L" означает количество свободных производственных единиц.
|
// Параметр "L" - Свободный производственный потенциал
|
||||||
}
|
}
|
||||||
|
|
||||||
// Производственный потенциал (I)
|
// Свободный производственный потенциал (L)
|
||||||
// промышленность * 0.75 + население * 0.25
|
// промышленность * 0.75 + население * 0.25
|
||||||
|
// TODO: за вычетом затрат, расходуемых в течение хода на модернизацию кораблей
|
||||||
func (p Planet) ProductionCapacity() float64 {
|
func (p Planet) ProductionCapacity() float64 {
|
||||||
return p.Industry*0.75 + p.Population*0.25
|
return p.Industry*0.75 + p.Population*0.25
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,26 +3,27 @@ package game
|
|||||||
type PlanetProduction string
|
type PlanetProduction string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ProductionNone PlanetProduction = "NONE"
|
ProductionNone PlanetProduction = "-"
|
||||||
ProductionMaterial PlanetProduction = "MAT"
|
ProductionMaterial PlanetProduction = "MAT" // Сырьё
|
||||||
ProductionCapital PlanetProduction = "CAP"
|
ProductionCapital PlanetProduction = "CAP" // Промышленность
|
||||||
ProductionDrive PlanetProduction = "DRIVE"
|
|
||||||
ProductionWeapons PlanetProduction = "WEAPONS"
|
|
||||||
ProductionShields PlanetProduction = "SHIELDS"
|
|
||||||
ProductionCargo PlanetProduction = "CARGO"
|
|
||||||
|
|
||||||
ProductionScience PlanetProduction = "SCIENCE"
|
ResearchDrive PlanetProduction = "DRIVE"
|
||||||
ProductionShip PlanetProduction = "SHIP"
|
ResearchWeapons PlanetProduction = "WEAPONS"
|
||||||
|
ResearchShields PlanetProduction = "SHIELDS"
|
||||||
|
ResearchCargo PlanetProduction = "CARGO"
|
||||||
|
|
||||||
|
ResearchScience PlanetProduction = "SCIENCE"
|
||||||
|
ProductionShip PlanetProduction = "SHIP"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ProductionType struct {
|
type ProductionType struct {
|
||||||
Production PlanetProduction
|
Production PlanetProduction
|
||||||
SubjectName string
|
SubjectName string // TODO: change to UUID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p PlanetProduction) AsType(subject string) ProductionType {
|
func (p PlanetProduction) AsType(subject string) ProductionType {
|
||||||
switch p {
|
switch p {
|
||||||
case ProductionScience, ProductionShip:
|
case ResearchScience, ProductionShip:
|
||||||
return ProductionType{Production: p, SubjectName: subject}
|
return ProductionType{Production: p, SubjectName: subject}
|
||||||
default:
|
default:
|
||||||
return ProductionType{Production: p}
|
return ProductionType{Production: p}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
|
import "github.com/google/uuid"
|
||||||
|
|
||||||
type Race struct {
|
type Race struct {
|
||||||
|
ID uuid.UUID
|
||||||
Name string
|
Name string
|
||||||
Killed bool
|
Killed bool
|
||||||
|
|
||||||
Votes float64
|
// Votes float64
|
||||||
VoteFor string
|
Ally uuid.UUID // Race's Votes receiver
|
||||||
|
|
||||||
Drive float64
|
Drive float64
|
||||||
Weapons float64
|
Weapons float64
|
||||||
|
|||||||
Reference in New Issue
Block a user