mirror of
https://github.com/arnaucube/gogame.git
synced 2026-02-06 19:16:40 +01:00
add calc.go Growths in time, Mines costs. Applied to game
This commit is contained in:
@@ -1,65 +1,12 @@
|
||||
package constants
|
||||
|
||||
import (
|
||||
"github.com/arnaucube/gogame/models"
|
||||
)
|
||||
|
||||
// game constants
|
||||
|
||||
const GALAXYSIZE = 50
|
||||
const SOLARSYSTEMSIZE = 15
|
||||
|
||||
// MetalMineLevels contains the constants of productivity for each level, sorted from 0 to X levels
|
||||
var MetalMineLevels = []int64{
|
||||
0,
|
||||
1,
|
||||
5,
|
||||
10,
|
||||
// TODO this will be same strategy with all the buildings and research
|
||||
}
|
||||
var CrystalMineLevels = []int64{
|
||||
0,
|
||||
1,
|
||||
5,
|
||||
10,
|
||||
}
|
||||
var DeuteriumMineLevels = []int64{
|
||||
0,
|
||||
1,
|
||||
5,
|
||||
10,
|
||||
}
|
||||
var EnergyMineLevels = []int64{
|
||||
0,
|
||||
1,
|
||||
5,
|
||||
10,
|
||||
}
|
||||
|
||||
// BuildingsNeededResources hold
|
||||
// map with all the buildings, that each one is a map with the levels of the buildings with the needed ressources
|
||||
var BuildingsNeededResources = map[string]map[int64]models.Resources{
|
||||
"metalplant": map[int64]models.Resources{
|
||||
1: models.Resources{
|
||||
Metal: 50,
|
||||
Crystal: 50,
|
||||
Deuterium: 50,
|
||||
Energy: 50,
|
||||
},
|
||||
2: models.Resources{
|
||||
Metal: 70,
|
||||
Crystal: 70,
|
||||
Deuterium: 70,
|
||||
Energy: 70,
|
||||
},
|
||||
3: models.Resources{
|
||||
Metal: 90,
|
||||
Crystal: 90,
|
||||
Deuterium: 90,
|
||||
Energy: 90,
|
||||
},
|
||||
},
|
||||
}
|
||||
const UniverseAcceleration = 1
|
||||
const MineVelocity = 1
|
||||
|
||||
// extra
|
||||
const JWTIdKey = "id"
|
||||
|
||||
@@ -73,15 +73,15 @@ func handleGetUser(c *gin.Context) {
|
||||
fail(c, err, "error on getting user")
|
||||
return
|
||||
}
|
||||
resources, err := user.GetResources()
|
||||
if err != nil {
|
||||
fail(c, err, "error on getting user resources")
|
||||
return
|
||||
}
|
||||
// resources, err := user.GetResources()
|
||||
// if err != nil {
|
||||
// fail(c, err, "error on getting user resources")
|
||||
// return
|
||||
// }
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"user": user,
|
||||
"resources": resources,
|
||||
"user": user,
|
||||
// "resources": resources,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
150
models/calc.go
Normal file
150
models/calc.go
Normal file
@@ -0,0 +1,150 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/arnaucube/gogame/constants"
|
||||
)
|
||||
|
||||
// formulas
|
||||
// https://ogame.fandom.com/wiki/Formulas
|
||||
// https://ogame.fandom.com/wiki/Research
|
||||
|
||||
// idelta is time in seconds units
|
||||
func MetalGrowth(ilvl int64, idelta int64) int64 {
|
||||
lvl := float64(ilvl)
|
||||
delta := float64(idelta)
|
||||
|
||||
// 30 * L * 1.1^L
|
||||
perHour := constants.UniverseAcceleration * 30 * lvl * math.Pow(1.1, lvl)
|
||||
r := (perHour / 60) * delta * constants.MineVelocity
|
||||
return int64(r)
|
||||
}
|
||||
func CrystalGrowth(ilvl int64, idelta int64) int64 {
|
||||
lvl := float64(ilvl)
|
||||
delta := float64(idelta)
|
||||
|
||||
// 20 * L * 1.1^L
|
||||
perHour := constants.UniverseAcceleration * 20 * lvl * math.Pow(1.1, lvl)
|
||||
r := (perHour / 60) * delta * constants.MineVelocity
|
||||
return int64(r)
|
||||
}
|
||||
func DeuteriumGrowth(ilvl int64, idelta int64) int64 {
|
||||
lvl := float64(ilvl)
|
||||
delta := float64(idelta)
|
||||
|
||||
t := float64(240) // t: max temperature
|
||||
// 10 * L * 1.1^L * (−0.002 * T + 1.28))
|
||||
perHour := constants.UniverseAcceleration * 10 * lvl * math.Pow(1.1, lvl) * ((-0.002)*t + 1.28)
|
||||
r := (perHour / 60) * delta * constants.MineVelocity
|
||||
return int64(r)
|
||||
}
|
||||
func SolarGrowth(ilvl int64, idelta int64) int64 {
|
||||
lvl := float64(ilvl)
|
||||
delta := float64(idelta)
|
||||
|
||||
// 20 * L * 1.1^L
|
||||
perHour := constants.UniverseAcceleration * 20 * lvl * math.Pow(1.1, lvl)
|
||||
r := (perHour / 60) * delta * constants.MineVelocity
|
||||
return int64(r)
|
||||
}
|
||||
func FusionGrowth(ilvl int64, ilvlTech int64, idelta int64) int64 {
|
||||
lvl := float64(ilvl)
|
||||
lvlTech := float64(ilvlTech)
|
||||
delta := float64(idelta)
|
||||
|
||||
// 30 * L * (1.05 + lvlTech * 0.01)^lvl
|
||||
perHour := constants.UniverseAcceleration * 30 * math.Pow((1.05+lvlTech*0.01), lvl)
|
||||
r := (perHour / 60) * delta * constants.MineVelocity
|
||||
return int64(r)
|
||||
}
|
||||
|
||||
// https://ogame.fandom.com/wiki/Buildings
|
||||
|
||||
// https://ogame.fandom.com/wiki/Metal_Mine
|
||||
func MetalMineCost(ilvl int64) Resources {
|
||||
lvl := float64(ilvl)
|
||||
base := Resources{
|
||||
Metal: 60,
|
||||
Crystal: 15,
|
||||
Deuterium: 0,
|
||||
Energy: 0,
|
||||
}
|
||||
// cost = base * 1.5^(lvl-1)
|
||||
cost := Resources{}
|
||||
cost.Metal = int64(float64(base.Metal) * math.Pow(1.5, lvl-1))
|
||||
cost.Crystal = int64(float64(base.Crystal) * math.Pow(1.5, lvl-1))
|
||||
cost.Deuterium = int64(float64(base.Deuterium) * math.Pow(1.5, lvl-1))
|
||||
cost.Energy = int64(float64(base.Energy) * math.Pow(1.5, lvl-1))
|
||||
return cost
|
||||
}
|
||||
|
||||
// https://ogame.fandom.com/wiki/Crystal_Mine
|
||||
func CrystalMineCost(ilvl int64) Resources {
|
||||
lvl := float64(ilvl)
|
||||
base := Resources{
|
||||
Metal: 48,
|
||||
Crystal: 24,
|
||||
Deuterium: 0,
|
||||
Energy: 0,
|
||||
}
|
||||
// cost = base * 1.6^(lvl-1)
|
||||
cost := Resources{}
|
||||
cost.Metal = int64(float64(base.Metal) * math.Pow(1.6, lvl-1))
|
||||
cost.Crystal = int64(float64(base.Crystal) * math.Pow(1.6, lvl-1))
|
||||
cost.Deuterium = int64(float64(base.Deuterium) * math.Pow(1.6, lvl-1))
|
||||
cost.Energy = int64(float64(base.Energy) * math.Pow(1.6, lvl-1))
|
||||
return cost
|
||||
}
|
||||
|
||||
// https://ogame.fandom.com/wiki/Deuterium_Synthesizer
|
||||
func DeuteriumMineCost(ilvl int64) Resources {
|
||||
lvl := float64(ilvl)
|
||||
base := Resources{
|
||||
Metal: 225,
|
||||
Crystal: 75,
|
||||
Deuterium: 0,
|
||||
Energy: 0,
|
||||
}
|
||||
// cost = base * 1.5^(lvl-1)
|
||||
cost := Resources{}
|
||||
cost.Metal = int64(float64(base.Metal) * math.Pow(1.5, lvl-1))
|
||||
cost.Crystal = int64(float64(base.Crystal) * math.Pow(1.5, lvl-1))
|
||||
cost.Deuterium = int64(float64(base.Deuterium) * math.Pow(1.5, lvl-1))
|
||||
cost.Energy = int64(float64(base.Energy) * math.Pow(1.5, lvl-1))
|
||||
return cost
|
||||
}
|
||||
|
||||
func EnergyMineCost(ilvl int64) Resources {
|
||||
lvl := float64(ilvl)
|
||||
base := Resources{
|
||||
Metal: 75,
|
||||
Crystal: 30,
|
||||
Deuterium: 0,
|
||||
Energy: 0,
|
||||
}
|
||||
// cost = base * 1.5^(lvl-1)
|
||||
cost := Resources{}
|
||||
cost.Metal = int64(float64(base.Metal) * math.Pow(1.5, lvl-1))
|
||||
cost.Crystal = int64(float64(base.Crystal) * math.Pow(1.5, lvl-1))
|
||||
cost.Deuterium = int64(float64(base.Deuterium) * math.Pow(1.5, lvl-1))
|
||||
cost.Energy = int64(float64(base.Energy) * math.Pow(1.5, lvl-1))
|
||||
return cost
|
||||
}
|
||||
|
||||
func RessearchLabCost(ilvl int64) Resources {
|
||||
lvl := float64(ilvl)
|
||||
base := Resources{
|
||||
Metal: 200,
|
||||
Crystal: 400,
|
||||
Deuterium: 200,
|
||||
Energy: 0,
|
||||
}
|
||||
// cost = base * 1.5^(lvl-1)
|
||||
cost := Resources{}
|
||||
cost.Metal = int64(float64(base.Metal) * math.Pow(2, lvl-1))
|
||||
cost.Crystal = int64(float64(base.Crystal) * math.Pow(2, lvl-1))
|
||||
cost.Deuterium = int64(float64(base.Deuterium) * math.Pow(2, lvl-1))
|
||||
cost.Energy = int64(float64(base.Energy) * math.Pow(2, lvl-1))
|
||||
return cost
|
||||
}
|
||||
62
models/calc_test.go
Normal file
62
models/calc_test.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/arnaucube/gogame/constants"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGrowth(t *testing.T) {
|
||||
// metal
|
||||
assert.Equal(t, int64(33), MetalGrowth(1, 60)/constants.MineVelocity)
|
||||
assert.Equal(t, int64(66), MetalGrowth(1, 120)/constants.MineVelocity)
|
||||
assert.Equal(t, int64(72), MetalGrowth(2, 60)/constants.MineVelocity)
|
||||
|
||||
// crystal
|
||||
assert.Equal(t, int64(22), CrystalGrowth(1, 60)/constants.MineVelocity)
|
||||
assert.Equal(t, int64(44), CrystalGrowth(1, 120)/constants.MineVelocity)
|
||||
assert.Equal(t, int64(48), CrystalGrowth(2, 60)/constants.MineVelocity)
|
||||
|
||||
// deuterium
|
||||
assert.Equal(t, int64(8), DeuteriumGrowth(1, 60)/constants.MineVelocity)
|
||||
assert.Equal(t, int64(17), DeuteriumGrowth(1, 120)/constants.MineVelocity)
|
||||
assert.Equal(t, int64(19), DeuteriumGrowth(2, 60)/constants.MineVelocity)
|
||||
|
||||
// solar
|
||||
assert.Equal(t, int64(22), SolarGrowth(1, 60)/constants.MineVelocity)
|
||||
assert.Equal(t, int64(44), SolarGrowth(1, 120)/constants.MineVelocity)
|
||||
assert.Equal(t, int64(48), SolarGrowth(2, 60)/constants.MineVelocity)
|
||||
|
||||
// fusion
|
||||
assert.Equal(t, int64(31), FusionGrowth(1, 1, 60)/constants.MineVelocity)
|
||||
assert.Equal(t, int64(63), FusionGrowth(1, 1, 120)/constants.MineVelocity)
|
||||
assert.Equal(t, int64(34), FusionGrowth(2, 2, 60)/constants.MineVelocity)
|
||||
}
|
||||
|
||||
func TestMineCost(t *testing.T) {
|
||||
// metalmine
|
||||
assert.Equal(t, Resources{Metal: 60, Crystal: 15}, MetalMineCost(1))
|
||||
assert.Equal(t, Resources{Metal: 90, Crystal: 22}, MetalMineCost(2))
|
||||
assert.Equal(t, Resources{Metal: 17515, Crystal: 4378}, MetalMineCost(15))
|
||||
|
||||
// crystalmine
|
||||
assert.Equal(t, Resources{Metal: 48, Crystal: 24}, CrystalMineCost(1))
|
||||
assert.Equal(t, Resources{Metal: 76, Crystal: 38}, CrystalMineCost(2))
|
||||
assert.Equal(t, Resources{Metal: 34587, Crystal: 17293}, CrystalMineCost(15))
|
||||
|
||||
// deuteriummine
|
||||
assert.Equal(t, Resources{Metal: 225, Crystal: 75}, DeuteriumMineCost(1))
|
||||
assert.Equal(t, Resources{Metal: 337, Crystal: 112}, DeuteriumMineCost(2))
|
||||
assert.Equal(t, Resources{Metal: 65684, Crystal: 21894}, DeuteriumMineCost(15))
|
||||
|
||||
// energymine
|
||||
assert.Equal(t, Resources{Metal: 75, Crystal: 30}, EnergyMineCost(1))
|
||||
assert.Equal(t, Resources{Metal: 112, Crystal: 45}, EnergyMineCost(2))
|
||||
assert.Equal(t, Resources{Metal: 21894, Crystal: 8757}, EnergyMineCost(15))
|
||||
|
||||
// researchlab
|
||||
assert.Equal(t, Resources{Metal: 200, Crystal: 400, Deuterium: 200}, RessearchLabCost(1))
|
||||
assert.Equal(t, Resources{Metal: 400, Crystal: 800, Deuterium: 400}, RessearchLabCost(2))
|
||||
assert.Equal(t, Resources{Metal: 3276800, Crystal: 6553600, Deuterium: 3276800}, RessearchLabCost(15))
|
||||
}
|
||||
@@ -107,7 +107,7 @@ func (u *User) GetResources() (*Resources, error) {
|
||||
return nil, err
|
||||
}
|
||||
// calculate Delta time = currentTime - u.LastUpdated
|
||||
delta := time.Since(u.LastUpdated)
|
||||
delta := time.Since(u.LastUpdated).Seconds()
|
||||
|
||||
// get planets
|
||||
planets, err := u.GetPlanets()
|
||||
@@ -119,11 +119,10 @@ func (u *User) GetResources() (*Resources, error) {
|
||||
// and calculate growth = ResourcePlant.Level for each planet
|
||||
var metalGrowth, crystalGrowth, deuteriumGrowth, energyGrowth int64
|
||||
for _, planet := range planets {
|
||||
// TODO find correct formulas
|
||||
metalGrowth = metalGrowth + ((1 + planet.Buildings["metalmine"]) * int64(delta))
|
||||
crystalGrowth = crystalGrowth + ((1 + planet.Buildings["crystalmine"]) * int64(delta))
|
||||
deuteriumGrowth = deuteriumGrowth + ((1 + planet.Buildings["deuteriummine"]) * int64(delta))
|
||||
energyGrowth = energyGrowth + ((1 + planet.Buildings["energymine"]) * int64(delta))
|
||||
metalGrowth = metalGrowth + MetalGrowth(planet.Buildings["metalmine"], int64(delta))
|
||||
crystalGrowth = crystalGrowth + MetalGrowth(planet.Buildings["crystalmine"], int64(delta))
|
||||
deuteriumGrowth = deuteriumGrowth + MetalGrowth(planet.Buildings["deuteriummine"], int64(delta))
|
||||
energyGrowth = energyGrowth + MetalGrowth(planet.Buildings["energymine"], int64(delta))
|
||||
}
|
||||
// calculate newAmount = oldAmount + growth
|
||||
u.Resources.Metal = u.Resources.Metal + metalGrowth
|
||||
@@ -171,3 +170,21 @@ func (u *User) SpendResources(r Resources) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *User) GetBuildingCost(planet Planet, building string) (Resources, error) {
|
||||
switch building {
|
||||
case "metalmine":
|
||||
return MetalMineCost(planet.Buildings["metalmine"] + 1), nil
|
||||
case "crystalmine":
|
||||
return CrystalMineCost(planet.Buildings["crystalmine"] + 1), nil
|
||||
case "deuteriummine":
|
||||
return DeuteriumMineCost(planet.Buildings["deuteriummine"] + 1), nil
|
||||
case "energymine":
|
||||
return EnergyMineCost(planet.Buildings["energymine"] + 1), nil
|
||||
case "ressearchlab":
|
||||
return RessearchLabCost(planet.Buildings["ressearchlab"] + 1), nil
|
||||
default:
|
||||
return Resources{}, errors.New("building not found")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,11 +31,11 @@ func (srv Service) CreatePlanet(userId bson.ObjectId) (*models.SolarSystem, *mod
|
||||
OwnerId: userId,
|
||||
}
|
||||
// in case that wants to start with resources plants
|
||||
// newPlanet.Buildings = make(map[string]int64)
|
||||
// newPlanet.Buildings["metalplant"] = 1
|
||||
// newPlanet.Buildings["crystalplant"] = 1
|
||||
// newPlanet.Buildings["deuteriumplant"] = 1
|
||||
// newPlanet.Buildings["energyplant"] = 1
|
||||
newPlanet.Buildings = make(map[string]int64)
|
||||
newPlanet.Buildings["metalmine"] = 1
|
||||
newPlanet.Buildings["crystalmine"] = 1
|
||||
newPlanet.Buildings["deuteriummine"] = 1
|
||||
newPlanet.Buildings["energymine"] = 1
|
||||
|
||||
err := srv.db.Planets.Insert(newPlanet)
|
||||
if err != nil {
|
||||
@@ -101,8 +101,13 @@ func (srv Service) UpgradeBuilding(user *models.User, planetid bson.ObjectId, bu
|
||||
}
|
||||
|
||||
// get current building level, and get the needed resources for next level
|
||||
resourcesNeeded := constants.BuildingsNeededResources[building][planet.Buildings[building]+1]
|
||||
resourcesNeeded, err := user.GetBuildingCost(planet, building)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Println("bui", building)
|
||||
fmt.Println("needed", resourcesNeeded)
|
||||
// if user have enough resources to upgrade the building, upgrade the building
|
||||
err = user.SpendResources(resourcesNeeded)
|
||||
if err != nil {
|
||||
|
||||
14
test/test.py
14
test/test.py
@@ -56,7 +56,7 @@ jsonR = r.json()
|
||||
print(jsonR)
|
||||
|
||||
r = requests.get(URL + "/planets", headers=headers)
|
||||
t.rStatus("post /planets/:userid", r)
|
||||
t.rStatus("post /planets", r)
|
||||
jsonR = r.json()
|
||||
print(jsonR)
|
||||
print(jsonR["planets"][0])
|
||||
@@ -64,10 +64,10 @@ planetid = jsonR["planets"][0]["id"]
|
||||
|
||||
d = {
|
||||
"planetid": planetid,
|
||||
"building": "metalplant",
|
||||
"building": "metalmine",
|
||||
}
|
||||
r = requests.post(URL + "/buildings", json=d, headers=headers)
|
||||
t.rStatus("post /building/:userid", r)
|
||||
t.rStatus("post /building", r)
|
||||
jsonR = r.json()
|
||||
print(jsonR)
|
||||
|
||||
@@ -76,7 +76,13 @@ d = {
|
||||
"building": "ressearchlab",
|
||||
}
|
||||
r = requests.post(URL + "/buildings", json=d, headers=headers)
|
||||
t.rStatus("post /building/:userid", r)
|
||||
t.rStatus("post /building", r)
|
||||
jsonR = r.json()
|
||||
print(jsonR)
|
||||
|
||||
time.sleep(1)
|
||||
r = requests.get(URL + "/resources", headers=headers)
|
||||
t.rStatus("get /resources", r)
|
||||
jsonR = r.json()
|
||||
print(jsonR)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user