Documentation
¶
Overview ¶
Package cae — фасад над остальными пакетами движка: одна структура Sim, которая держит вместе мир, сетку и правило и умеет всё то, ради чего движок обычно и подключают — прогнать N тиков, прочитать клетку, узнать её цвет.
Пакеты под ним (automaton, world, script, visualrule, goal) остаются полностью самостоятельными: фасад ничего не прячет и ничем не владеет монопольно — все его поля публичные, и в любой момент можно спуститься на уровень ниже и работать с ними напрямую. Он нужен ровно затем, чтобы «просто запустить симуляцию» не требовало знать про разницу между Rule и SequentialRule и про то, что для первого Engine.Step подменяет сетку (см. Sim.Step).
Формата файла проекта здесь нет сознательно. Правило, мир и цель — это обычные структуры с именованными полями, которые сериализуются стандартным encoding/json без чьей-либо помощи; во что их завернуть, куда положить, как версионировать и чем сжать — решает приложение, и движку в этом решении участвовать незачем. Единственное, что ему пришлось предусмотреть, — шов для сетки: её клетки лежат приватно, и наружу они ходят через Grid.Cells/LoadCells (см. examples/rulejson).
Ноль внешних зависимостей: весь движок собирается на одной стандартной библиотеке.
Index ¶
- Constants
- type Sim
- func (s *Sim) At(x, y int) automaton.Cell
- func (s *Sim) ColorAt(x, y int) color.RGBA
- func (s *Sim) KindAt(x, y int) int
- func (s *Sim) Program() *script.Program
- func (s *Sim) RunUntil(g goal.Goal, maxTicks int) (bool, int)
- func (s *Sim) Set(x, y int, c automaton.Cell)
- func (s *Sim) SetKind(x, y int, k int)
- func (s *Sim) Size() (w, h int)
- func (s *Sim) Step()
- func (s *Sim) StepN(n int) int
- func (s *Sim) Tick() uint64
- func (s *Sim) Truncated() bool
- func (s *Sim) VisualRule() *visualrule.VisualRule
Constants ¶
const Version = "0.4.1"
Version — версия движка: того, что считает симуляцию.
Она сознательно НЕ совпадает ни с версией приложения, которое движок подключает, ни с версией формата файла, в котором это приложение сохраняет проекты. Три разные вещи меняются по трём разным поводам, и одно число на всех врало бы про каждую из них:
версия движка меняется, когда меняется поведение симуляции —
новый узел языка, другая семантика тика, новый
контракт правила. Это она;
версия приложения меняется, когда меняется то, что видит человек —
экраны, редактор, уровни. Живёт в приложении, и
движок про неё ничего не знает;
версия формата меняется, когда файл проекта перестаёт читаться
старой сборкой. Живёт там же, где сам формат, то
есть в приложении: своего формата у движка нет.
Нумерация начинается с 0.4.0, а не с нуля: движок не новый, он просто впервые выехал отдельным модулем — до этого он ехал внутри CellEngine и дошёл там до 0.3.x. Начать заново с 0.1.0 значило бы сделать вид, что всей этой истории не было.
Приложению, которое хочет показать обе версии сразу, ничего изобретать не нужно: cae.Version — вот она, а свою оно и так знает.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Sim ¶
type Sim struct {
World *world.World
Grid *automaton.Grid
Engine *automaton.Engine
// Interp — интерпретатор, если симуляция крутит программу (script);
// nil, если правило визуальное. Через него читается LastTick (уложился
// ли тик в бюджет) и выставляются Budget/FPS/CellSize/Mouse.
Interp *script.Interpreter
}
Sim — симуляция целиком: мир (типы клеток, константы, переменные), сетка и правило, которое их связывает.
Поля публичные сознательно: подкрутить константу, добавить тип клетки или дорисовать что-нибудь в сетку между тиками — обычное дело, и заводить на каждое такое действие метод-обёртку не за чем.
ВАЖНО про Grid: у классического правила (visualrule и любой другой automaton.Rule) каждый тик рождает НОВУЮ сетку, поэтому запоминать s.Grid в своей переменной надолго нельзя — после Step это уже прошлый кадр. Сам Sim за этим следит и обновляет своё поле; читать всегда через s.Grid или s.At.
func Life ¶
Life — самый короткий путь к работающей симуляции: Conway's Life на сетке w×h с зацикленными краями. Пригодится, чтобы за один вызов проверить, что библиотека вообще подключилась.
func NewRule ¶
NewRule собирает симуляцию из правила, написанного на Go, — любого типа, реализующего automaton.Rule или automaton.SequentialRule. Мир нужен только для цветов и может быть nil, если правило красит клетки само.
func NewVisualRule ¶
func NewVisualRule(w *world.World, rule *visualrule.VisualRule, g *automaton.Grid) *Sim
NewVisualRule собирает симуляцию из визуального правила.
func (*Sim) At ¶
At — клетка в (x,y). Координаты за краем сетки не паникуют, а разрешаются политикой границы (см. automaton.Grid.At).
func (*Sim) ColorAt ¶
ColorAt — каким цветом клетка (x,y) должна быть нарисована: её собственный цвет, если программа его выставила (SET COLOR), иначе цвет её типа. Ровно то, что нужно, чтобы сложить из сетки картинку, не зная ничего про устройство мира и правила.
func (*Sim) KindAt ¶
KindAt — тип клетки в (x,y) как обычный int (тот же ID, что у world.Kind.ID) — чтобы не приводить типы на каждой строчке разбора результата.
func (*Sim) Program ¶
Program возвращает программу симуляции, если она собрана из script, и nil иначе. Вместе с VisualRule это шов для сохранения: обе структуры — обычные значения с именованными полями, и приложение сериализует их тем, чем сочтёт нужным, безо всякого участия движка.
func (*Sim) RunUntil ¶
RunUntil крутит симуляцию, пока не выполнится условие g, но не дольше maxTicks тиков. Возвращает, выполнилось ли условие, и сколько тиков на это ушло. Условие проверяется и на стартовом кадре тоже (до первого Step) — если оно уже выполнено, ответ (true, 0).
func (*Sim) Step ¶
func (s *Sim) Step()
Step продвигает симуляцию на один тик и подхватывает новую сетку, если правило классическое (см. комментарий к Sim.Grid).
func (*Sim) StepN ¶
StepN прогоняет n тиков. Возвращает, сколько успело пройти: если программа не уложилась в бюджет (см. Truncated), считать дальше бессмысленно — сетка уже в полуобновлённом виде, — и прогон останавливается досрочно.
func (*Sim) Truncated ¶
Truncated — оборвался ли последний тик по исчерпанию бюджета (только для программ; у визуального правила бюджета нет и ответ всегда false). Если true, сетка обновилась не целиком: подробности — в s.Interp.LastTick.
func (*Sim) VisualRule ¶
func (s *Sim) VisualRule() *visualrule.VisualRule
VisualRule возвращает визуальное правило симуляции, если она собрана им, и nil иначе (программа или правило, написанное на Go).
Directories
¶
| Path | Synopsis |
|---|---|
|
Пакет capi — тонкая обёртка над cae.Sim с плоским C-интерфейсом, чтобы движок можно было собрать в разделяемую библиотеку (.dll / .so / .dylib) и дёргать из C, C++, C#, Python, Rust — откуда угодно, где есть FFI.
|
Пакет capi — тонкая обёртка над cae.Sim с плоским C-интерфейсом, чтобы движок можно было собрать в разделяемую библиотеку (.dll / .so / .dylib) и дёргать из C, C++, C#, Python, Rust — откуда угодно, где есть FFI. |
|
examples
|
|
|
crypt
command
Пример: поточный шифр, гаммой которого работает сам клеточный автомат.
|
Пример: поточный шифр, гаммой которого работает сам клеточный автомат. |
|
goalrun
command
Пример: движок как счётная машина, а не как игрушка на экране.
|
Пример: движок как счётная машина, а не как игрушка на экране. |
|
internal/gridimg
Package gridimg складывает из сетки картинку — PNG или анимированный GIF.
|
Package gridimg складывает из сетки картинку — PNG или анимированный GIF. |
|
life
command
Пример: Conway's Life прямо в терминале, без единой картинки.
|
Пример: Conway's Life прямо в терминале, без единой картинки. |
|
rulejson
command
Пример: правило — это данные.
|
Пример: правило — это данные. |
|
visual
command
Пример: симуляция в картинках — PNG отдельных кадров и анимированный GIF.
|
Пример: симуляция в картинках — PNG отдельных кадров и анимированный GIF. |
|
Package goal — декларативные условия на состояние сетки: "клеток типа K не меньше 20", "клетка (5,7) стала стеной", "картинка не менялась 30 тиков", и любые И/ИЛИ из них.
|
Package goal — декларативные условия на состояние сетки: "клеток типа K не меньше 20", "клетка (5,7) стала стеной", "картинка не менялась 30 тиков", и любые И/ИЛИ из них. |
|
Package script реализует небольшой императивный язык для описания поведения клетки: выражения (Expr) произвольной вложенности и последовательности операторов (Stmt) — if/else, ограниченный repeat, return, запись в любую клетку (свою/соседнюю/произвольную по (x,y)), вызов пользовательских методов с параметрами и возвратом значения.
|
Package script реализует небольшой императивный язык для описания поведения клетки: выражения (Expr) произвольной вложенности и последовательности операторов (Stmt) — if/else, ограниченный repeat, return, запись в любую клетку (свою/соседнюю/произвольную по (x,y)), вызов пользовательских методов с параметрами и возвратом значения. |
|
Package visualrule реализует automaton.Rule, чьи правила собираются не в коде, а интерактивно — как последовательность блоков "ЕСЛИ <условия> ТО <команды>", по порядку сверху вниз, первая совпавшая ветка побеждает (как if/elseif/else в Scratch).
|
Package visualrule реализует automaton.Rule, чьи правила собираются не в коде, а интерактивно — как последовательность блоков "ЕСЛИ <условия> ТО <команды>", по порядку сверху вниз, первая совпавшая ветка побеждает (как if/elseif/else в Scratch). |
|
Заглушка для всех платформ, кроме js/wasm: без неё `go build ./...` на обычной машине падал бы с "build constraints exclude all Go files".
|
Заглушка для всех платформ, кроме js/wasm: без неё `go build ./...` на обычной машине падал бы с "build constraints exclude all Go files". |
|
Package world хранит словарь симуляции: список типов клеток (Kind), именованных числовых констант (Constant) и переменных мира (Variable), плюс подписи слотов свойств клетки.
|
Package world хранит словарь симуляции: список типов клеток (Kind), именованных числовых констант (Constant) и переменных мира (Variable), плюс подписи слотов свойств клетки. |