172 lines
4.4 KiB
Racket
172 lines
4.4 KiB
Racket
#lang scheme/gui
|
|
|
|
;;; these come from:
|
|
;;; http://www.ask.ne.jp/~hattori/puzzle/menu.html
|
|
;;; We must cite him in the game somewhere...
|
|
|
|
(define pixel-size 10)
|
|
|
|
(define (main-n n)
|
|
(let ([grid (calculate-grid (build-path 'up "hattori" (format "~a.gif" n)))])
|
|
(display-grid grid)
|
|
(pretty-print
|
|
(build-problem
|
|
n grid))
|
|
(newline)
|
|
(newline (current-error-port))
|
|
(newline (current-error-port))))
|
|
|
|
(define (calculate-grid filename)
|
|
(fprintf (current-error-port) "reading ~a~n" filename)
|
|
(let* ([bitmap (make-object bitmap% filename)]
|
|
[_ (unless (send bitmap ok?)
|
|
(error 'bad-bitmap "name: ~a" filename))]
|
|
[bitmap-dc (make-object bitmap-dc% bitmap)]
|
|
[raw-width (send bitmap get-width)]
|
|
[raw-height (send bitmap get-height)]
|
|
[image-width raw-width]
|
|
[image-height (get-puzzle-height bitmap-dc raw-height)]
|
|
[grid-x-start (get-grid-start bitmap-dc #t)]
|
|
[grid-y-start (get-grid-start bitmap-dc #f)]
|
|
[puzzle-width (- image-width grid-x-start)]
|
|
[puzzle-height (- image-height grid-y-start)]
|
|
[new-bitmap-width (floor (/ (- puzzle-width 1) pixel-size))]
|
|
[new-bitmap-height (floor (/ (- puzzle-height 1) pixel-size))])
|
|
|
|
(begin
|
|
(fprintf (current-error-port) "size of picture: ~a x ~a~n" raw-width raw-height)
|
|
(fprintf (current-error-port) " size of image: ~a x ~a~n" image-width image-height)
|
|
(fprintf (current-error-port) "grid-start (~a, ~a)~n" grid-x-start grid-y-start)
|
|
(fprintf (current-error-port) "size of puzzle: ~a x ~a~n"
|
|
puzzle-width
|
|
puzzle-height))
|
|
(reverse
|
|
(let loop ([j new-bitmap-height])
|
|
(cond
|
|
[(zero? j) null]
|
|
[else
|
|
(cons
|
|
(reverse
|
|
(let loop ([i new-bitmap-width])
|
|
(cond
|
|
[(zero? i) null]
|
|
[else
|
|
(let ([pixel-value
|
|
(if (black-pixel?
|
|
bitmap-dc
|
|
(floor
|
|
(+ grid-x-start
|
|
(* pixel-size (+ i -1 1/2))))
|
|
(floor
|
|
(+ grid-y-start
|
|
(* pixel-size (+ j -1 1/2)))))
|
|
'x
|
|
'o)])
|
|
;(fprintf (current-error-port) "(~a, ~a) is ~a~n" i j pixel-value)
|
|
(cons pixel-value
|
|
(loop (- i 1))))])))
|
|
(loop (- j 1)))])))))
|
|
|
|
(define (display-grid grid)
|
|
(display "+" (current-error-port))
|
|
(for-each (lambda (x) (display "-" (current-error-port))) (car grid))
|
|
(display "+" (current-error-port))
|
|
(newline (current-error-port))
|
|
|
|
(for-each
|
|
(lambda (row)
|
|
(display "|" (current-error-port))
|
|
(for-each
|
|
(lambda (i)
|
|
(if (eq? i 'x)
|
|
(display "#" (current-error-port))
|
|
(display " " (current-error-port))))
|
|
row)
|
|
(display "|" (current-error-port))
|
|
(newline (current-error-port)))
|
|
grid)
|
|
(display "+" (current-error-port))
|
|
(for-each (lambda (x) (display "-" (current-error-port))) (car grid))
|
|
(display "+" (current-error-port))
|
|
(newline (current-error-port)))
|
|
|
|
(define tmp-color (make-object color%))
|
|
|
|
(define (colored-pixel? value)
|
|
(lambda (bitmap-dc x y)
|
|
(send bitmap-dc get-pixel x y tmp-color)
|
|
(= value
|
|
(send tmp-color red)
|
|
(send tmp-color green)
|
|
(send tmp-color blue))))
|
|
|
|
(define white-pixel? (colored-pixel? 255))
|
|
(define black-pixel? (colored-pixel? 0))
|
|
|
|
(define (get-puzzle-height bitmap-dc raw-height)
|
|
(let loop ([i raw-height])
|
|
(cond
|
|
[(white-pixel? bitmap-dc 0 (- i 1))
|
|
(loop (- i 1))]
|
|
[else i])))
|
|
|
|
(define (get-grid-start bitmap-dc x?)
|
|
(let loop ([i 0])
|
|
(cond
|
|
[(if x?
|
|
(white-pixel? bitmap-dc i 0)
|
|
(white-pixel? bitmap-dc 0 i))
|
|
(loop (+ i 1))]
|
|
[else i])))
|
|
|
|
|
|
(define (on-off->blocks l)
|
|
(let loop ([l l]
|
|
[in? #f]
|
|
[size 0])
|
|
(cond
|
|
[(null? l) (if (= size 0)
|
|
null
|
|
(list size))]
|
|
[else
|
|
(let ([on? (eq? (car l) 'x)])
|
|
(cond
|
|
[(and in? on?)
|
|
(loop (cdr l)
|
|
on?
|
|
(+ size 1))]
|
|
[(and in? (not on?))
|
|
(cons size
|
|
(loop (cdr l)
|
|
#f
|
|
0))]
|
|
[(and (not in?) on?)
|
|
(loop (cdr l)
|
|
#t
|
|
1)]
|
|
[(and (not in?) (not on?))
|
|
(loop (cdr l)
|
|
#f
|
|
0)]))])))
|
|
|
|
(define (transpose l) (apply map list l))
|
|
|
|
(define (build-problem n on-off-lists)
|
|
(list (format "Hattori ~a" n)
|
|
(map on-off->blocks on-off-lists)
|
|
(map on-off->blocks (transpose on-off-lists))
|
|
on-off-lists))
|
|
|
|
(provide main)
|
|
(define (main)
|
|
(call-with-output-file "raw-hattori.ss"
|
|
(lambda (port)
|
|
(parameterize ([current-output-port port])
|
|
(printf "`(~n")
|
|
(let loop ([n 1])
|
|
(when (<= n 139)
|
|
(main-n n)
|
|
(loop (+ n 1))))
|
|
(printf ")")))
|
|
#:exists 'truncate))
|