224 lines
4.7 KiB
Go
224 lines
4.7 KiB
Go
package model
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"hamster-tycoon/randomizer"
|
|
"time"
|
|
|
|
uuid "github.com/satori/go.uuid"
|
|
)
|
|
|
|
const (
|
|
Full = iota
|
|
AlmostFull
|
|
Middle
|
|
AlmostEmpty
|
|
Empty
|
|
)
|
|
|
|
const (
|
|
TotalGestationPeriod = 15
|
|
MinChild = 5
|
|
MaxChild = 9
|
|
GestationCooldown = (3 * 7) + 2
|
|
GestationMinAge = 10 * 6
|
|
MaxAge = 365 * 2
|
|
GestationLuck = 70
|
|
FEMALE = "F"
|
|
MALE = "M"
|
|
)
|
|
|
|
var GlobalHamsterNumber = 1
|
|
|
|
type Hamster struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Number int `json:"number"`
|
|
Sexe string `json:"sexe"`
|
|
Age int `json:"age"`
|
|
Father *Hamster `json:"father"`
|
|
Mother *Hamster `json:"mother"`
|
|
HungerLevel int8 `json:"hunger_level"`
|
|
ThirstLevel int8 `json:"thirst_level"`
|
|
Weight float64 `json:"weight"`
|
|
Height float64 `json:"height"`
|
|
Alive bool `json:"alive"`
|
|
Sold bool `json:"sold"`
|
|
Gestation bool `json:"gestation"`
|
|
GestationPeriod int8 `json:"gestation_period"`
|
|
GestationCooldown int8 `json:"gestation_cooldown"`
|
|
GestationFather *Hamster `json:"gestation_father"`
|
|
Child []*Hamster `json:"childs"`
|
|
CreatedAt time.Time `json:"createdAt"`
|
|
UpdatedAt *time.Time `json:"updatedAt"`
|
|
Cage *Cage `json:"cage"`
|
|
}
|
|
|
|
func (h *Hamster) Die() {
|
|
h.Alive = false
|
|
}
|
|
|
|
func (h *Hamster) DeterminatePrice() int {
|
|
if h.Age >= 600 {
|
|
return 0
|
|
}
|
|
var price = 50
|
|
if h.Age >= 60 && h.Age <= 300 {
|
|
var diffAge, quotient int
|
|
diffAge = 300 - h.Age
|
|
quotient = diffAge / 25
|
|
price += quotient * 5
|
|
}
|
|
if h.Sexe == FEMALE {
|
|
price += 20
|
|
} else {
|
|
price -= 20
|
|
}
|
|
|
|
if h.Gestation {
|
|
if h.Age >= 500 {
|
|
price += 5
|
|
} else {
|
|
price += 20
|
|
}
|
|
}
|
|
|
|
if h.Age > 300 {
|
|
var diffAge, quotient int
|
|
diffAge = h.Age - 300
|
|
quotient = diffAge / 100
|
|
price += quotient * 10
|
|
}
|
|
|
|
switch h.ThirstLevel {
|
|
case Empty:
|
|
price -= 20
|
|
case AlmostEmpty:
|
|
price -= 10
|
|
case AlmostFull:
|
|
price += 10
|
|
case Full:
|
|
price += 20
|
|
}
|
|
|
|
switch h.HungerLevel {
|
|
case Empty:
|
|
price -= 20
|
|
case AlmostEmpty:
|
|
price -= 10
|
|
case AlmostFull:
|
|
price += 10
|
|
case Full:
|
|
price += 20
|
|
}
|
|
switch {
|
|
case h.GestationCooldown > 0 && h.GestationCooldown <= 7:
|
|
price -= 10
|
|
case h.GestationCooldown >= 8 && h.GestationCooldown <= 14:
|
|
price -= 5
|
|
case h.GestationCooldown > 15:
|
|
price -= 2
|
|
}
|
|
return price
|
|
|
|
}
|
|
|
|
func (h *Hamster) Grow() {
|
|
if h.Age >= MaxAge {
|
|
if randNumber(h.Age-MaxAge, 365) > 364 {
|
|
h.Die()
|
|
return
|
|
}
|
|
}
|
|
h.Age++
|
|
if h.Gestation {
|
|
h.GestationPeriod++
|
|
} else {
|
|
if h.GestationCooldown > 0 {
|
|
h.GestationCooldown--
|
|
}
|
|
}
|
|
fmt.Println(h.GestationCooldown)
|
|
}
|
|
|
|
func (h *Hamster) Fuck(another *Hamster) (bool, error) {
|
|
if h.Sexe == another.Sexe {
|
|
return false, errors.New("can't fuck together")
|
|
}
|
|
|
|
if h.Age < GestationMinAge || another.Age < GestationMinAge {
|
|
return false, errors.New("one of the hamster is too young")
|
|
}
|
|
|
|
rand := randNumber(1, 100)
|
|
|
|
if rand <= GestationLuck {
|
|
female, male := func() (*Hamster, *Hamster) {
|
|
if h.Sexe == FEMALE {
|
|
return h, another
|
|
}
|
|
return another, h
|
|
}()
|
|
female.GestationFather = male
|
|
female.Gestation = true
|
|
female.GestationPeriod = 0
|
|
female.GestationCooldown = TotalGestationPeriod + GestationCooldown
|
|
}
|
|
return rand <= GestationLuck, nil
|
|
}
|
|
|
|
func Born(father *Hamster, mother *Hamster) ([]*Hamster, error) {
|
|
if !mother.Alive || mother.Sold {
|
|
return nil, errors.New("the mother is not here")
|
|
}
|
|
if mother.GestationPeriod != TotalGestationPeriod {
|
|
return nil, errors.New("not the time to make child")
|
|
}
|
|
|
|
mother.GestationCooldown = 0
|
|
mother.Gestation = false
|
|
mother.GestationPeriod = 0
|
|
|
|
numberOfChild := randNumberChild()
|
|
child := make([]*Hamster, numberOfChild)
|
|
for i := 0; i < numberOfChild; i++ {
|
|
child[i] = &Hamster{
|
|
ID: uuid.NewV4().String(),
|
|
Name: fmt.Sprintf("Hamster %d", GlobalHamsterNumber),
|
|
Number: GlobalHamsterNumber,
|
|
Age: 1,
|
|
Sexe: randSexe(),
|
|
Father: father,
|
|
Mother: mother,
|
|
HungerLevel: Full,
|
|
ThirstLevel: Full,
|
|
Alive: true,
|
|
Sold: false,
|
|
Gestation: false,
|
|
GestationPeriod: 0,
|
|
GestationCooldown: 30,
|
|
}
|
|
}
|
|
mother.Child = append(mother.Child, child...)
|
|
father.Child = append(father.Child, child...)
|
|
return child, nil
|
|
}
|
|
|
|
func randNumberChild() int {
|
|
return randNumber(MinChild, MaxChild)
|
|
}
|
|
|
|
func randSexe() string {
|
|
return func() string {
|
|
if randNumber(1, 2) == 2 {
|
|
return MALE
|
|
}
|
|
return FEMALE
|
|
}()
|
|
}
|
|
|
|
func randNumber(min int, max int) int {
|
|
return min + randomizer.Rand(max)
|
|
}
|