feat: cargo unload challenge
This commit is contained in:
@@ -5,7 +5,6 @@ import (
|
||||
"fmt"
|
||||
"iter"
|
||||
"maps"
|
||||
"math/rand/v2"
|
||||
"slices"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@@ -283,97 +282,16 @@ func (c *Cache) shipGroupUnload(ri int, groupID uuid.UUID, quantity float64) err
|
||||
return e.NewEntityNotOwnedError("planet #%d unload %v", p.Number, ct)
|
||||
}
|
||||
|
||||
toBeUnloaded := quantity
|
||||
if quantity == 0 {
|
||||
toBeUnloaded = float64(c.ShipGroup(sgi).Load)
|
||||
}
|
||||
if toBeUnloaded > float64(c.ShipGroup(sgi).Load) {
|
||||
return e.NewCargoUnoadNotEnoughError("load: %.03f", c.ShipGroup(sgi).Load)
|
||||
}
|
||||
|
||||
c.unsafeUnloadCargo(sgi, toBeUnloaded)
|
||||
|
||||
c.unsafeUnloadCargo(sgi, UnloadCargoRequest(float64(c.ShipGroup(sgi).Load), quantity))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Cache) shipGroupUnloadColonistChallenge(groupIDs []uuid.UUID, quantites []float64) error {
|
||||
if len(groupIDs) != len(quantites) {
|
||||
e.NewGameStateError("challenge group unload: groups=%d quantities=%d", len(groupIDs), len(quantites))
|
||||
func UnloadCargoRequest(load, quantity float64) float64 {
|
||||
result := quantity
|
||||
if result == 0 || result > load {
|
||||
result = load
|
||||
}
|
||||
if len(groupIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
type challenger struct {
|
||||
ri int
|
||||
sgi int
|
||||
quantity float64
|
||||
}
|
||||
challenge := make(map[uint]map[int][]challenger, 0)
|
||||
for i, gid := range groupIDs {
|
||||
sgi, ok := c.shipGroupIndexByID(gid)
|
||||
if !ok {
|
||||
return e.NewGameStateError("challenge group unload: group not found: %v", gid)
|
||||
}
|
||||
sg := c.ShipGroup(sgi)
|
||||
pn, ok := sg.AtPlanet()
|
||||
if !ok || sg.CargoType == nil {
|
||||
continue
|
||||
}
|
||||
p := c.MustPlanet(pn)
|
||||
ri := c.ShipGroupOwnerRaceIndex(sgi)
|
||||
if p.Owned() || *sg.CargoType != game.CargoColonist {
|
||||
if err := c.shipGroupUnload(ri, gid, quantites[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if _, ok := challenge[pn]; !ok {
|
||||
challenge[pn] = make(map[int][]challenger)
|
||||
}
|
||||
challenge[pn][ri] = append(challenge[pn][ri], challenger{ri: ri, sgi: sgi, quantity: quantites[i]})
|
||||
}
|
||||
for pn := range challenge {
|
||||
if len(challenge[pn]) < 2 {
|
||||
for _, v := range challenge[pn] {
|
||||
for _, ch := range v {
|
||||
if err := c.shipGroupUnload(ch.ri, c.ShipGroup(ch.sgi).ID, ch.quantity); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
sum := make(map[int]float64)
|
||||
races := slices.Collect(maps.Keys(challenge[pn]))
|
||||
for ri, groups := range challenge[pn] {
|
||||
for i := range groups {
|
||||
sum[ri] = sum[ri] + groups[i].quantity
|
||||
}
|
||||
c.listProducingPlanets()
|
||||
}
|
||||
|
||||
slices.SortFunc(races, func(ria, rib int) int {
|
||||
return cmp.Or(
|
||||
// Наибольшее количество выгружаемых колонистов
|
||||
cmp.Compare(sum[rib], sum[ria]),
|
||||
|
||||
// Наибольшее количество населения расы (они же голоса)
|
||||
cmp.Compare(c.g.Race[rib].Votes, c.g.Race[ria].Votes),
|
||||
|
||||
// Случайный выбор претендента
|
||||
cmp.Compare(rand.Float64(), rand.Float64()),
|
||||
|
||||
// in theoty, unreacheable option, but let's randomize again
|
||||
cmp.Compare(rand.Float64(), rand.Float64()),
|
||||
)
|
||||
})
|
||||
|
||||
for _, ch := range challenge[pn][races[0]] {
|
||||
if err := c.shipGroupUnload(ch.ri, c.ShipGroup(ch.sgi).ID, ch.quantity); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return result
|
||||
}
|
||||
|
||||
func (c *Cache) shipGroupIndexByID(id uuid.UUID) (int, bool) {
|
||||
|
||||
Reference in New Issue
Block a user