62 lines
2.2 KiB
Racket
62 lines
2.2 KiB
Racket
#lang racket
|
|
|
|
(struct Hex (x y letter clicked?) #:mutable #:transparent)
|
|
|
|
(define hexes
|
|
(let* ([A (char->integer #\A)]
|
|
[letters (take (shuffle (map (compose string integer->char)
|
|
(range A (+ A 26))))
|
|
20)])
|
|
(for*/list ([row 4] [column 5])
|
|
(Hex (* 3/2 column) (* 2 (+ row (if (odd? column) 1/2 0)))
|
|
(list-ref letters (+ (* 5 row) column))
|
|
false))))
|
|
|
|
(require 2htdp/image)
|
|
(define (blank width height) (rectangle width height 'outline (color 0 0 0 0)))
|
|
|
|
(define (hexagon mode color) (regular-polygon 1 6 mode color))
|
|
(define aspect-ratio (sin (/ pi 3)))
|
|
|
|
(define (board _)
|
|
(scale 100
|
|
(for/fold ([the-board (blank 8 (* aspect-ratio 9))])
|
|
([hex hexes])
|
|
(define-values (letter-color hex-color)
|
|
(if (Hex-clicked? hex) (values 'black 'purple) (values 'red 'yellow)))
|
|
(underlay/align/offset
|
|
'left 'top the-board
|
|
(Hex-x hex) (* aspect-ratio (Hex-y hex))
|
|
(overlay (scale 1/10 (text (Hex-letter hex) 10 letter-color))
|
|
(hexagon 'outline 'black)
|
|
(hexagon 'solid hex-color))))))
|
|
|
|
#| Closest hex in hexes to x y, as one with minimum distance to its center. |#
|
|
(define (hex-at x y)
|
|
(argmin (λ (hex) (+ (sqr (- x (* 100 (add1 (Hex-x hex)))))
|
|
(sqr (- y (* aspect-ratio 100 (add1 (Hex-y hex)))))))
|
|
hexes))
|
|
|
|
(define letters-chosen '())
|
|
(define (choose hex)
|
|
(set-Hex-clicked?! hex true)
|
|
(define letter (Hex-letter hex))
|
|
(when (not (member letter letters-chosen))
|
|
(set! letters-chosen (list* (Hex-letter hex) letters-chosen))))
|
|
|
|
(require 2htdp/universe)
|
|
(void (big-bang
|
|
(void)
|
|
[to-draw board]
|
|
[stop-when (λ (_) (andmap Hex-clicked? hexes)) board]
|
|
[on-key (λ (_ k)
|
|
(define hex (findf (λ (hex) (key=? k (string-downcase (Hex-letter hex))))
|
|
hexes))
|
|
(when hex (choose hex)))]
|
|
[on-mouse (λ (_ x y event-type)
|
|
(when (equal? "button-down" event-type)
|
|
(choose (hex-at x y))))]))
|
|
|
|
(displayln "The letters were chosen in the order:")
|
|
(for-each display (add-between (reverse letters-chosen) " "))
|