{"id":27948600,"url":"https://github.com/cryptocode/amazig","last_synced_at":"2025-05-07T14:59:38.463Z","repository":{"id":272046889,"uuid":"822145934","full_name":"cryptocode/amazig","owner":"cryptocode","description":"Maze generator based on the Origin Shift algorithm","archived":false,"fork":false,"pushed_at":"2025-03-07T18:22:46.000Z","size":11,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-07T14:59:31.599Z","etag":null,"topics":["gamedev","maze","maze-generator","origin-shift","zig","zig-package"],"latest_commit_sha":null,"homepage":"","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cryptocode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-30T12:04:23.000Z","updated_at":"2025-03-12T17:46:13.000Z","dependencies_parsed_at":"2025-01-11T18:24:22.265Z","dependency_job_id":"fe67225e-6a15-4c16-b9d0-8305b1c559cf","html_url":"https://github.com/cryptocode/amazig","commit_stats":null,"previous_names":["cryptocode/amazig"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cryptocode%2Famazig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cryptocode%2Famazig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cryptocode%2Famazig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cryptocode%2Famazig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cryptocode","download_url":"https://codeload.github.com/cryptocode/amazig/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252902602,"owners_count":21822258,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gamedev","maze","maze-generator","origin-shift","zig","zig-package"],"created_at":"2025-05-07T14:59:38.014Z","updated_at":"2025-05-07T14:59:38.444Z","avatar_url":"https://github.com/cryptocode.png","language":"Zig","readme":"**amazig** is a non-allocating library for generating perfect mazes for games and puzzles, using the \nOrigin Shift algorithm. A perfect maze is one where you can pick any pair of positions and \nbe guaranteed that these two positions are joined by a unique path. Such a maze\nis a minimum spanning tree, and it is thus free of loops and isolated areas.\nYou can still add such features using the generated maze as the starting point.\n\n\u003cimg width=\"300\" alt=\"image\" src=\"https://github.com/user-attachments/assets/bb56d5de-80f0-4478-9aa0-9caf297fc1f2\" /\u003e\n\n## The Origin Shift algorithm\nThe Origin Shift algorithm was discussed in a January 2024 video by [CaptainLuma](https://www.youtube.com/watch?v=zbXKcDVV4G0), and\nturns out to be a rediscovery of an algorithm described in a 1988 [paper](https://people.eecs.berkeley.edu/~ananth/1987-1989/MC_TreeTheorem.pdf)\non Markov chains by V. Anantharam. It's been noted that Origin Shift is essentially the Aldous-Broder algorithm in reverse.\n\nThe key property of Origin Shift is that the starting point is an already perfect maze, and every iteration produces a new perfect maze.\nDuring the maze generation, we thus never have to ask if the maze is complete - it always is! However, since we usually start with a trivial\nmaze we still run the algorithm steps quite a few times to make the maze look good.\n\n### Seeding the maze\nThe fact that a perfect maze generator requires a perfect maze to begin with might be the reason\nwhy it took so long for someone to consider this approach. However, a baseline perfect maze is trivial \nto contruct programmatically, regardless of size.\n\nThe initial maze is by convention one with the origin at the lower-right corner. Every\nnode points to its right neighbor, except for the last one on each row, which points to\nits neighbor below.\n\nFor a 25 by 12 maze, the initial state looks like this:\n``` \n →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  ↓\n →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  ↓\n →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  ↓\n →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  ↓\n →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  ↓\n →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  ↓\n →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  ↓\n →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  ↓\n →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  ↓\n →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  ↓\n →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  ↓\n →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  →  O\n```\n\n*Any initial perfect maze will do, and in some cases it may make sense to start off\nwith a pre-selected perfect maze, and then perhaps mutate it per some rules. This can\nlead to some fun game ideas.*\n\nYou should be able to convince yourself that wherever you start navigating in this maze,\nyou'll end up at the origin. The simple maze mutation algorithm below maintains\nthis property no matter how often you iterate:\n\n* Point the current origin to a neighbor in any random direction\n* Make the selected neighbor point to nothing, thus also making it the new origin\n\nThe direction can be picked by any means, but a good PRNG is usually used.\n\nAfter a number of iterations, the maze paths may look something like this:\n\n```\n →  ↓  ←  ↓  ↓  ←  ↓  ←  ←  ↓  →  →  ↓  ←  ←  →  →  ↓  →  ↓  ←  ←  ←  ←  ←\n ↓  →  ↓  →  ↓  ↓  ↓  ↑  →  →  ↓  ↑  ↓  ←  ↓  ↑  ←  ↓  ↓  ↓  ↑  ↑  ←  ↑  ←\n →  ↑  ↓  →  →  →  →  ↓  ↑  ←  →  ↑  →  →  ↓  ↑  ↑  ↓  ←  ←  ←  ↓  ↑  ←  ↑\n →  ↓  →  →  →  ↑  ↑  →  ↓  →  ↓  ↓  ←  →  →  ↑  →  ↓  ←  ←  ↓  ←  ↑  ↑  ↑\n ↑  ↓  →  →  ↑  ↓  →  ↑  O  ↑  →  ↓  ↑  ←  ←  ←  ↓  ←  ↓  ↑  ←  ←  →  ↑  ←\n ↑  →  ↓  ↑  ↑  ←  →  ↑  ↑  ←  ←  ←  →  ↑  ←  →  →  →  ↓  ←  ↑  →  ↑  ↑  ←\n ↑  ↑  ↓  →  →  ↑  ←  ←  ↑  →  ↓  ↑  →  ↑  ←  ←  ←  ←  ←  ↓  →  →  →  ↑  ↑\n ↑  ↓  ←  ↑  ↑  ↓  ←  ←  ↑  ↓  ↓  ↑  ↑  ←  ↓  ↑  →  ↑  ←  ↓  ↑  ↓  ↑  →  ↑\n ↑  →  →  ↑  ←  ↓  ←  ←  ↑  ←  →  ↓  ↑  ←  →  ↑  ↓  ↓  ←  →  →  →  →  ↑  ←\n →  →  ↑  ↓  →  ↓  →  ↓  ↓  ↑  ↓  →  ↓  ↑  →  ↑  →  ↓  →  ↑  →  ↓  ↑  ↑  ↓\n ↑  →  ↑  ←  ←  ←  ←  ←  ←  ↑  ↓  ↓  →  ↑  ←  ←  →  →  ↑  ↑  ←  →  →  ↑  ←\n →  ↑  ↑  ↑  ←  ←  ←  ←  ↑  ↑  ←  →  ↑  →  ↑  ←  ↑  ↑  ←  ←  ↑  ←  ←  ←  ←\n```\n\nPick any arrow at random and follow the path. You'll eventually end up at the origin.\n\nNote that we're generating the *paths* here, not the walls. The library does, however,\noffer a \"wallified API\" to make it easy to render mazes for games and puzzles.\n\nOrigin Shift is not the most time-efficient maze generator, though for typical maze sizes used in\ngames and puzzles this is unlikely to be an issue. For mazes that don't change at runtime, you can also pre-generate\nthe maze either through tooling or at compile-time.\n\nOrigin Shift is a simple algorithm which allows for mazes to mutate at runtime.\nThis might be handy in certain games and puzzles.\n\nMoreover, the generated maze have directed edges for every single position already pointing towards the\norigin, which may represent an exit or a final destination on a level (or you can completely ignore the origin after maze generation)\n\n### Representation in memory\nThe maze is represented as a simple row-major u32 slice of size `rows * columns` where each item is the offset to\nthe neighbor it points to. This is all the memory ever needed by the library, and the buffer is provided by the library user.\n\nIf needed, you can convert this representation into whatever suits your project.\n\n## Using the library\nThe library requires Zig 0.14 \n\nUse `zig fetch --save \u003curl\u003e` to update your zon file. Alternatively, just copy `lib-amazig.zig` to your\nproject, as it's self-contained.\n\nA simple example is included which animates the generation. Simply run `zig build run`. This example also shows how\nto use the wallified API, which makes it trivial to draw the walls and paths without additional memory.\n\nThe library does not allocate, so it's up to you to provide a backing buffer for the maze paths. This can\nbe heap allocated or a static buffer.\n\nTo generate a new maze, call `init`. Supply a random number generator of your choice, the number of rows and columns,\nand optionally the initial number of iterations. If this is null, then a heuristic default is used. If you supply 0 iterations, then you\ncan can call `iterate` or `iterateOnce` yourself any number of times.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcryptocode%2Famazig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcryptocode%2Famazig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcryptocode%2Famazig/lists"}