diff --git a/constants/constants.go b/constants/constants.go index 69ac5ed..3dc2860 100644 --- a/constants/constants.go +++ b/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" diff --git a/endpoint/handlers.go b/endpoint/handlers.go index 691fc36..a5cd981 100644 --- a/endpoint/handlers.go +++ b/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, }) } diff --git a/models/calc.go b/models/calc.go new file mode 100644 index 0000000..597354f --- /dev/null +++ b/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 +} diff --git a/models/calc_test.go b/models/calc_test.go new file mode 100644 index 0000000..da48250 --- /dev/null +++ b/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)) +} diff --git a/models/user.go b/models/user.go index f5eb41c..a459b5b 100644 --- a/models/user.go +++ b/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") + } + +} diff --git a/services/gamesrv/gamesrv.go b/services/gamesrv/gamesrv.go index 598b5bb..34d740d 100644 --- a/services/gamesrv/gamesrv.go +++ b/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 { diff --git a/test/test.py b/test/test.py index 67a8039..0eb42b1 100644 --- a/test/test.py +++ b/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)