---
layout: ../Site.layout.js
---
# Common Lisp Hurkle Interface Manager
I got a few from notes from gamedev-of-the-ages [mdhughes](https://mdhughes.tech) about my common lisp class fulfilling Bob Albrecht's Hurkle. So so far I made a common lisp ASDF system, with a package following [my own ASDF introduction](/programming/completely-reasonable-common-lisp-asdf-system-with-eev-demo), with my [common lisp object system class whose methods span Hurkle](../itching-for-hurkles). This article add the McCLIM GUI packages ('actual game') to the aforesaid.
([git link](https://codeberg.org/tfw/hurkle))
As `mdh` says, the interface was basically just a debug interface:
```
CL-USER> (asdf:load-system :hurkle/class)
T
CL-USER> (use-package :hurkle/class)
T
CL-USER> (make-instance 'game-grid :rows 6)
#
CL-USER> (defparameter *g* *)
*G*
CL-USER> (look-board *g*)
0 ? ? ? ? ? ? ? ? ? ?
1 ? ? ? ? ? ? ? ? ? ?
2 ? ? ? ? ? ? ? ? ? ?
3 ? ? ? ? ? ? ? ? ? ?
4 ? ? ? ? ? ? ? ? ? ?
5 ? ? ? ? ? ? ? ? ? ?
+ 0 1 2 3 4 5 6 7 8 9
NIL
...
CL-USER> (investigate *g* 3 0)
0 ? ? ? ? ? ? ? ? ? ?
1 ? ? ? SE ? ? ? ? ? ?
2 ? ? ? ? ? ? ? ? ? ?
3 E E ? E ? ? E ? ? ?
4 ? ? ? ? ? ? ? ? ? ?
5 ? ? ? ? ? ? ? ? ? ?
+ 0 1 2 3 4 5 6 7 8 9
NIL
CL-USER> (investigate *g* 3 7)
0 ? ? ? ? ? ? ? ? ? ?
1 ? ? ? SE ? ? ? ? ? ?
2 ? ? ? ? ? ? ? ? ? ?
3 E E ? E ? ? E SE ? ?
4 ? ? ? ? ? ? ? ? ? ?
5 ? ? ? ? ? ? ? ? ? ?
+ 0 1 2 3 4 5 6 7 8 9you ran out of time!
NIL
```
Real talk: I got east and west mixed up in my head while playing above. This is the primary difficulty I have experienced Hurkling.
The next step today is to declaratively generate a common lisp interface manager GUI using [jackdaniel](https://turtleware.eu)'s [McCLIM](https://codeberg.org/McCLIM/McCLIM/) implementation of the spec. Aside, CLIM is the modern successor to the lisp machine dynamic-windows engineering and experiments.
## Add the package-inferred file=package mixing the hurkle class and CLIM into it
```
(eepitch-sbcl)
(with-open-file (*standard-output*
#p"~/common-lisp/hurkle/frame.lisp"
:direction :output
:if-exists :supersede
:if-does-not-exist :create)
(format t "
#|
\ (eepitch-sbcl)
\ (eepitch-kill)
\ (eepitch-sbcl)
|#
(uiop:define-package :hurkle/frame
(:mix :hurkle/class :clim :clim-lisp :cl)
(:export #:hurkle-frame
#:define-hurkle-frame-command
#:display-hurkles))
(in-package :hurkle/frame)
"))
```
# McCommon Lisp Interface Manager Hurkle Frame
```
;;; #P"~/common-lisp/hurkle/frame.lisp" ; continued
(define-application-frame hurkle-frame
(game-grid standard-application-frame)
()
(:pane :application
:display-function 'display-hurkles
:incremental-redisplay t))
(defmethod display-hurkles
((obj hurkle-frame)
pane)
(with-slots
(grid)
obj
(formatting-table
()
(loop :initially (terpri)
:with count := 0
:for row :in grid :do
(formatting-row
()
(loop
:initially
(formatting-cell () (princ count))
(incf count)
:for col :in row :do
(updating-output
(pane)
(formatting-cell
(pane)
(present col)))))
:finally
(formatting-row ()
(loop
:initially
(formatting-cell () (princ "."))
:for x
:below (length (car grid))
:do (formatting-cell () (princ x))))))))
```
Trying it:
```
(asdf:load-system :hurkle/frame)
(use-package :hurkle/frame)
(find-application-frame 'hurkle-frame)
```
(Before I added numbers:)
Looks like we're in business (trivially so).
Note I had to add the export `#:grid` to our `:hurkle/class` (pull your git or w/e).
## Hurkle common lisp interface manager commands
We add a new package in our game directory for commands because it must happen logically-after we defined `hurkle-frame` so we can use `define-hurkle-frame-command`
```
(with-open-file (*standard-output*
#P"~/common-lisp/hurkle/commands.lisp"
:direction :output
:if-exists :supersede
:if-does-not-exist :create)
(format t "
#|
\ (eepitch-sbcl)
\ (eepitch-kill)
\ (eepitch-sbcl)
|#
(uiop:define-package :hurkle/commands
(:mix :hurkle/frame
:hurkle/class
:clim :clim-lisp :cl)
(:export #:com-investigate))
(in-package :hurkle/commands)
"))
```
and its source:
### Investigate
```
(define-hurkle-frame-command
(com-investigate :menu t)
()
(let ((frame *application-frame*))
(let ((position
(accepting-values
(t :own-window t)
(reverse
(list
(accept 'integer :prompt "Col=x")
(accept 'integer :prompt "Row=y"))))))
(apply 'investigate frame (append position '(:stream nil))))))
```
### Quick note about those clim forms
(besides, the default text entry being too big for my case)
- Enter -> (Next form)
- alt enter -> Submit form
Hmm, maybe try slime or a raw repl rather than `eepitch-sbcl`. Still,
# Useage
(Observing that I am too tired right now)
```
(eepitch-sbcl)
(asdf:load-system :mcclim)
(in-package :clim-user)
(asdf:load-system :hurkle/commands)
(use-package :hurkle/class)
(use-package :hurkle/frame)
(use-package :hurkle/commands)
(find-application-frame 'hurkle-frame)
```
# Conclusion
I got kinda morally exhausted during the changes from *frame works* to *rows and columns are numbered* (not because of you/Hurkles, just the weight of the world on my shoulders). Calling it here.
I went back and added a `stream` keyword to `hurkle/class.lisp` so that McCLIM doesn't guess I am trying to get it to display this text `investigate` is producing.
Further notes, if you please!
I think the final installment of this triumverate will be the-frame-as-a-published-game on itch actually, then the `parenscript` `kittenification` will be another thing. I dunno, what do you think? The McCLIM is a straightforward and orthogonal extension to the CLOS class, right?
# Fin.
See you in [the Mastodon thread](https://gamerplus.org/@screwlisp/114611664134145784). No pressure but I already [told Sacha of emacsconf that we will unleash emacs smallweb kittens](https://gamerplus.org/@screwlisp/114606155202539991).
I am actively trying to help share lisp knowledge and useage! Please share this in any and every manner that occurs to you, and prod me to provide improvements at your leisure.