fix: battles are not round-based
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"iter"
|
||||||
"maps"
|
"maps"
|
||||||
"math"
|
"math"
|
||||||
"math/rand/v2"
|
"math/rand/v2"
|
||||||
@@ -84,15 +85,6 @@ func FilterBattleOpponents(c *Cache, attIdx, defIdx int, cacheProbability map[in
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
FIXME: Сражение происходит раундами
|
|
||||||
|
|
||||||
Случайным образом из всех участвующих в сражении вооруженных кораблей выбирается один...
|
|
||||||
...Затем вновь случайным образом выбирается корабль, который будет стрелять...
|
|
||||||
Так продолжается до тех пор, пока не отстреляются все корабли. Если после
|
|
||||||
этого еще остались корабли и с той и с другой стороны, все повторяется с
|
|
||||||
самого начала (происходит еще один цикл сражения).
|
|
||||||
*/
|
|
||||||
func ProduceBattles(c *Cache) []*Battle {
|
func ProduceBattles(c *Cache) []*Battle {
|
||||||
cacheProbability := make(map[int]map[int]float64)
|
cacheProbability := make(map[int]map[int]float64)
|
||||||
defer func() { clear(cacheProbability) }()
|
defer func() { clear(cacheProbability) }()
|
||||||
@@ -159,13 +151,23 @@ func ProduceBattles(c *Cache) []*Battle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SingleBattle(c *Cache, b *Battle) {
|
func SingleBattle(c *Cache, b *Battle) {
|
||||||
|
roundShooters := make(map[int]bool)
|
||||||
for len(b.attacker) > 0 {
|
for len(b.attacker) > 0 {
|
||||||
attackers := slices.Collect(maps.Keys(b.attacker))
|
// список участников раунда
|
||||||
attIdx := attackers[rand.IntN(len(attackers))]
|
clear(roundShooters)
|
||||||
|
for sgi := range b.attacker {
|
||||||
|
roundShooters[sgi] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for len(roundShooters) > 0 {
|
||||||
|
// attacke group id among round participants
|
||||||
|
attIdx := randomValue(maps.Keys(roundShooters))
|
||||||
|
delete(roundShooters, attIdx)
|
||||||
|
|
||||||
for range b.shipAmmo[attIdx] {
|
for range b.shipAmmo[attIdx] {
|
||||||
defenders := slices.Collect(maps.Keys(b.attacker[attIdx]))
|
// defender group id among all attacker's opponents
|
||||||
defIdx := defenders[rand.IntN(len(defenders))]
|
defIdx := randomValue(maps.Keys(b.attacker[attIdx]))
|
||||||
|
|
||||||
destroyed := false
|
destroyed := false
|
||||||
|
|
||||||
probability := b.attacker[attIdx][defIdx]
|
probability := b.attacker[attIdx][defIdx]
|
||||||
@@ -188,19 +190,29 @@ func SingleBattle(c *Cache, b *Battle) {
|
|||||||
c.ShipGroupDestroyItem(defIdx)
|
c.ShipGroupDestroyItem(defIdx)
|
||||||
}
|
}
|
||||||
if c.ShipGroup(defIdx).Number == 0 {
|
if c.ShipGroup(defIdx).Number == 0 {
|
||||||
delete(b.attacker, defIdx) // Eliminated group cant attack anyone
|
// Eliminated group cant attack anyone
|
||||||
|
delete(b.attacker, defIdx)
|
||||||
|
delete(roundShooters, defIdx)
|
||||||
|
|
||||||
for attIdx := range b.attacker {
|
for attIdx := range b.attacker {
|
||||||
delete(b.attacker[attIdx], defIdx) // Other attackers can't attack eliminated group anymore
|
// Other attackers can't attack eliminated group anymore
|
||||||
|
delete(b.attacker[attIdx], defIdx)
|
||||||
|
|
||||||
if len(b.attacker[attIdx]) == 0 {
|
if len(b.attacker[attIdx]) == 0 {
|
||||||
delete(b.attacker, attIdx) // Remove attacker if he lost all opponents
|
// Remove attacker if he lost all opponents
|
||||||
|
delete(b.attacker, attIdx)
|
||||||
|
delete(roundShooters, attIdx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When attacker has no more targets to shoot - break its ammo cycle
|
||||||
if len(b.attacker[attIdx]) == 0 {
|
if len(b.attacker[attIdx]) == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func DestructionProbability(attWeapons, attWeaponsTech, defShields, defShiledsTech, defFullMass float64) float64 {
|
func DestructionProbability(attWeapons, attWeaponsTech, defShields, defShiledsTech, defFullMass float64) float64 {
|
||||||
@@ -212,3 +224,8 @@ func DestructionProbability(attWeapons, attWeaponsTech, defShields, defShiledsTe
|
|||||||
func EffectiveDefence(defShields, defShiledsTech, defFullMass float64) float64 {
|
func EffectiveDefence(defShields, defShiledsTech, defFullMass float64) float64 {
|
||||||
return defShields * defShiledsTech / math.Pow(defFullMass, 1./3.) * math.Pow(30., 1./3.)
|
return defShields * defShiledsTech / math.Pow(defFullMass, 1./3.) * math.Pow(30., 1./3.)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func randomValue(v iter.Seq[int]) int {
|
||||||
|
ids := slices.Collect(v)
|
||||||
|
return ids[rand.IntN(len(ids))]
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ func (c *Controller) MakeTurn() error {
|
|||||||
c.Cache.g.Turn += 1
|
c.Cache.g.Turn += 1
|
||||||
c.Cache.g.Stage = 0
|
c.Cache.g.Stage = 0
|
||||||
|
|
||||||
|
// TODO: Выполнение приказов
|
||||||
|
|
||||||
// 01. Вышедшие расы удаляются из списка участвующих рас перед началом просчета очередного хода
|
// 01. Вышедшие расы удаляются из списка участвующих рас перед началом просчета очередного хода
|
||||||
c.Cache.TurnWipeExtinctRaces()
|
c.Cache.TurnWipeExtinctRaces()
|
||||||
|
|
||||||
// TODO: передача кораблей между расами
|
|
||||||
|
|
||||||
// 02. Товары загружаются на корабли, находящиеся в начале грузовых маршрутов, и корабли входят в гиперпространство (но ещё не полетели)
|
// 02. Товары загружаются на корабли, находящиеся в начале грузовых маршрутов, и корабли входят в гиперпространство (но ещё не полетели)
|
||||||
c.Cache.SendRoutedGroups()
|
c.Cache.SendRoutedGroups()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user