A memory game in McCLIM
| link | Last. 20260119T041125921Z |
A memory game in McCLIM
(ql:quickload :McCLIM)
(require :McCLIM)
(in-package :clim-user)
(define-presentation-type memory-card () :inherit-from '(symbol))
(define-presentation-method present (object
(type memory-card)
stream view
&key
&allow-other-keys)
(present
(if (get object :visible)
(get object :front)
(get object :back))))
(defparameter *cards*
(loop :with deck-size := 6
:with back := 'x
:with fronts := (loop
:for front
:below (truncate deck-size 2)
:collecting front)
:for card := (gensym)
:for x :below deck-size :do
(setf (get card :back) back
(get card :front)
(elt fronts (mod x (length fronts))))
:collect card))
(defparameter *cursors* '(t t))
(defun reveal (card)
(multiple-value-bind
(card1 card2)
(apply 'values *cursors*)
(if card2
(symbol-macrolet
((match (equal (get card1 :front)
(get card2 :front))))
(psetf (get card1 :visible) match
(get card2 :visible) match
(first *cursors*) card
(second *cursors*) nil
(get card :visible) t))
(setf (second *cursors*) card
card2 card
(get card2 :visible) t))))
(defun disp ()
(present *cards* '(sequence memory-card)) (terpri)
(present *cursors*))
(defun reset ()
(setq *cursors* '(t t))
(loop :for card :in *cards* :do
(setf (get card :visible) nil)))
I think this is a straightforward implementation of the memory card game.
Playing memory
I know this is the hard-hitting lisp knowledge you crave.
CLIM-USER> (disp)
X,X,X,X,X,X
T,T
NIL
CLIM-USER> (elt *cards* 0)
#:G3644
CLIM-USER> (reveal *)
NIL
CLIM-USER> (disp)
1,X,X,X,X,X
G3644,NIL
NIL
CLIM-USER> (reveal (elt *cards* 1))
T
CLIM-USER> (disp)
1,2,X,X,X,X
G3644,G3645
NIL
CLIM-USER> (reveal (elt *cards* 2))
NIL
CLIM-USER> (disp)
X,X,3,X,X,X
G3646,NIL
NIL
CLIM-USER> (reveal (elt *cards* 5))
T
CLIM-USER> (disp)
X,X,3,X,X,3
G3646,G3649
NIL
CLIM-USER> (reveal (elt *cards* 4))
NIL
CLIM-USER> (disp)
X,X,3,X,2,3
G3648,NIL
NIL
CLIM-USER> (reveal (elt *cards* 3))
T
CLIM-USER> (disp)
X,X,3,1,2,3
G3648,G3647
NIL
CLIM-USER> (reveal (elt *cards* 0))
NIL
CLIM-USER> (disp)
1,X,3,X,X,3
G3644,NIL
NIL
CLIM-USER> (reveal (elt *cards* 3))
T
CLIM-USER> (disp)
1,X,3,1,X,3
G3644,G3647
NIL
CLIM-USER> (reveal (elt *cards* 1))
NIL
CLIM-USER> (reveal (elt *cards* 4))
T
CLIM-USER> (disp)
1,2,3,1,2,3
G3645,G3648
NIL
CLIM-USER>
Cheating using rotatef as an aside
CLIM-USER> (disp)
X,X,X,X,X,X
G3645,G3648
NIL
CLIM-USER> (reveal (first *cards*))
NIL
CLIM-USER> (disp)
0,X,X,X,X,X
G1404648,NIL
NIL
CLIM-USER> (reveal (second *cards*))
T
CLIM-USER> (disp)
0,1,X,X,X,X
G1404648,G1404649
NIL
CLIM-USER> (rotatef (first *cards*) (second *cards*))
NIL
CLIM-USER> (disp)
1,0,X,X,X,X
G1404648,G1404649
NIL
Conclusions
So my actual intent is to use xhtmlambda to generate a kitten web game. However a complicated game might obfuscate that, and you cannot get more simple than memory.
I still had to think of how to implement memory. This McCLIM is me doing that. It might be good to continue the clim example as well. My rules seem to allow you to deliberately turn your own cards face down again if you really want to. I will allow it.
Also, yes, even though I just implemented a way to generate RSS, I have not enabled it yet because I am shuffling the way I generate kitten blogposts.
See you on this Mastodon thread.