Skip to content

Instantly share code, notes, and snippets.

@coopermayne
Created January 28, 2026 03:11
Show Gist options
  • Select an option

  • Save coopermayne/5f48132e45e19f1b64ebaefb66ec54df to your computer and use it in GitHub Desktop.

Select an option

Save coopermayne/5f48132e45e19f1b64ebaefb66ec54df to your computer and use it in GitHub Desktop.
Two Not Touch - Puzzle JSON to PBM (no stars)
#!/usr/bin/env python3
"""
Converts Two Not Touch puzzle JSON to PBM image (puzzle only, no stars).
Usage:
python3 puzzle_to_pbm.py puzzle.json # outputs puzzle.pbm
python3 puzzle_to_pbm.py puzzle.json -o output.pbm # custom output path
python3 puzzle_to_pbm.py < puzzle.json > output.pbm # stdin/stdout
cat puzzle.json | python3 puzzle_to_pbm.py # pipe
"""
import json
import sys
import argparse
from typing import List
GRID_SIZE = 10
def create_puzzle_pbm(regions: List[List[int]], cell_size: int = 30,
border_width: int = 4, grid_line_width: int = 1) -> str:
"""
Create PBM image data for puzzle grid (no stars).
Returns PBM as a string.
"""
grid_size = len(regions)
img_size = grid_size * cell_size + border_width
# Initialize white image (0 = white, 1 = black)
pixels = [[0] * img_size for _ in range(img_size)]
# Draw outer border (thick)
for i in range(img_size):
for b in range(border_width):
pixels[b][i] = 1 # Top
pixels[img_size - 1 - b][i] = 1 # Bottom
pixels[i][b] = 1 # Left
pixels[i][img_size - 1 - b] = 1 # Right
# Draw cell boundaries
for r in range(grid_size):
for c in range(grid_size):
cell_top = r * cell_size + border_width // 2
cell_left = c * cell_size + border_width // 2
cell_bottom = cell_top + cell_size
cell_right = cell_left + cell_size
# Right edge of cell
if c < grid_size - 1:
is_region_border = regions[r][c] != regions[r][c + 1]
line_width = border_width if is_region_border else grid_line_width
line_x = cell_right - line_width // 2
for y in range(cell_top, cell_bottom):
for w in range(line_width):
if 0 <= line_x + w < img_size and 0 <= y < img_size:
pixels[y][line_x + w] = 1
# Bottom edge of cell
if r < grid_size - 1:
is_region_border = regions[r][c] != regions[r + 1][c]
line_width = border_width if is_region_border else grid_line_width
line_y = cell_bottom - line_width // 2
for x in range(cell_left, cell_right):
for w in range(line_width):
if 0 <= x < img_size and 0 <= line_y + w < img_size:
pixels[line_y + w][x] = 1
# Build PBM string
lines = ["P1", f"{img_size} {img_size}"]
for row in pixels:
lines.append(" ".join(str(p) for p in row))
return "\n".join(lines) + "\n"
def main():
parser = argparse.ArgumentParser(
description="Convert Two Not Touch puzzle JSON to PBM image"
)
parser.add_argument("input", nargs="?", help="Input JSON file (default: stdin)")
parser.add_argument("-o", "--output", help="Output PBM file (default: stdout or input.pbm)")
parser.add_argument("--cell-size", type=int, default=30, help="Cell size in pixels (default: 30)")
parser.add_argument("--border-width", type=int, default=4, help="Region border width (default: 4)")
args = parser.parse_args()
# Read input
if args.input:
with open(args.input, 'r') as f:
data = json.load(f)
else:
data = json.load(sys.stdin)
# Get puzzle (support both 'puzzle' and 'regions' keys for compatibility)
regions = data.get('puzzle') or data.get('regions')
if not regions:
print("Error: JSON must contain 'puzzle' or 'regions' key", file=sys.stderr)
sys.exit(1)
# Generate PBM
pbm_data = create_puzzle_pbm(regions, args.cell_size, args.border_width)
# Write output
if args.output:
with open(args.output, 'w') as f:
f.write(pbm_data)
print(f"PBM saved to: {args.output}", file=sys.stderr)
elif args.input and not sys.stdin.isatty():
# Input file provided but also piped - write to stdout
sys.stdout.write(pbm_data)
elif args.input:
# Input file provided, derive output name
output_path = args.input.rsplit('.', 1)[0] + '.pbm'
with open(output_path, 'w') as f:
f.write(pbm_data)
print(f"PBM saved to: {output_path}", file=sys.stderr)
else:
# stdin input, stdout output
sys.stdout.write(pbm_data)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment