goap

package module
v0.0.0-...-e959537 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 12, 2023 License: MIT Imports: 7 Imported by: 0

README

kelindar/goap
Go Version PkgGoDev Go Report Card License Coverage

GOAP: Goal-Oriented Action Planning in Go

GOAP, standing for Goal-Oriented Action Planning, is a library developed in Go, designed to facilitate the creation of plans to achieve specific goals. Its primary application is in AI planning for areas such as game development, robotics, and other fields requiring complex decision-making. GOAP combines the simplicity of Go with the complexity of action planning, making it a practical tool for developers in need of reliable AI solutions.

Key Features

  1. High Performance: This library is built with performance in mind, ensuring it can handle real-time decision-making efficiently and with minimal overhead.

  2. Simple Interface: This library is designed to be easy to use, with a simple interface that allows you to define actions and goals with minimal code.

  3. Supports Various State Types: With support for both numeric and symbolic states, this library can be applied to a wide range of problems and use cases. This allows you to define states such as food=10 or !food (no food).

  4. A* Search: Utilizing the A* algorithm, the library efficiently navigates through possible plans, aiding in finding optimal paths to achieve goals. It uses the state distance heuristic to determine the best plan.

GOAP's blend of efficiency, flexibility, and practical search capabilities makes it a valuable tool for developers looking to incorporate advanced planning and decision-making into their AI applications.

Quick Start

This guide will walk you through implementing a simple AI using the GOAP (Goal-Oriented Action Planning) library. We'll create a scenario where an AI character must manage hunger and tiredness while gathering food. Our AI character starts with high hunger and no food. The goal is to accumulate food (food>80) while managing hunger and tiredness.

Step 1: Initialize States

Start by defining the initial state (init) and the goal (goal):

init := goap.StateOf("hunger=80", "!food", "!tired")
goal := goap.StateOf("food>80")
  • init represents the AI's starting condition: hunger at 80, no food, and not tired.
  • goal is the desired state where the AI has more than 80 units of food.

Step 2: Define Actions

Define the actions the AI can perform: eat, forage, and sleep. Each action has prerequisites and outcomes. First, we need to implement the Action interface. For simplicity, we create a generic action:

// NewAction creates a new action from the given name, require and outcome.
func NewAction(name, require, outcome string) *Action {
	return &Action{
		name:    name,
		require: goap.StateOf(strings.Split(require, ",")...),
		outcome: goap.StateOf(strings.Split(outcome, ",")...),
	}
}

// Action represents a single action that can be performed by the agent.
type Action struct {
	name    string
	cost    int
	require *goap.State
	outcome *goap.State
}

// Simulate simulates the action and returns the required and outcome states.
func (a *Action) Simulate(current *goap.State) (*goap.State, *goap.State) {
	return a.require, a.outcome
}

// Cost returns the cost of the action.
func (a *Action) Cost() float32 {
	return 1
}

Next, we can define a list of actions that the AI can perform (eat, forage, and sleep).

actions := []goap.Action{
    NewAction("eat", "food>0", "hunger-50,food-5"),
    NewAction("forage", "tired<50", "tired+20,food+10,hunger+5"),
    NewAction("sleep", "tired>30", "tired-30"),
}
  • eat: Can be performed if food>0. Reduces hunger by 50 and food by 5.
  • forage: Possible when tired<50. Increases tiredness by 20, food by 10, and hunger by 5.
  • sleep: Executable if tired>30. Reduces tiredness by 30.

Step 3: Generate the Plan

Generate a plan to reach the goal from the initial state using the defined actions.

plan, err := goap.Plan(init, goal, actions)
if err != nil {
    panic(err)
}

The output will be a sequence of actions that the AI character needs to perform to achieve its goal. Here's an example:

1. forage
2. forage
3. forage
4. sleep
5. forage
6. sleep
7. forage
8. forage
9. sleep
10. forage
11. sleep
12. forage
13. eat
14. forage

This sequence represents the AI's decision-making process, balancing foraging for food, eating to reduce hunger, and sleeping to manage tiredness.

License

This library is licensed under the MIT license. See the LICENSE file in the project root for more details.

Credits

This library is developed and maintained by Roman Atachiants and contributions from the open-source community. We welcome contributions and feedback to make the library even better.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Action

type Action interface {

	// Simulate returns requirements and outcomes given the current
	// state (model) of the world.
	Simulate(current *State) (require, outcome *State)

	// Cost returns the cost of performing the action.
	Cost() float32
}

Action represents an action that can be performed.

func Plan

func Plan(start, goal *State, actions []Action) ([]Action, error)

Plan finds a plan to reach the goal from the start state using the provided actions.

type State

type State struct {
	// contains filtered or unexported fields
}

State represents a state of the world.

func StateOf

func StateOf(rules ...string) *State

StateOf creates a new state from a list of keys.

func (*State) Add

func (s *State) Add(rule string) error

Add adds a key to the state.

func (*State) Apply

func (s *State) Apply(effects *State) error

Apply adds (applies) the keys from the effects to the state.

func (*State) Clone

func (s *State) Clone() *State

Clone returns a clone of the state.

func (*State) Del

func (s *State) Del(rule string) error

Del removes a key from the state.

func (*State) Distance

func (state *State) Distance(goal *State) (diff float32)

Distance estimates the distance to the goal state.

func (*State) Equals

func (s *State) Equals(other *State) bool

Equals returns true if the state is equal to the other state.

func (*State) Hash

func (s *State) Hash() (h uint32)

Hash returns a hash of the state.

func (*State) Len

func (s *State) Len() int

Len returns the number of elements in the state.

func (*State) Less

func (s *State) Less(i, j int) bool

Less reports whether the element with index i should sort before the element with index j.

func (*State) Match

func (state *State) Match(needs *State) (bool, error)

Match checks if the State satisfies all the rules of the other state.

func (*State) String

func (s *State) String() string

String returns a string representation of the state.

func (*State) Swap

func (s *State) Swap(i, j int)

Swap swaps the elements with indexes i and j.

Directories

Path Synopsis
example

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL