Esempio n. 1
0
func (self *State) executeConflicts(l common.Logger) {
	execution := []func(){}
	for _, node := range self.Nodes {
		total := 0
		for _, units := range node.Units {
			total += units
		}
		for playerId, units := range node.Units {
			enemies := total - units
			if units > 0 && enemies > 0 {
				newSum := common.Max(0, common.Min(units-1, int(float64(units)-(float64(enemies)/5.0))))
				playerIdCpy := playerId
				nodeCpy := node
				if newSum < units {
					oldSum := units
					execution = append(execution, func() {
						nodeCpy.Units[playerIdCpy] = newSum
						self.Changes[nodeCpy.Id] = append(self.Changes[nodeCpy.Id], Change{
							Units:    newSum - oldSum,
							PlayerId: playerIdCpy,
							Reason:   ChangeReason("Conflict"),
						})
					})
				}
			}
		}
	}
	for _, exec := range execution {
		exec()
	}
}
Esempio n. 2
0
func (self *State) executeOrders(orderMap map[PlayerId]Orders) {
	execution := []func(){}
	for playerId, orders := range orderMap {
		for _, order := range orders {
			if src, found := self.Nodes[order.Src]; found {
				if edge, found := src.Edges[order.Dst]; found {
					toMove := common.Min(src.Units[playerId], order.Units)
					src.Units[playerId] -= toMove
					edgeCpy := edge
					playerIdCpy := playerId
					if toMove > 0 {
						execution = append(execution, func() {
							edgeCpy.Units[0][playerIdCpy] += toMove
							self.Changes[edgeCpy.Src] = append(self.Changes[edgeCpy.Src], Change{
								Units:    -toMove,
								PlayerId: playerIdCpy,
								Reason:   ChangeReason("Orders"),
							})
						})
					}
				}
			}
		}
	}
	for _, exec := range execution {
		exec()
	}
}
Esempio n. 3
0
func (self *State) executeGrowth(c common.Logger) {
	execution := []func(){}
	for _, node := range self.Nodes {
		total := 0
		for _, units := range node.Units {
			total += units
		}
		players := make([]PlayerId, 0, len(node.Units))
		for playerId, units := range node.Units {
			if units > 0 {
				players = append(players, playerId)
			}
		}
		if len(players) == 1 {
			playerId := players[0]
			units := node.Units[playerId]
			if total > 0 && total < node.Size {
				nodeCpy := node
				newSum := common.Min(node.Size, int(1+float64(units)*(1.0+(growthFactor*(float64(node.Size-total)/float64(node.Size))))))
				if newSum > units {
					execution = append(execution, func() {
						nodeCpy.Units[playerId] = newSum
						self.Changes[nodeCpy.Id] = append(self.Changes[nodeCpy.Id], Change{
							Units:    newSum - units,
							PlayerId: playerId,
							Reason:   ChangeReason("Growth"),
						})
					})
				}
			}
		} else if len(players) > 1 {
			if total > node.Size {
				for playerId, units := range node.Units {
					if units > 0 {
						playerIdCpy := playerId
						nodeCpy := node
						newSum := common.Max(0, int(float64(units)/(1.0+(starvationFactor*(float64(units)/float64(node.Size)))))-1)
						if newSum < units {
							oldSum := units
							execution = append(execution, func() {
								nodeCpy.Units[playerIdCpy] = newSum
								self.Changes[nodeCpy.Id] = append(self.Changes[nodeCpy.Id], Change{
									Units:    newSum - oldSum,
									PlayerId: playerIdCpy,
									Reason:   ChangeReason("Starvation"),
								})
							})
						}
					}
				}
			}
		}
	}
	for _, exec := range execution {
		exec()
	}
}
Esempio n. 4
0
/*
Orders will return orders randomly moving up to 20% of all troops in each occupied node along randomly chosen edges of that node.
*/
func (self Randomizer) Orders(logger common.Logger, me state.PlayerId, s *state.State) (result state.Orders) {
	// Go through all nodes
	for _, node := range s.Nodes {
		// If I have units here
		if node.Units[me] > 0 {
			// Create a slice with room for one float per edge in this node
			breakpoints := make(sort.Float64Slice, len(node.Edges))
			// Fill it with numbers between 0 and 0.2
			for index, _ := range breakpoints {
				breakpoints[index] = rand.Float64() / 5
			}
			// Sort the numbers
			sort.Sort(breakpoints)
			lastRate := 0.0
			rate := 1.0
			// For each edge in this node
			for _, edge := range node.Edges {
				// Take the fraction between the first float in the slice and the last picked float (or zero)
				rate = breakpoints[0] - lastRate
				lastRate = rate
				// Remove the first float from the slice
				breakpoints = breakpoints[1:]
				// Calculate how many units the fraction corresponds to
				units := common.Min(node.Units[me], int(float64(node.Units[me])*rate))
				// If any, create a move order for those units
				if units > 0 {
					result = append(result, state.Order{
						Src:   edge.Src,
						Dst:   edge.Dst,
						Units: units,
					})
				}
			}
		}
	}
	// Return the created orders
	return
}