1
; AisleRiot - giant.scm
2
; Copyright (C) 2009 Ed Sirett <ed@makewrite.demon.co.uk>
4
; This program is free software: you can redistribute it and/or modify
5
; it under the terms of the GNU General Public License as published by
6
; the Free Software Foundation, either version 3 of the License, or
7
; (at your option) any later version.
9
; This program is distributed in the hope that it will be useful,
10
; but WITHOUT ANY WARRANTY; without even the implied warranty of
11
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
; GNU General Public License for more details.
14
; You should have received a copy of the GNU General Public License
15
; along with this program. If not, see <http://www.gnu.org/licenses/>.
22
(define foundation '(1 2 3 4 5 6 7 8))
23
(define tableau '(9 10 11 12 13 14 15 16 ))
24
(define reserve-slot 17)
26
(make-standard-double-deck)
29
(define winning-score 104)
31
(define allow-empty-slots #t)
35
(initialize-playing-area)
40
(add-normal-slot DECK)
50
(add-carriage-return-slot)
51
(add-extended-slot '() down)
52
(add-extended-slot '() down)
53
(add-extended-slot '() down)
54
(add-extended-slot '() down)
55
(add-extended-slot '() down)
56
(add-extended-slot '() down)
57
(add-extended-slot '() down)
58
(add-extended-slot '() down)
62
(deal-cards-face-up stock-slot tableau)
68
(define (give-status-message)
69
(set-statusbar-message (get-stock-no-string))
72
(define (get-stock-no-string)
73
(format (_"Deals left: ~a")
74
(number->string (/ (length (get-cards stock-slot)) 8 ))
78
;additional functions.
80
(define (complete-transaction start-slot card-list end-slot)
81
(if (member end-slot foundation)
82
(move-n-cards! start-slot end-slot (reverse card-list))
83
(move-n-cards! start-slot end-slot card-list)
87
(define (button-pressed slot card-list)
88
(if (or (empty-slot? slot) (= slot stock-slot))
89
#f ; can't pick from stock or empty piles
90
(and (or (and (not same-suit) (check-alternating-color-list card-list))
91
(and same-suit (check-same-suit-list card-list)))
92
(check-straight-descending-list card-list))))
96
(define (droppable? start-slot card-list end-slot)
97
(and (not (= start-slot end-slot))
98
( or (and (member end-slot foundation)
99
(check-straight-descending-list card-list)
100
(check-same-suit-list card-list)
101
(if (empty-slot? end-slot)
102
(= (get-value (car card-list)) ace)
103
(and (= (get-suit (car card-list)) (get-suit (get-top-card end-slot)))
104
(= (- (get-value (car card-list)) 1 ) (get-value (get-top-card end-slot)))
108
(and (member end-slot tableau)
109
(check-straight-descending-list card-list)
110
(or (and (not same-suit) (check-alternating-color-list card-list))
111
(and same-suit (check-same-suit-list card-list)))
112
(if (not (empty-slot? end-slot))
113
(and (= (+ (get-value (car (reverse card-list))) 1 ) (get-value (get-top-card end-slot)))
114
(or (and (not same-suit)
115
(not ( eq? ( is-red? ( car (reverse card-list))) (is-red? (get-top-card end-slot)))))
117
(= (get-suit (car (reverse card-list))) (get-suit (get-top-card end-slot))))))
121
(and (= end-slot reserve-slot)
122
(empty-slot? reserve-slot)
123
(= (length card-list) 1)
129
(define (button-released start-slot card-list end-slot)
130
(and (droppable? start-slot card-list end-slot)
131
(complete-transaction start-slot card-list end-slot))
134
(define (do-deal-next-cards)
135
(deal-cards-face-up stock-slot tableau))
137
(define (button-clicked slot)
138
(if (= stock-slot slot)
139
(if (dealable?) (do-deal-next-cards) #f)
143
(define (find-any-to-foundation from-slots)
144
(if (eq? from-slots '() )
146
(let ((find-to-result (find-to foundation (car from-slots))))
148
(list (car from-slots) find-to-result)
149
(find-any-to-foundation (cdr from-slots))))))
151
; remake a list of slots with/without empty members
152
(define (without-gaps slots with-empties)
153
(cond ((eq? slots '()) '())
155
((empty-slot? (car slots)) (without-gaps (cdr slots) with-empties))
156
( else (cons (car slots) (without-gaps (cdr slots) with-empties)))))
159
(define (find-any-to-tableau from-slots with-empties)
160
(if (eq? from-slots '() )
162
(let ((find-to-result (find-to (without-gaps tableau with-empties) (car from-slots)))
163
(cfs (car from-slots)))
164
(if (and find-to-result
165
; check we are not breaking an existing run
166
(or (= (length (get-cards cfs )) 1)
167
(not (check-straight-descending-list (list (get-top-card cfs) (cadr (get-cards cfs))))))
168
; if suggesting a move to a gap make sure it is worthwhile
169
(or (not (empty-slot? find-to-result))
170
(> (length (get-cards cfs )) 1))) ;can move a top card to a gap if it does not make a gap
171
(list cfs find-to-result)
172
(find-any-to-tableau (cdr from-slots) with-empties)))))
174
(define (move-any-to-foundation slots)
175
(let (( find-any-result (find-any-to-foundation slots)))
177
(move-a-card (car find-any-result) (cadr find-any-result))
182
(if (move-any-to-foundation (append tableau (list reserve-slot)))
183
(delayed-call auto-play)
189
(define (find-to slots from-slot)
190
(if (or (empty-slot? from-slot) (eq? slots '()))
192
(if (droppable? from-slot (list (get-top-card from-slot)) (car slots) )
194
(find-to (cdr slots) from-slot)
199
(define (move-a-card from-slot to-slot)
200
(if ( or (not to-slot) (empty-slot? from-slot))
202
(add-card! to-slot (remove-card from-slot))
206
(define (move-to-foundation from-slot)
207
(move-a-card from-slot (find-to foundation from-slot ))
211
(define (button-double-clicked slot)
212
(if (member slot foundation)
214
(if (or (member slot tableau) (= slot reserve-slot) )
215
(move-to-foundation slot)
223
(give-status-message)
224
(and (not (game-won))
229
; score the game - 1 pt for every card in the foundations 104 to win.
230
(define (game-score slot-list)
231
(if (and (null? slot-list))
233
(+ (length (get-cards (car slot-list))) (game-score (cdr slot-list)))
237
; game is won when all cards are moved to foundations.
239
(= (set-score! (game-score foundation)) winning-score)
246
(not (empty-slot? stock-slot ))
247
(or allow-empty-slots
248
(not (any-slot-empty? tableau))))
249
(list 0 (_"Deal a row"))
253
(define (my-get-card-name slot)
254
(if (empty-slot? slot)
255
(if (member slot foundation)
256
(_"an empty foundation place")
257
(_"an empty tableau place"))
258
(get-name (get-top-card slot))
265
; This is the hint function
266
; 1) Suggest a move to a foundation.
267
; 2) Suggest moving a card from the (reserve + tableau) to the tableau.
268
; 3) Suggest moviing a card to an empty tableau-slot
269
; 4) Suggest moving to the reserve if unoccupied
270
; 5) Suggest dealing a row if there are cards still in the stock.
271
; 6) Suggest moving cards around.
274
(let ((find-result (find-any-to-foundation (append tableau (list reserve-slot))))
275
(t-result1 (find-any-to-tableau (append tableau (list reserve-slot)) #f ))
276
(t-result2 (find-any-to-tableau (append tableau (list reserve-slot)) #t )))
279
(list 2 (my-get-card-name (car find-result)) (my-get-card-name (cadr find-result))))
281
(list 2 (my-get-card-name (car t-result1)) (my-get-card-name (cadr t-result1))))
283
(list 2 (my-get-card-name (car t-result2)) (my-get-card-name (cadr t-result2))))
284
( (empty-slot? reserve-slot) (list 0 (_"Try moving a card to the reserve")))
285
( (dealable?) (list 0 (_"Try dealing a row of cards")))
286
; this isn't great, but it will get around the premature end-of-game call
287
(else (list 0 (_"Try moving card piles around")))
290
(define (get-options)
291
(list 'begin-exclusive
292
(list (_"Same suit") same-suit)
293
(list (_"Alternating colors") (not same-suit))
296
(define (apply-options options)
297
(set! same-suit (cadr (list-ref options 1))))
299
(define (timeout) #f)
301
(set-features droppable-feature dealable-feature)
303
(set-lambda new-game button-pressed button-released button-clicked button-double-clicked game-over game-won get-hint
304
get-options apply-options timeout droppable? dealable?)