Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Two ways to build the Pac-Man maze

Build the classic Pac-Man maze from a simple 28 × 31 character map, using CSG and RectLattice. Export both geometries for reuse in future variance reduction notebooks.

Two ways to build the Pac-Man maze
├── 0. Layout
│   ├── Common tile map and dimensions
│   └── Common boundary surfaces
├── 1. Rectangular CSG corridors
│   └── Convert corridor rectangles into OpenMC regions
├── 2. Rectangular lattice
├── 3. Check the two geometries
├── 4. Export
├── 5. Import both exports and check again
└── 6. Plot with OpenMC
    ├── CSG plots
    └── RectLattice plots

The character map is adapted from Pac-Man Parameterized, a text-based reconstruction of the original arcade maze.

  1. Constructive solid geometry (CSG): build long rectangular open corridors and treat the remaining space as walls.

  2. openmc.RectLattice: place just two reusable universes, one for a wall tile and one for an open tile, on a regular grid.

Both approaches describe the same physical volume.

0. Layout

Common tile map and dimensions

The original arcade layout is represented as 28 columns by 31 rows, top row first. The narrowest # wall tile is 100 cm wide. Any other symbol is treated as open space, including the ghost-house doorway; pellets and ghosts are not physical objects.

Geometry dimensions: 2,800 × 3,100 cm in XY, 200 cm in the maze’s z direction, plus a 200 cm slab on each axial side. The bounding volume extends from z = −300 to +300 cm. The origin is at (0, 0, 0).

28 x 31 = 868 tiles
488 wall tiles and 380 open tiles

Common boundary surfaces

We use the same X, Y and Z planes for both constructions. Interior XY planes sit at the edges of the 100 cm tiles; only planes that the region expressions actually reference appear in the exported geometry. Outer surfaces are vacuum. The arcade’s wraparound game mechanic is not modeled as a periodic neutron boundary.

1. Rectangular CSG corridors

This begins with the paths, as one might draw them manually with rectangular boxes. We turn contiguous horizontal runs of open tiles into rectangles, merging runs vertically when their endpoints match. The rectangles do not overlap.

Their union is one open-space cell. The wall cell is the complement of that union inside the maze footprint. Thus, the map does not create a separate transport cell for every tile. This decomposition is easy to follow, though it is not guaranteed to use the fewest possible rectangles.

67 merged corridor rectangles

Convert corridor rectangles into OpenMC regions

The tile map is stored top to bottom, while OpenMC Y increases bottom to top. That is why a rectangle spanning map rows top:bottom uses y_planes[N_ROWS - bottom] and y_planes[N_ROWS - top].

Each rectangle is an intersection of four half-spaces; | joins the rectangles into one open-space region, and ~ describes the complementary walls.

CSG root cells: 4
CSG lattice objects: 0

2. Rectangular lattice

The second construction starts from two prototype universes. The wall universe contains one void-placeholder cell, and the open-space universe contains another. RectLattice arranges those prototypes at all 868 tile positions, with a pitch of 100 cm.

The prototypes are defined once and referenced repeatedly. These are geometry lattice elements, not scoring mesh voxels. They do, however, introduce a regular hierarchy that particle tracking must traverse.

Lattice sites: 868
Prototype universes: Wall tile universe and Open tile universe

3. Check the two geometries

Query the OpenMC geometry objects at the center of every tile. The leaf cell must be wall or open in both representations. We avoid sampling on boundaries, where the mathematical region sense is ambiguous.

Both OpenMC geometries agree with all 868 tile centers.

4. Export

Both files contain void placeholders; material compositions, settings, source, tallies and nuclear data stay in subsequent notebooks.

Exported: pacman_geometry_lattice.xml and pacman_geometry_csg.xml

5. Import both exports and check again

Explicitly pass an empty openmc.Materials() collection when importing geometry-only XML. This prevents OpenMC from looking for a materials.xml at import time.

csg XML imported; cells: 4
lattice XML imported; cells: 5

6. Plot with OpenMC

CSG plots

                                %%%%%%%%%%%%%%%
                           %%%%%%%%%%%%%%%%%%%%%%%%
                        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                                    %%%%%%%%%%%%%%%%%%%%%%%%
                                     %%%%%%%%%%%%%%%%%%%%%%%%
                 ###############      %%%%%%%%%%%%%%%%%%%%%%%%
                ##################     %%%%%%%%%%%%%%%%%%%%%%%
                ###################     %%%%%%%%%%%%%%%%%%%%%%%
                ####################     %%%%%%%%%%%%%%%%%%%%%%
                #####################     %%%%%%%%%%%%%%%%%%%%%
                ######################     %%%%%%%%%%%%%%%%%%%%
                #######################     %%%%%%%%%%%%%%%%%%
                 #######################     %%%%%%%%%%%%%%%%%
                 ######################     %%%%%%%%%%%%%%%%%
                  ####################     %%%%%%%%%%%%%%%%%
                    #################     %%%%%%%%%%%%%%%%%
                     ###############     %%%%%%%%%%%%%%%%
                       ############     %%%%%%%%%%%%%%%
                          ########     %%%%%%%%%%%%%%
                                      %%%%%%%%%%%

                 | The OpenMC Monte Carlo Code
       Copyright | 2011-2026 MIT, UChicago Argonne LLC, and contributors
         License | https://docs.openmc.org/en/latest/license.html
         Version | 0.16.0
     Commit Hash | 617d35a5063c57796b43428bc401e627d2011046
       Date/Time | 2026-11-09 14:06:09
  OpenMP Threads | 16

 Reading settings XML file...
 Reading materials XML file...
 Reading geometry XML file...
 Preparing distributed cell instances...
 Reading plot XML file...

 =======================>     PLOTTING SUMMARY     <========================

Plot ID: 1
Plot file: csg_xy.png
Universe depth: -1
Plot Type: Slice
Origin: 0 0 0
Width: 2800 3100
Coloring: Cells
Basis: XY
Pixels: 280 310

Plot ID: 2
Plot file: csg_xz.png
Universe depth: -1
Plot Type: Slice
Origin: 0 0 0
Width: 2800  600
Coloring: Cells
Basis: XZ
Pixels: 280 60

 Processing plot 1: csg_xy.png...
 Processing plot 2: csg_xz.png...
<IPython.core.display.Image object>
<IPython.core.display.Image object>

RectLattice plots

Now render the lattice geometry in a different OpenMC process and directory. These images should agree with the CSG images at the same resolution.

                                %%%%%%%%%%%%%%%
                           %%%%%%%%%%%%%%%%%%%%%%%%
                        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                                    %%%%%%%%%%%%%%%%%%%%%%%%
                                     %%%%%%%%%%%%%%%%%%%%%%%%
                 ###############      %%%%%%%%%%%%%%%%%%%%%%%%
                ##################     %%%%%%%%%%%%%%%%%%%%%%%
                ###################     %%%%%%%%%%%%%%%%%%%%%%%
                ####################     %%%%%%%%%%%%%%%%%%%%%%
                #####################     %%%%%%%%%%%%%%%%%%%%%
                ######################     %%%%%%%%%%%%%%%%%%%%
                #######################     %%%%%%%%%%%%%%%%%%
                 #######################     %%%%%%%%%%%%%%%%%
                 ######################     %%%%%%%%%%%%%%%%%
                  ####################     %%%%%%%%%%%%%%%%%
                    #################     %%%%%%%%%%%%%%%%%
                     ###############     %%%%%%%%%%%%%%%%
                       ############     %%%%%%%%%%%%%%%
                          ########     %%%%%%%%%%%%%%
                                      %%%%%%%%%%%

                 | The OpenMC Monte Carlo Code
       Copyright | 2011-2026 MIT, UChicago Argonne LLC, and contributors
         License | https://docs.openmc.org/en/latest/license.html
         Version | 0.16.0
     Commit Hash | 617d35a5063c57796b43428bc401e627d2011046
       Date/Time | 2026-11-09 14:06:09
  OpenMP Threads | 16

 Reading settings XML file...
 Reading materials XML file...
 Reading geometry XML file...
 Preparing distributed cell instances...
 Reading plot XML file...

 =======================>     PLOTTING SUMMARY     <========================

Plot ID: 3
Plot file: lattice_xy.png
Universe depth: -1
Plot Type: Slice
Origin: 0 0 0
Width: 2800 3100
Coloring: Cells
Basis: XY
Pixels: 280 310

Plot ID: 4
Plot file: lattice_xz.png
Universe depth: -1
Plot Type: Slice
Origin: 0 0 0
Width: 2800  600
Coloring: Cells
Basis: XZ
Pixels: 280 60

 Processing plot 3: lattice_xy.png...
 Processing plot 4: lattice_xz.png...
<IPython.core.display.Image object>
<IPython.core.display.Image object>