# Generators

A generator, as we use it, is a class that has a `Next`

method that always gives you an object of a certain type. They
work a bit like random generators, except the elements may or may not be random. They support various LINQ-like methods,
and so also resemble sequences (although generators are always infinite). Generators are designed to be used for
procedural content generation. All non-deterministic generators have overloads that take a seed, so you can use
deterministic versions to ensure consistent results for different players if you need it.

There are a few “primitive” generators that you can construct directly with the various static methods in the Generator class. These include:

Generator | Description |
---|---|

Constant | A generator that always generates the same element. |

Count | A generator generates the sequence 0, 1, 2, 3, ..., n, 0, 1, 2, forever. |

Repeat | A generator that generates the elements of a given list repeatedly in sequence. |

Iterate | A generator that applies a given function to the last k elements to generate the next one. |

OpenSawTooth | A generator that generates evenly spaced numbers in a range, excluding the upper limit. |

ClosedSawTooth | A generator that generates evenly spaced floatsin a range, inccluding both limits. |

FromFunc | A generator that generates elements using a given function. Useful to get a generator from something that already behaves like a generator. |

(There are Choose generators that are technically primitive but, since some of their overloads are not primitive, they are listed below)

There are also various random number and bool generators:

Generator | Description |
---|---|

RandomBoolGenerator | A generator that generates random booleans, given a probability of being true. |

Poisson | A generator that generates booleans so `true` occurs uniformly witin a specified range. |

UniformRandomInt | A generator that generates random integers uniformly distributed between 0 and a given number. |

UniformRandomFloat | A generator that generates random floats uniformly distributed between 0 and 1. |

FrequencyRandomInt | A generator that generates random integers with a given frequency distribution. |

GaussianRandomFloat | A generator that generates random floats with a Gaussian distribution. |

MarkovRandomInt, MarkovRandomIntStartsWith | A generator that generates random integers with a given Markov chain. |

UniformVector2InRect | A generator that generates random vectors uniformly distributed in a rectangle. |

UniformVector2InCircle | A generator that generates random vectors uniformly distributed in a circle. |

There are several methods that manipulate and combine them to make more interesting generators.

Method | Description |
---|---|

Where | Generates only elements from a source generator that satisfy a predicate. |

WhereWindow | Generates only elements from a source geerator where the last n elements of the source satisfy a predicate. |

Select | Transforms the elements of a source generator and generates the transformed copies. |

Cast | Casts the elements of a source generator to a different type. |

SelectMany | Generates ele,ents from lists generated by the sources |

Aggregate | Uses a function to combine elements of a source generator generated so far into into a single element. |

Sum | Sums the elements of a source generator. |

Average | Averages the elements of a source generator. |

Choose | A generator that uses an integer generator to select from a list of objects or generators. |

ChooseUniformRandom | A generator that selects from a list of objects or generators with equal probability. |

Group | Groups elements of a source generator, and generates the groups. |

Combine | Uses several source generators to generate parameters for a function. |

RepeatEach | Uses a source generator, and repeats each generated element several times. |

Interleave | Interleaves elements of several source generators. |

Pad | Pads a source generator with a given element or list of elements. |

Interpolate | Generates elements by interpolating between elements a source generators. |

InterpolateDither | Generates elements by interpolating between elements a source generators, with dithering. |

Iterate | Generates elements by re-applying a function to one or more initial elements. |

SwitchWhen | Switches to a new generator when a condition is met. |

SwitchAfter | Switches to a new generator after a certain number of elements have been generated. |

For a full list of all the generators and methods that can manipulate them, see Generator.

Here are some simple examples:

```
var generator = Generator
.RamdomUniformInt(500)
.Select(x => 2*x); //Generates random even numbers between 0 and 998
var generator = Generator
.RandomUniformInt(1000)
.Where(n => n % 2 == 0); //Same as above
var generator = Generator
.Iterate(1, 1, (m, n) => m + n); //Fibonacci numbers
var generator = Generator
.RandomUniformInt(2)
.Select(n => 2*n - 1)
.Aggregate((m, n) => m + n); //Random walk using steps of 1 or -1 one randomly
var generator = Generator
.Iterate(0, Generator.RandomUniformInt(4), (m, n) => m + n - 1)
.Where(n >= 0); //A random sequence that increases on average
```

In each case, elements are only being produced each time you call the Next method or one of its variants. Most calculations are done lazily, so the bulk of the processing is spread over getting the elements and most generators don’t required much memory.

To debug Generators, you can use the Log method to transform a generator into one that will log each element it generates.

There are also some other methods useful when working with generators:

Method | Description |
---|---|

Apply | Applies an action to the elements of a source generator. |

Next<TSource>(IGenerator<TSource>, int) | Gets the next n elements from a generator. |

NextWhile | Gets the next elements from a generator while a predicate is true. |

Skip | Skips the first n elements from a generator. |

SkipAndTake | Skips the first n elements from a generator and then takes the next m elements. |

TakeAndSkip | Takes the first n elements from a generator and then skips the next m elements. |

Generators are useful in creating procedural content, or alter properties of game entities (such as their strength) procedurally. A place where you want to use randomness is the ideal candidate, especially when you want to inject some order to make the playable experience more interesting or coherent.

Here are some examples of what things generators can generate (taken from games we have built):

- sky colors that change over time
- scene decoration next to an infinite road
- obstacle patterns
- AI movement
- game difficulty
- random interesting paths
- letters that have a good chance to make words