77 lines
1.8 KiB
Go
77 lines
1.8 KiB
Go
package turn
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/iliadenisov/galaxy/internal/controller"
|
|
e "github.com/iliadenisov/galaxy/internal/error"
|
|
"github.com/iliadenisov/galaxy/internal/model/game"
|
|
)
|
|
|
|
func MakeTurn(r controller.Repo, g *game.Game) error {
|
|
// Next turn
|
|
g.Age += 1
|
|
|
|
// 01. Корабли, где это возможно, объединяются в группы.
|
|
game.JoinEqualGroups(g)
|
|
|
|
// 02. Враждующие корабли вступают в схватку.
|
|
battles := game.ProduceBattles(g)
|
|
|
|
// Internal control: after battles there are can't be groups with no ships left
|
|
for i := range g.ShipGroups {
|
|
if g.ShipGroups[i].Number == 0 {
|
|
return e.NewGameStateError("")
|
|
}
|
|
}
|
|
|
|
// Last step: storing battles
|
|
if len(battles) > 0 {
|
|
for i := range battles {
|
|
br := TransformBattle(g, battles[i])
|
|
if err := r.SaveBattle(g.Age, br); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func TransformBattle(g *game.Game, b *game.Battle) *game.BattleReport {
|
|
p, ok := game.PlanetByNum(g, b.Planet)
|
|
if !ok {
|
|
panic(fmt.Sprintf("TransformBattle: no planet with number #%d", b.Planet))
|
|
}
|
|
r := &game.BattleReport{
|
|
ID: b.ID,
|
|
Planet: b.Planet,
|
|
PlanetName: p.Name,
|
|
Races: make(map[int]string),
|
|
Ships: make(map[int]string),
|
|
Protocol: make([]game.BattleActionReport, len(b.Protocol)),
|
|
}
|
|
|
|
cacheShipClass := make(map[string]int)
|
|
|
|
shipClass := func(shipClass string) int {
|
|
if v, ok := cacheShipClass[shipClass]; ok {
|
|
return v
|
|
} else {
|
|
l := len(r.Ships)
|
|
r.Ships[l] = shipClass
|
|
cacheShipClass[shipClass] = l
|
|
return l
|
|
}
|
|
}
|
|
|
|
for i := range b.Protocol {
|
|
r.Protocol[i] = game.BattleActionReport{
|
|
AttackerShipClass: shipClass(b.ShipClassName(b.Protocol[i].Attacker)),
|
|
DefenderShipClass: shipClass(b.ShipClassName(b.Protocol[i].Defenter)),
|
|
Destroyed: b.Protocol[i].Destroyed,
|
|
}
|
|
}
|
|
|
|
return r
|
|
}
|