Browse Source

add calc.go Growths in time, Mines costs. Applied to game

master
arnaucube 4 years ago
parent
commit
80fe8883b1
7 changed files with 265 additions and 78 deletions
  1. +2
    -55
      constants/constants.go
  2. +7
    -7
      endpoint/handlers.go
  3. +150
    -0
      models/calc.go
  4. +62
    -0
      models/calc_test.go
  5. +23
    -6
      models/user.go
  6. +11
    -6
      services/gamesrv/gamesrv.go
  7. +10
    -4
      test/test.py

+ 2
- 55
constants/constants.go

@ -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"

+ 7
- 7
endpoint/handlers.go

@ -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
- 0
models/calc.go

@ -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
- 0
models/calc_test.go

@ -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))
}

+ 23
- 6
models/user.go

@ -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")
}
}

+ 11
- 6
services/gamesrv/gamesrv.go

@ -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 {

+ 10
- 4
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)

Loading…
Cancel
Save