Documentation ¶
Index ¶
- Variables
- func DefaultIsPossibleFunc(state *Module, from, to *Slot, d Direction) bool
- func GetTileFromSpriteSheet(img image.Image, x, y, width, height int) (image.Image, error)
- func HexFromColor(c Color) string
- func LoadImage(file string) (image.Image, error)
- func LoadImageFolder(folder string) ([]image.Image, error)
- func SaveImage(file string, img image.Image) error
- type Color
- type ConstraintFunc
- type ConstraintId
- type Direction
- type IsPossibleFunc
- type Module
- type Slot
- type Wave
- func (w *Wave) Collapse(attempts int) error
- func (w *Wave) CollapseRandomSlot() *Slot
- func (w *Wave) ExportImage() image.Image
- func (w *Wave) GetNeighbor(s *Slot, d Direction) *Slot
- func (w *Wave) GetPossibleModules(a, b *Slot, d Direction) []*Module
- func (w *Wave) GetSlot(x, y int) *Slot
- func (w *Wave) HasNeighbor(s *Slot, d Direction) bool
- func (w *Wave) HasVisited(s *Slot) bool
- func (w *Wave) Initialize(seed int)
- func (w *Wave) IsCollapsed() bool
- func (w *Wave) Recurse() error
Constants ¶
This section is empty.
Variables ¶
var (
ErrNoSolution = errors.New("no possible modules for slot")
)
Functions ¶
func DefaultIsPossibleFunc ¶ added in v0.0.4
DefaultIsPossibleFunc returns whether or not a module is possible given a slot and direction.
func GetTileFromSpriteSheet ¶
GetTileFromSpriteSheet returns a tile from a sprite sheet.
func HexFromColor ¶
func LoadImageFolder ¶
LoadImageFolder loads all images in a directory and returns them as a slice.
Types ¶
type ConstraintFunc ¶
type ConstraintFunc func(image.Image, Direction) ConstraintId
ConstraintFunc is a function that returns an adjacency hash for an image tile in a specified direction.
var DefaultConstraintFunc ConstraintFunc = GetConstraintFunc(3)
The default constraint function uses color values to generate an adjacency.
func GetConstraintFunc ¶ added in v0.0.3
func GetConstraintFunc(count int) ConstraintFunc
GetConstraintFunc returns a constraint function that uses the given number of color lookups
type ConstraintId ¶
type ConstraintId [8]byte
Adjacency constraint type.
This is a an arbitrary value that should be the same between two or more modules. It represents modules that can be next to each other.
This codebase combines 3 color values along the edges of input tiles and then uses sha256 to generate a hash. Only the first 8 bytes are kept.
The color values are reduced to 4 bits each, discarding the least significant bits. This rounds the color values to allow for some flexibility.
func GetConstraintFromHex ¶
func GetConstraintFromHex(s string) ConstraintId
GetConstraintFromHex returns the adjacency constraint id for the given hex
func (ConstraintId) Equal ¶ added in v0.0.3
func (c ConstraintId) Equal(o ConstraintId) bool
Equal returns true if the two adjacency constraints are equal.
type Direction ¶
type Direction int
Direction type, one of Up, Down, Left, Right.
Used to specify the direction of a constraint between two modules.
type IsPossibleFunc ¶ added in v0.0.4
IsPossibleFunc is a function that returns whether or not a module is possible given a slot and direction. Use this if you'd like custom logic.
type Module ¶
type Module struct { Index int // The index of the module in the input tiles Adjacencies [4]ConstraintId // Adjacency constraints for each direction Image image.Image // The tile image for the module }
Module represents a single module in the wave function as described by Oskar Stalberg. A module is a possible tile that might exist at a slot in the wave function grid. It can be thought of as a single state of a superposition.
type Slot ¶
type Slot struct {
X, Y int // Coordinates of the slot
Superposition []*Module // Possible modules at the slot
}
A Slot is a single point in space inside the Wave function. It can be in a superposition of many modules until collapsed.
A Slot that has no superposition (length == 0) is considered to be in a contridiction state. Meaning that the wave function was not able to resolve it.
A Slot that has a single module in its superposition is considered to be a collapsed slot and only has one possible module at its coordinates.
type Wave ¶
type Wave struct {
Width, Height int // Width and height of the grid
Input []*Module // Input tiles (possible tiles at each slot)
PossibilitySpace []*Slot // The 2D grid of slots
History []*Slot // Slots that have been visited during the current/last collapse iteration
// Override this if you'd like custom logic when checking if a state is
// possible from a direction. This is useful if you'd like to slow down the
// collapse or add probabilities.
IsPossibleFn IsPossibleFunc
}
Wave holds the state of a wave collapse function as described by Oskar Stalberg.
The wave is a recursive algorithm that collapses the possibility space of a 2D grid into a single output. Specifically, it is a 2D array of slots that are all in a superposition state of one or more modules; each module is a possible tile that might exist at that slot.
The algorithm is described in detail by Oskar Stalberg at several conferences. It is described in detail during the following talk: https://www.youtube.com/watch?v=0bcZb-SsnrA&t=350s
An example implmentation of the algorithm can be found here: https://oskarstalberg.com/game/wave/wave.html
func New ¶
New creates a new wave collapse function with the given width and height and possible image tiles.
Constraints are automatically generated by looking at the color values of the pixels along each of the four edges of the tile. Any tiles that should potentially be neighbors should have the same color values along the edges. Otherwise, the tile will not be considered a neighbor.
When generating constraints, only 3 pixels per edge are considered. For example, for the top edge, it looks at the top-left, then top-middle, then top-right pixels. likewise for the right edge, it would look at the top-right, then middle-right, then bottom-right.
func NewWithCustomConstraints ¶
func NewWithCustomConstraints(tiles []image.Image, width, height int, fn ConstraintFunc) *Wave
NewWithCustomConstraints creates a new wave collapse function with the given adjacency constraint calculation function. Use this if you'd like custom logic for specifying constraints.
func (*Wave) Collapse ¶
Collapse recursively collapses the possibility space for each slot into a single module.
Important: Not all tile sets will allways produce a solution, so this function can return an error if a contradiction is found. You can still export the image of a failed collapse to see which of your tiles is causing issues for you.
func (*Wave) CollapseRandomSlot ¶
CollapseRandomSlot takes a random slot and collapses it into a single module. If the slot is already collapsed, it will pick another slot and try again.
func (*Wave) ExportImage ¶
Export takes the current state of the wave collapse function and exports it as an image. Any slots that have not been collapsed will be transparent. Contradictions will be red.
func (*Wave) GetNeighbor ¶
GetNeighbor returns the slot in the given direction from the given slot.
func (*Wave) GetPossibleModules ¶
GetPossibleModules returns a list of modules that are possible when traveling from slot "a" to slot "b" with the provided direction.
func (*Wave) HasNeighbor ¶
HasNeighbor checks if the given slot has a neighbor in the given direction (edges of the grid don't have neighbors).
func (*Wave) HasVisited ¶
HasVisited checks if the given slot has been visited during the current collapse iteration. This is used to prevent infinite recursion.
func (*Wave) Initialize ¶
Initialize sets up the wave collapse function so that every slot is in a superposition of all input tiles/modules.
Each module is equally likely to be at each slot.
func (*Wave) IsCollapsed ¶
IsCollapsed checks if the given slot is collapsed. Either in a contradiction state or to a single possible value.