/ src / maze / mz_hamiltonian.scad
mz_hamiltonian.scad
 1  /**
 2  * mz_hamiltonian.scad
 3  *
 4  * @copyright Justin Lin, 2020
 5  * @license https://opensource.org/licenses/lgpl-3.0.html
 6  *
 7  * @see https://openhome.cc/eGossip/OpenSCAD/lib3x-mz_hamiltonian.html
 8  *
 9  **/
10  
11  use <_impl/_mz_hamiltonian_impl.scad>
12  use <mz_square.scad>
13  use <mz_square_initialize.scad>
14  use <mz_square_get.scad>
15  use <../util/set/hashset.scad>
16  use <../util/set/hashset_elems.scad>
17  
18  include <../__comm__/_pt2_hash.scad>
19  
20  function mz_hamiltonian(rows, columns, start = [0, 0], init_cells, seed) =
21      let(
22          init_cells_undef = is_undef(init_cells),
23          r = init_cells_undef ? rows : len(init_cells),
24          c = init_cells_undef ? columns : len(init_cells[0]),
25          cells = mz_square(
26              r, c,
27              init_cells = init_cells,
28              start = start,
29              seed = seed
30          ),
31          all = concat(
32              [
33                  for(row = cells, cell = row)
34                  let(type = mz_square_get(cell, "t"))
35                  each if(type == "TOP_WALL") _top(cell.x, cell.y) else
36                       if(type == "RIGHT_WALL") _right(cell.x, cell.y) else
37                       if(type == "TOP_RIGHT_WALL" || type == "MASK") _top_right(cell.x, cell.y) 
38              ],
39              [for(x = [0:c * 2 - 1]) [x, 0]],
40              [for(y = [0:r * 2 - 1]) [0, y]]
41          ),
42          
43          dot_pts = hashset_elems(
44              hashset(
45                  all, 
46                  hash = _pt2_hash
47              )
48          ),
49          falseRow = [for(c = [0:c * 2]) false],
50          falseM = [for(r = [0:r * 2]) falseRow],
51          dotM = dot_m(dot_pts, len(dot_pts), falseM),
52  
53          path_leng = init_cells_undef ? r * c : 
54              len([for(row = init_cells, cell = row) if(mz_square_get(cell, "t") != "MASK") undef])
55      )
56      _travel(dotM, start * 2, path_leng * 4);