Index: aisleriot/sol.scm =================================================================== --- aisleriot/sol.scm (revision 5971) +++ aisleriot/sol.scm (working copy) @@ -296,6 +296,17 @@ (define (empty-slot? slot-id) (null? (get-cards slot-id))) +(define (any-slot-empty? slots) + (if (eq? slots '()) + #f + (or (empty-slot? (car slots)) + (any-slot-empty? (cdr slots))))) + +(define (find-empty-slot slots) + (if (empty-slot? (car slots)) + (car slots) + (find-empty-slot (cdr slots)))) + ; Get the nth card from a slot. Returns #f if n is out of range. (define (get-nth-card slot-id n) (let ((cards (get-cards slot-id))) @@ -522,6 +533,12 @@ (define (nthcdr n lst) (if (zero? n) lst (nthcdr (+ -1 n) (cdr lst)))) +; guile library function I'm not sure I can rely on +(define (list-head lst k) + (if (= k 0) + '() + (cons (car lst) (list-head (cdr lst) (- k 1))))) + ;; INTERNAL procedures ; global variables Index: aisleriot/rules/spider.scm =================================================================== --- aisleriot/rules/spider.scm (revision 5971) +++ aisleriot/rules/spider.scm (working copy) @@ -45,6 +45,8 @@ (define winning-score 96) +(define allow-empty-slots #f) + (define (new-game) (initialize-playing-area) (make-deck) @@ -120,7 +122,8 @@ #t) (define (check-for-points slot) - (and (is-visible? (cadr (get-cards slot))) + (and (> (length (get-cards slot)) 1) + (is-visible? (cadr (get-cards slot))) (eq? (get-suit (get-top-card slot)) (get-suit (cadr (get-cards slot)))) (= (+ 1 (get-value (get-top-card slot))) @@ -165,16 +168,11 @@ (and (droppable? start-slot card-list end-slot) (complete-transaction start-slot card-list end-slot))) -(define (any-slot-empty? slots) - (if (eq? slots '()) - #f - (or (empty-slot? (car slots)) - (any-slot-empty? (cdr slots))))) - (define (button-clicked slot) (and (= stock slot) (not (empty-slot? stock)) - (if (any-slot-empty? tableau) + (if (and (not allow-empty-slots) + (any-slot-empty? tableau)) (begin (set-statusbar-message (_"Please fill in empty pile first.")) #f) @@ -183,8 +181,20 @@ (give-status-message) #t)))) + +(define (is-playable-stack cards n) + (and (not (null? cards)) + (= (get-value (car cards)) n) + (or (= n 13) + (is-playable-stack (cdr cards) (+ n 1))))) + (define (button-double-clicked slot) - #f) + (and (member slot tableau) + (is-playable-stack (get-cards slot) 1) + (let ((card-list (list-head (get-cards slot) 13))) + (remove-n-cards slot 13) + (complete-transaction slot card-list (find-empty-slot foundation))) + #t)) (define (game-over) (and (not (game-won))