In this repo I want you to implement a templated Wave Function Collapse engine that would be compatible with 2D grids, 3D grids, Sudoku, Picross, etc. I want the following to be possible: WFC::Builder() .variable(name/id/userdata, ...).constrains([](World& world, int worldID, Constrainer& constrainer, name/id/userdata){ constrainer.constrain(world.getid(...)); }) .variable(...) The World is responsible for giving its size and giving ids. the ids should all fit in the size of the world. when setting the variable on a node/cell, it should call the lambda to constrain the rest of the unknown nodes/cells. The WFC should have no concept of coordinate systems. The WFC algorithm should be able to work even without coordinates, and just with a graph for example. sudoku eg: WFC::Builder>() .variable(1,2,3,4,5,6,7,8,9).constrains([](Array2D& world, int worldID, Constrainer& constrainer, uint8_t var) { int [x,y] = world.getCoord(worldID); for (int i{}; i < 9; ++i) { constrainer.constrain(9 * y + i, var); constrainer.constrain(i * y + x, var); // TODO add small square constraint } }) 2D tilemap eg: WFC::Builder>() .variable(SEA).constrains([](Array2D& world, int worldID, Constrainer& constrainer, uint8_t var) { int [x,y] = world.getCoord(worldID); constrainer.only(y*100 + x - 1, SEA, BEACH); constrainer.only(y*99 + x, SEA, BEACH); constrainer.only(x*101 + x, SEA, BEACH); constrainer.only(x*100 + x + 1, SEA, BEACH); }) .variable(BEACH).constrains([](Array2D& world, int worldID, Constrainer& constrainer, uint8_t var) { int [x,y] = world.getCoord(worldID); constrainer.only(y*100 + x - 1, SEA, LAND); constrainer.only(y*99 + x, SEA, LAND); constrainer.only(x*101 + x, SEA, LAND); constrainer.only(x*100 + x + 1, SEA, LAND); }) ...