package maze import ( "fmt" "image" "image/color" "image/png" "os" ) var ( // DefaultWallColor is used for wall cells. DefaultWallColor = color.RGBA{R: 0, G: 0, B: 0, A: 255} // DefaultPathColor is used for open maze cells. DefaultPathColor = color.RGBA{R: 255, G: 255, B: 255, A: 255} // DefaultSolutionColor is used to highlight solution cells. DefaultSolutionColor = color.RGBA{R: 0, G: 180, B: 0, A: 255} ) // RenderOptions controls how a maze image is rendered. type RenderOptions struct { Scale int WallColor color.RGBA PathColor color.RGBA SolutionColor color.RGBA HighlightPath bool } // DefaultRenderOptions returns baseline rendering options. func DefaultRenderOptions() RenderOptions { return RenderOptions{ Scale: 5, WallColor: DefaultWallColor, PathColor: DefaultPathColor, SolutionColor: DefaultSolutionColor, HighlightPath: false, } } // RenderImage converts a maze grid into an RGBA image. // // If options.HighlightPath is true, Solve is used and solution cells are painted // with options.SolutionColor. func RenderImage(grid Grid, options RenderOptions) (*image.RGBA, error) { width, height, err := validateGrid(grid) if err != nil { return nil, err } if options.Scale <= 0 { return nil, fmt.Errorf("scale must be greater than zero") } img := image.NewRGBA(image.Rect(0, 0, width*options.Scale, height*options.Scale)) var solutionPath [][]bool if options.HighlightPath { solutionPath, err = Solve(grid) if err != nil { return nil, err } } for cellY := 0; cellY < height; cellY++ { startY := cellY * options.Scale for cellX := 0; cellX < width; cellX++ { startX := cellX * options.Scale pixel := options.WallColor if grid[cellY][cellX] == 1 { pixel = options.PathColor if options.HighlightPath && solutionPath[cellY][cellX] { pixel = options.SolutionColor } } for dy := 0; dy < options.Scale; dy++ { row := img.Pix[(startY+dy)*img.Stride:] for dx := 0; dx < options.Scale; dx++ { offset := (startX + dx) * 4 row[offset+0] = pixel.R row[offset+1] = pixel.G row[offset+2] = pixel.B row[offset+3] = pixel.A } } } } return img, nil } // SavePNG renders a maze image and writes it to a PNG file. func SavePNG(grid Grid, outputPath string, options RenderOptions) error { img, err := RenderImage(grid, options) if err != nil { return err } f, err := os.Create(outputPath) if err != nil { return err } defer f.Close() return png.Encode(f, img) }