Advertisement
Guest User

Untitled

a guest
Sep 23rd, 2019
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.05 KB | None | 0 0
  1. (use-modules (oop goops)
  2. (srfi srfi-1) ;; sane lists
  3. (srfi srfi-26) ;; cut
  4. (srfi srfi-42) ;; list comprehension
  5. (srfi srfi-69) ;; hash-table
  6. (srfi srfi-88)) ;; keywords
  7.  
  8. ;; Upper lambda as an alias for "cut"
  9. (define-syntax Λ (identifier-syntax cut))
  10.  
  11. ;; sane name for "null?"
  12. (define empty? null?)
  13.  
  14. (define-method (sample (lst <list>))
  15. (if (empty? lst)
  16. #f
  17. (list-ref lst (random (length lst)))))
  18.  
  19. (define-method (sample . args)
  20. (sample args))
  21.  
  22. (define-method (chance (fraction <number>))
  23. (< (random:uniform) fraction))
  24.  
  25. (define-method (size (self <string>)) (string-length self))
  26. (define-method (size (self <list>)) (length self))
  27. ;;(define-method (size (self <srfi-69:hash-table>)) (hash-table-size self))
  28.  
  29. ;; Cell
  30. (define-class <cell> ()
  31. (row init-keyword: #:row getter: row)
  32. (col init-keyword: #:col getter: col)
  33. (north init-value: #f accessor: north)
  34. (south init-value: #f accessor: south)
  35. (west init-value: #f accessor: west)
  36. (east init-value: #f accessor: east)
  37. (links init-form: (make-hash-table eq?)))
  38.  
  39. (define-generic link)
  40.  
  41. (define-method (link (first <cell>) (second <cell>))
  42. (hash-table-set! (slot-ref first 'links) second #t)
  43. (hash-table-set! (slot-ref second 'links) first #t))
  44.  
  45. ;; If any of them are not cells, just ignore
  46. (define-method (link first second) #f)
  47.  
  48.  
  49. (define-method (link? (first <cell>) (second <cell>))
  50. (hash-table-exists? (slot-ref first 'links) second))
  51.  
  52. (define-method (link? first second) #f)
  53.  
  54.  
  55. (define-method (unlink (first <cell>) (second <cell>))
  56. (hash-table-delete! (slot-ref first 'links) second)
  57. (hash-table-delete! (slot-ref second 'links) first))
  58.  
  59. (define-method (links (self <cell>))
  60. (hash-table-keys (slot-ref self 'links)))
  61.  
  62. (define-method (neighbors (self <cell>))
  63. (filter-map (Λ <> self) (list north south west east)))
  64.  
  65.  
  66. (define-method (carve (proc <accessor>) (cell <cell>))
  67. (link cell (proc cell))
  68. cell)
  69.  
  70. ;; No cell, no carving
  71. (define-method (carve (proc <accessor>) anything)
  72. anything)
  73.  
  74.  
  75. (define-method (display (self <cell>) port)
  76. (format port "[~a ~a]" (row self) (col self)))
  77.  
  78. (define-method (write (self <cell>) port)
  79. (format port "<cell> row: ~a col: ~a" (row self) (col self)))
  80.  
  81. (define-method (show (self <cell>))
  82. (define (pass . directions)
  83. (and-map (λ (f) (link? self (f self))) directions))
  84. (cond
  85. [(pass north south west east) "╬"]
  86. [(pass north south west ) "╣"]
  87. [(pass north south east) "╠"]
  88. [(pass north west east) "╩"]
  89. [(pass south west east) "╦"]
  90. [(pass north west ) "╝"]
  91. [(pass north east) "╚"]
  92. [(pass south east) "╔"]
  93. [(pass south west ) "╗"]
  94. [(pass north south ) "║"]
  95. [(pass west east) "═"]
  96. [else " "]))
  97.  
  98. ;; Grid
  99.  
  100. (define-class <grid> ()
  101. (rows init-keyword: #:rows getter: rows)
  102. (cols init-keyword: #:cols getter: cols)
  103. (grid getter: cells))
  104.  
  105. (define-method (initialize (self <grid>) initargs)
  106. (define pos (Λ ref self <> <>))
  107.  
  108. (define (create-grid)
  109. (list-ec (: r (rows self))
  110. (: c (cols self))
  111. (make <cell> row: r col: c)))
  112.  
  113. (define (connect-neighbors cell)
  114. (define row (slot-ref cell 'row))
  115. (define col (slot-ref cell 'col))
  116. (set! (north cell) (pos (- row 1) col))
  117. (set! (south cell) (pos (+ row 1) col))
  118. (set! (west cell) (pos row (- col 1)))
  119. (set! (east cell) (pos row (+ col 1))))
  120.  
  121. (next-method)
  122. (slot-set! self 'grid (create-grid))
  123. (map connect-neighbors (slot-ref self 'grid)))
  124.  
  125. (define-method (ref (self <grid>) (row <integer>) (col <integer>))
  126. (if (and (< -1 row (rows self))
  127. (< -1 col (cols self)))
  128. (let ([g (slot-ref self 'grid)]
  129. [index (+ col (* row (cols self)))])
  130. (list-ref g index))
  131. #f))
  132.  
  133. (define-method (random-cell (self <grid>))
  134. (ref self
  135. (random (rows self))
  136. (random (cols self))))
  137.  
  138. (define-method (size (self <grid>))
  139. (* (rows self)
  140. (cols self)))
  141.  
  142. (define-generic for-each)
  143. (define-method (for-each (proc <procedure>) (self <list>))
  144. (let loop ([e (car self)]
  145. [r (cdr self)])
  146. (if (not (empty? r))
  147. (begin
  148. (proc e)
  149. (loop (car r)
  150. (cdr r))))))
  151.  
  152. (define-method (for-each (proc <procedure>) (self <grid>))
  153. (for-each proc (cells self)))
  154.  
  155. (define-method (for-each-row (proc <procedure>) (self <grid>))
  156. (let loop ([row (take (cells self) (cols self))]
  157. [rest (drop (cells self) (cols self))])
  158. (if (not (empty? rest))
  159. (begin
  160. (proc row)
  161. (loop (take rest (cols self))
  162. (drop rest (cols self)))))))
  163.  
  164. (define-method (show (self <grid>))
  165. (define glyphs (map show (cells self)))
  166. (let loop ([lst glyphs]
  167. [counter 1]
  168. [rslt '()])
  169. (cond
  170. [(empty? lst)
  171. (reverse rslt)]
  172. [(zero? (modulo counter (cols self)))
  173. (loop (cdr lst) (1+ counter) (cons "\n" (cons (car lst) rslt)))]
  174. [else (loop (cdr lst) (1+ counter) (cons (car lst) rslt))])))
  175.  
  176. (define (display-maze algorithm rows cols)
  177. (display (string-join (show (algorithm (make <grid> rows: rows cols: cols))) "")))
  178.  
  179.  
  180. ;; MAZE ALGORITHMS
  181.  
  182. ;; Binary tree
  183.  
  184. (define-method (binary-tree! (self <grid>))
  185. (define (make-hole cell)
  186. (cond
  187. [(and (east cell) (north cell)) (carve (sample north east) cell)]
  188. [(east cell) (carve east cell)]
  189. [(north cell) (carve north cell)]))
  190. (for-each make-hole self)
  191. self)
  192.  
  193. ;; Sidewider
  194. (define-method (sidewinder! (self <grid>))
  195. (sidewinder! self 0.7))
  196.  
  197. (define-method (sidewinder! (self <grid>) (horizontal-probability <real>))
  198. (define (carve-row row run)
  199. (if (not (empty? row))
  200. (let ([cell (car row)]
  201. [rest (cdr row)])
  202. (cond
  203. [(and (east cell) (chance horizontal-probability))
  204. (carve-row rest (cons (carve east cell) run))]
  205. [(not (north cell))
  206. (carve-row rest (cons (carve east cell) run))]
  207. [else (carve north (sample (cons cell run)))
  208. (carve-row rest '())]))))
  209. (for-each-row (Λ carve-row <> '()) self)
  210. self)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement