Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // miridiusAi
- package miridiusAi
- import (
- common "github.com/zond/stockholm-ai/common"
- state "github.com/zond/stockholm-ai/state"
- )
- /*
- BalancedAi1 basically just aims to multiply as much as possible
- 1. For each node i in s:
- a. i.Attraction = how much growth I would gain by sending 1 soldier there
- 2. For each node j in s where I have units:
- a. For each node k, attraction to k = k.Attraction / (distance from j to k)
- b. attraction of each edge connected to j is the sum of the attractions of nodes whos path start with that edge
- c. attraction of not moving = j.Attraction
- d. leave 1 unit to hold the node, and divide remaining units amongst all edges proportionally based on attraction ratios
- Known issues:
- 1. Soldiers currently on edges are not considered in calculations, which causes the AI to send out units more often than really necessary.
- */
- type BalancedAi1 struct{}
- /*
- Orders will analyze all nodes in s and return orders for each one
- */
- func (self BalancedAi1) Orders(logger common.Logger, me state.PlayerId, s *state.State) (result state.Orders) {
- var attraction, totalAttraction float64
- var edge state.NodeId
- // Calculate base attraction for all nodes
- attractions := make(map[state.NodeId]float64, len(s.Nodes))
- for _, node := range s.Nodes {
- if node.Units[me] < 1 {
- attraction = 1
- } else {
- attraction = 0
- }
- attraction = attraction + (0.2 * float64(node.Units[me]) / float64(node.Size))
- attractions[node.Id] = attraction
- }
- // For each node in s
- for _, node := range s.Nodes {
- // If I have units there (after leaving 1 behind to defend)
- if units := node.Units[me] - 1; units > 0 {
- // Check my attraction to all other nodes and keep an attraction sum for each starting edge.
- edgeAttractions := make(map[state.NodeId]float64, len(node.Edges)+1)
- totalAttraction = 0
- for _, destNode := range s.Nodes {
- path := s.Path(node.Id, destNode.Id, nil)
- if len(path) > 0 {
- edge = path[0]
- attraction = attractions[destNode.Id] / float64(len(path))
- } else {
- edge = node.Id
- attraction = attractions[destNode.Id]
- }
- edgeAttractions[edge] = edgeAttractions[edge] + attraction
- totalAttraction = totalAttraction + attraction
- }
- // go through all edges and send units accordingly
- for edgeId, att := range edgeAttractions {
- // in case of rounding errors or some other hiccup, make sure current edge's attraction <= total
- if att > totalAttraction {
- totalAttraction = att
- }
- sendUnits := int(float64(units) * att / totalAttraction)
- units = units - sendUnits
- totalAttraction = totalAttraction - att
- result = append(result, state.Order{
- Src: node.Id,
- Dst: edgeId,
- Units: sendUnits,
- })
- }
- }
- }
- return
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement