Documentation ¶
Index ¶
- type AI
- type Action
- type ActionBuilder
- func NewFirstToScoreThinker(threshold float64, children []ScoredActionBuilder) ActionBuilder
- func NewHighestScoreThinker(actions []ScoredActionBuilder) ActionBuilder
- func NewLinearProbabilisticThinker(threshold float64, children []ScoredActionBuilder) ActionBuilder
- func NewSoftMaxProbabilisticThinker(threshold float64, factor float64, children []ScoredActionBuilder) ActionBuilder
- func NewThinkerBuilder(thinker Thinker, actions []ScoredActionBuilder) ActionBuilder
- type ActionState
- type BayesFactor
- type BayesFactorBuilder
- type BayesScorer
- type CooldownQualifiedScoredAction
- type FixedScorer
- type IdleAction
- type InverterQualifier
- type MultCombineQualifier
- type ScoredAction
- type ScoredActionBuilder
- type Scorer
- type ScorerBuilder
- type ScorerBuilderAndActionBuilder
- type Thinker
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AI ¶
type AI struct {
// contains filtered or unexported fields
}
AI runs Actions on all the actors within the world.
func NewAI ¶
func NewAI(world interface{}, coreAction ActionBuilder) *AI
NewAI constructs a new AI within the given world, which uses the given coreAction for all actors. Typically coreAction is a Thinker, though this is not enforced.
func (*AI) AddActor ¶
func (ai *AI) AddActor(actor interface{})
AddActor adds the given actor to be handled by this AI.
performance: O(1) amortized
func (*AI) RemoveActor ¶
func (ai *AI) RemoveActor(actor interface{})
RemoveActor removes the given actor from being handled by this AI.
performance: O(n) where n is the number of actors
type Action ¶
type Action interface { // State returns the state of this action. Actions are responsible for // ensuring their state goes through the correct phases. State() ActionState // Attached is called when the action is in the state Init to let them know // which world and actor they are acting upon. The Action should typically // verify these are of the appropriate type and store them in a stricter // type, then move to Requested, Success, or Failure as appropriate. A // single Action is not reused across actors. Attached(world, actor interface{}) // Execute this action within the world on the actor, after the given // amount of elapsed time since the last call (or an arbitrary value // if never called before). Should eventually result in the action // transitioning to Success or Failure. Execute(delta time.Duration) // Cancel this action, which tells the Action to do whatever is necessary // to get to the Success or Failure state as quickly as possible. Typically // this will either imemdiately update the state of the Action to Success // or Failure, or move the action into the Canceled state. This is NOT called // if the actor is removed from the AI - the Action simply will no longer // receive callbacks in that event, to avoid tedious nil handling within // each Action. Cancel() // FinishCanceling is called when the Action is in the Cancel state, and // should eventually move the action to the Success or Failure state. It // is passed the elapsed time since the last call or an arbitrary value // if never called before. FinishCanceling(delta time.Duration) // Reset is called only in the Success or Failure state, and acts as the // equivalent of Attached except for an instance that's already been used // before. Reset() }
Action is a stateful object that acts upon a given actor in a given world. These are produced by action builders, which are what go into the AI.
type ActionBuilder ¶
type ActionBuilder interface { // Build the action Build() Action }
ActionBuilder is something capable of building unattached actions and is generally stateless
func NewFirstToScoreThinker ¶
func NewFirstToScoreThinker(threshold float64, children []ScoredActionBuilder) ActionBuilder
NewFirstToScoreThinker produces a Thinker which performs the first child whose score meets or exceeds the threshold, falling back to a HighestScoreThinker if no children meet or exceed the threshold.
func NewHighestScoreThinker ¶
func NewHighestScoreThinker(actions []ScoredActionBuilder) ActionBuilder
NewHighestScoreThinker produces a Thinker which performs whichever action from the given list of scored actions has the highest score. In the event of ties, it chooses uniformly at random from the ties.
func NewLinearProbabilisticThinker ¶
func NewLinearProbabilisticThinker(threshold float64, children []ScoredActionBuilder) ActionBuilder
NewLinearProbabilisticThinker produces a new Thinker which selects which child randomly, where the probability of a child being selected is proportional to its score. If any of the children scores meet or exceed the threshold, then all children below the threshold score are ignored.
func NewSoftMaxProbabilisticThinker ¶
func NewSoftMaxProbabilisticThinker(threshold float64, factor float64, children []ScoredActionBuilder) ActionBuilder
NewSoftMaxProbabilisticThinker produces a Thinker which selects a child randomly from the children with a probability proportional to e^(score*factor). If there are any children whose score meets or exceeds the given threshold, then all children whose score is below the threshold are ignored.
A factor of 1 makes this a pure soft-max function. A factor of 0 makes this a completely random choice. A higher factor reduces the amount of randomness. The factor is typically between 5 and 30
func NewThinkerBuilder ¶
func NewThinkerBuilder(thinker Thinker, actions []ScoredActionBuilder) ActionBuilder
NewThinkerBuilder produces an ActionBuilder out of something implementing the Thinker interface and the non-empty slice of children.
type ActionState ¶
type ActionState int
const ( // The initial state of an Action; implies it needs to be Attach'd. ActionStateInit ActionState = 0 // The action has never been Execute'd before and should have Execute // called ActionStateRequested ActionState = 1 // The action has had Execute called before but still needs Execute // to be called ActionStateExecuting ActionState = 2 // Something has requested the action be canceled, but it is not done // canceling so FinishCanceling should be called ActionStateCanceled ActionState = 3 // The action succeeded ActionStateSuccess ActionState = 4 // The action failed ActionStateFailure ActionState = 5 )
type BayesFactor ¶
type BayesFactor interface { // Attached is called once to tell the factor the world and actor // it is operating within. Typically the factor will store more // strictly typed representations. Attached(world, actor interface{}) // Factor returns how much information was gained by this factor. // If this factor is not informative, this will return // `big.NewRat(1, 1)`. If this increases the probability of success // by a factor of 2, this returns `big.NewRat(2, 1)`. If it decreases // the odds of success by a factor of 2, this returns `big.NewRat(1, 2)`. Factor() *big.Rat }
BayesFactor describes something which can alter our prediction about something by a given factor. It is stateful and only used for a single actor in a single world.
type BayesFactorBuilder ¶
type BayesFactorBuilder interface { // Build a new BayesFactor not attached yet. Build() BayesFactor }
BayesFactorBuilder acts as a constructor for BayesFactors, since we need one BayesFactor per actor. Typically stateless.
type BayesScorer ¶
type BayesScorer struct {
// contains filtered or unexported fields
}
BayesScorer is a type of ScorerBuilder that assumes that the utility of the action is 1, but it only succeeds probabilistically. It has some general chance at success, such as 1 success per 4 failures. It also has a set of things which alter its odds of success based on the world, such as "succeeds twice as often when Y is researched" in order to produce the final probability of succeeds.
func (BayesScorer) Build ¶
func (s BayesScorer) Build() Scorer
type CooldownQualifiedScoredAction ¶ added in v0.2.0
type CooldownQualifiedScoredAction struct { ScoredAction ScoredActionBuilder MinCooldown time.Duration MaxCooldown time.Duration CooldownSuppressedOnSuccess bool CooldownSuppressedOnFailure bool }
CooldownQualifiedScoredAction creates a dependency between the scorer and action provided. Specifically, the Score is set to 0 if it's been less than the MinCooldown since the Action completed, it is scaled linearly between 0 and 1 between the MinCooldown and MaxCooldown, and it is unmodified past the MaxCooldown.
func (CooldownQualifiedScoredAction) Build ¶ added in v0.2.0
func (b CooldownQualifiedScoredAction) Build() ScoredAction
type FixedScorer ¶
type FixedScorer struct { // Score is the score that the fixed scorer returns for all actors // at all times in all worlds Score float64 }
FixedScorer is the simplest type of scorer which always returns the same value
type IdleAction ¶ added in v0.1.2
type IdleAction struct { // MinDuration is the minimum duration to idle for. MinDuration time.Duration // MaxDuration is the maximum duration to idle for. MaxDuration time.Duration }
IdleAction idles for a random amount of time selected uniformly between the min and max duration.
func (IdleAction) Build ¶ added in v0.1.2
func (b IdleAction) Build() Action
type InverterQualifier ¶ added in v0.2.7
type InverterQualifier struct { // Scorer is the scorer to invert Scorer ScorerBuilder }
InverterQualifier inverts the score of the child, i.e., returns 1 - Scorer.Score()
func (InverterQualifier) Build ¶ added in v0.2.7
func (b InverterQualifier) Build() Scorer
type MultCombineQualifier ¶ added in v0.2.7
type MultCombineQualifier struct { // Children are the children the score is built from Children []ScorerBuilder }
MultCombineQualifier produces a score from the children by multiplying their scores together.
func (MultCombineQualifier) Build ¶ added in v0.2.7
func (b MultCombineQualifier) Build() Scorer
type ScoredAction ¶
ScoredAction is a convenience struct for describing an Action and a Score. This is typically only used within actual Actions, - for nesting ActionBuilder's use ScoredActionBuilder
type ScoredActionBuilder ¶
type ScoredActionBuilder interface {
Build() ScoredAction
}
ScoredActionBuilder builds pairs of actions and scores. If the action and scorer are independent then the obvious implementation is done via ScorerBuilderAndActionBuilder. For example, when the Scorer is a fixed scorer, then the action and scorer are independent, i.e., you can build the action without building the scorer. If the Scorer is a cooldown scorer, where the cooldown starts when the action finishes, then the Scorer is not independent of the Action and hence they must be built in tandem.
type Scorer ¶
type Scorer interface { // Attached is called once when the Scorer is first attached to the AI to // let it know which world it is operating in and the actor which the scorer // is determining the utility of the action for. It should store these with // a stricter type. Attached(world, actor interface{}) // Score returns the current measure, typically a 0-1 value where 0 is the // least valuable and 1 is the most valuable. Score() float64 }
A Scorer is something which is capable of producing a measure of utility for something. There is one instance per actor in the world and it is assumed to be stateful.
type ScorerBuilder ¶
type ScorerBuilder interface { // Build a new scorer and return it so it may be attached Build() Scorer }
ScorerBuilder builds Scorer's
func NewBayesScorer ¶
func NewBayesScorer(prior *big.Rat, factors []BayesFactorBuilder) ScorerBuilder
NewBayesScorer produces a ScorerBuilder that has a score of 1 on the action, but the action only succeeds probabilistically. The estimate of the odds of success is prior. Note that prior should NOT be interpreted as a fraction, e.g., 3/5. Instead, it's interpreted such that the numerator is the number of successes and the denominator is the number of failures. so "3/9" should be interpreted as 3 successes to 9 failures. A "1/1" prior means 1 success to 1 failure, aka a 50% chance of success.
func NewFactorQualifier ¶
func NewFactorQualifier(factor float64, scorer ScorerBuilder) ScorerBuilder
NewFactorQualifier creates a new Qualifier that qualifies the score of the child by multiplying it by the given factor.
type ScorerBuilderAndActionBuilder ¶ added in v0.2.0
type ScorerBuilderAndActionBuilder struct { // Action builds actions Action ActionBuilder // Scorer builds scorers Scorer ScorerBuilder }
ScorerBuilderAndActionBuilder merges a scorer and an action. The scorer and action might not be independent.
func (ScorerBuilderAndActionBuilder) Build ¶ added in v0.2.0
func (b ScorerBuilderAndActionBuilder) Build() ScoredAction
Build implements ScoredActionBuilder but only works if the action and scorer are independent. Hence when receiving a ScorerBuilderAndActionBuilder as that type this function should not be called, but this allows receiving a ScorerBuilderAndActionBuilder type asserted as a ScoredActionBuilder, which is convenenient if you want to make a ScoredActionBuilder with an independent Scorer and Action.
type Thinker ¶
type Thinker interface { // Select the index of the child which should be exected from the given // slice of scored actions. Select(children []ScoredAction) int }
Thinker describes the standard Thinker interface which can be wrapped with NewThinkerBuilder to produce an ActionBuilder.
Note that when we use the word "Thinker" in this package we are almost never referring to this interface. We are simply referring to any ActionBuilder which selects which ActionBuilder to delegate to based on its score. The most common way to implement that concept of Thinker is by implementing this interface and using NewThinkerBuilder as the constructor for the ActionBuilder.
Source Files ¶
- action.go
- ai.go
- bayes_scorer.go
- cooldown_qualified_scored_action.go
- factor_qualifier.go
- first_to_score_thinker.go
- fixed_scorer.go
- highest_score_thinker.go
- idle_action.go
- inverter_qualifier.go
- linear_probabilistic_thinker.go
- mult_combine_qualifier.go
- scored_action.go
- scorer.go
- soft_max_probabilistic_thinker.go
- thinker.go