Want more features on Pastebin? Sign Up, it's FREE!
Guest

Miridius Balanced AI v1

By: a guest on Oct 14th, 2013  |  syntax: Go  |  size: 2.76 KB  |  views: 51  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
This paste has a previous version, view the difference. Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. // miridiusAi
  2. package miridiusAi
  3.  
  4. import (
  5.         common "github.com/zond/stockholm-ai/common"
  6.         state "github.com/zond/stockholm-ai/state"
  7. )
  8.  
  9. /*
  10. BalancedAi1 basically just aims to multiply as much as possible
  11. 1. For each node i in s:
  12.         a. i.Attraction = how much growth I would gain by sending 1 soldier there
  13. 2. For each node j in s where I have units:
  14.         a. For each node k, attraction to k = k.Attraction / (distance from j to k)
  15.         b. attraction of each edge connected to j is the sum of the attractions of nodes whos path start with that edge
  16.         c. attraction of not moving = j.Attraction
  17.         d. leave 1 unit to hold the node, and divide remaining units amongst all edges proportionally based on attraction ratios
  18.  
  19. Known issues:
  20. 1. Soldiers currently on edges are not considered in calculations, which causes the AI to send out units more often than really necessary.
  21. */
  22. type BalancedAi1 struct{}
  23.  
  24. /*
  25. Orders will analyze all nodes in s and return orders for each one
  26. */
  27. func (self BalancedAi1) Orders(logger common.Logger, me state.PlayerId, s *state.State) (result state.Orders) {
  28.  
  29.         var attraction, totalAttraction float64
  30.         var edge state.NodeId
  31.         // Calculate base attraction for all nodes
  32.         attractions := make(map[state.NodeId]float64, len(s.Nodes))
  33.         for _, node := range s.Nodes {
  34.                 if node.Units[me] < 1 {
  35.                         attraction = 1
  36.                 } else {
  37.                         attraction = 0
  38.                 }
  39.                 attraction = attraction + (0.2 * float64(node.Units[me]) / float64(node.Size))
  40.  
  41.                 attractions[node.Id] = attraction
  42.         }
  43.  
  44.         // For each node in s
  45.         for _, node := range s.Nodes {
  46.                 // If I have units there (after leaving 1 behind to defend)
  47.                 if units := node.Units[me] - 1; units > 0 {
  48.                         // Check my attraction to all other nodes and keep an attraction sum for each starting edge.
  49.                         edgeAttractions := make(map[state.NodeId]float64, len(node.Edges)+1)
  50.                         totalAttraction = 0
  51.                         for _, destNode := range s.Nodes {
  52.                                 path := s.Path(node.Id, destNode.Id, nil)
  53.                                 if len(path) > 0 {
  54.                                         edge = path[0]
  55.                                         attraction = attractions[destNode.Id] / float64(len(path))
  56.                                 } else {
  57.                                         edge = node.Id
  58.                                         attraction = attractions[destNode.Id]
  59.                                 }
  60.                                 edgeAttractions[edge] = edgeAttractions[edge] + attraction
  61.                                 totalAttraction = totalAttraction + attraction
  62.                         }
  63.                         // go through all edges and send units accordingly
  64.                         for edgeId, att := range edgeAttractions {
  65.                                 // in case of rounding errors or some other hiccup, make sure current edge's attraction <= total
  66.                                 if att > totalAttraction {
  67.                                         totalAttraction = att
  68.                                 }
  69.                                 sendUnits := int(float64(units) * att / totalAttraction)
  70.                                 units = units - sendUnits
  71.                                 totalAttraction = totalAttraction - att
  72.                                 result = append(result, state.Order{
  73.                                         Src:   node.Id,
  74.                                         Dst:   edgeId,
  75.                                         Units: sendUnits,
  76.                                 })
  77.                         }
  78.                 }
  79.         }
  80.         return
  81. }
clone this paste RAW Paste Data