public L2Maze(L1Maze maze)
        {
            // a root is a start point, key or door
            var roots = maze.StartPositions.Concat(maze.Keys.Keys.Concat(maze.Doors.Keys)).ToList();

            // assign an integer value to each root
            var indexMap = roots.Select((root, index) => (root, index)).ToDictionary(t => t.root, t => t.index);

            NeighborLookup = roots.Select(r => FindNeighbors(maze, r, indexMap)).ToArray();
            AllKeys        = maze.AllKeys;
            StartPositions = maze.StartPositions.Select(s => indexMap[s]).ToArray();
        }
 Neighbor[] FindNeighbors(L1Maze maze, (int, int) position, Dictionary <(int, int), int> indexMap)