1
; AisleRiot - union_square.scm
2
; Copyright (C) 1999 Rosanna Yuen <rwsy@mit.edu>
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/>.
17
(use-modules (aisleriot interface) (aisleriot api))
21
(define tableau '(2 3 4 5 7 8 9 10 12 13 14 15 17 18 19 20))
22
(define foundation '(6 11 16 21))
25
(initialize-playing-area)
27
(make-standard-double-deck)
30
(add-normal-slot DECK 'stock)
31
(add-normal-slot '() 'waste)
35
(add-partially-extended-slot '() right 2 'tableau)
36
(add-partially-extended-slot '() right 2 'tableau)
37
(add-partially-extended-slot '() right 2 'tableau)
38
(add-partially-extended-slot '() right 2 'tableau)
42
(add-partially-extended-slot '() right 2 'foundation)
44
(add-carriage-return-slot)
49
(add-partially-extended-slot '() right 2 'tableau)
50
(add-partially-extended-slot '() right 2 'tableau)
51
(add-partially-extended-slot '() right 2 'tableau)
52
(add-partially-extended-slot '() right 2 'tableau)
56
(add-partially-extended-slot '() right 2 'foundation)
58
(add-carriage-return-slot)
63
(add-partially-extended-slot '() right 2 'tableau)
64
(add-partially-extended-slot '() right 2 'tableau)
65
(add-partially-extended-slot '() right 2 'tableau)
66
(add-partially-extended-slot '() right 2 'tableau)
70
(add-partially-extended-slot '() right 2 'foundation)
71
(add-carriage-return-slot)
76
(add-partially-extended-slot '() right 2 'tableau)
77
(add-partially-extended-slot '() right 2 'tableau)
78
(add-partially-extended-slot '() right 2 'tableau)
79
(add-partially-extended-slot '() right 2 'tableau)
83
(add-partially-extended-slot '() right 2 'foundation)
85
(deal-cards-face-up 0 '(2 3 4 5 7 8 9 10 12 13 14 15 17 18 19 20))
92
(define (give-status-message)
93
(set-statusbar-message (get-stock-no-string)))
95
(define (get-stock-no-string)
96
(string-append (_"Stock left:") " "
97
(number->string (length (get-cards 0)))))
100
(define (button-pressed slot-id card-list)
101
(and (not (empty-slot? slot-id))
102
(is-visible? (car card-list))
103
(= (length card-list) 1)
104
(not (or (= slot-id 6)
109
(define (to-foundation? card-list end-slot)
110
(if (empty-slot? end-slot)
111
(and (eq? (get-value (car card-list)) ace)
114
(not (eq? (get-suit (get-top-card 6))
115
(get-suit (car card-list)))))
118
(not (eq? (get-suit (get-top-card 11))
119
(get-suit (car card-list)))))
122
(not (eq? (get-suit (get-top-card 16))
123
(get-suit (car card-list)))))
126
(not (eq? (get-suit (get-top-card 21))
127
(get-suit (car card-list))))))
128
(if (eq? (get-suit (get-top-card end-slot))
129
(get-suit (car card-list)))
130
(cond ((< (length (get-cards end-slot)) 13)
131
(= (+ 1 (get-value (get-top-card end-slot)))
132
(get-value (car card-list))))
133
((= (length (get-cards end-slot)) 13)
134
(= (get-value (car card-list)) 13))
136
(= (get-value (get-top-card end-slot))
137
(+ 1 (get-value (car card-list))))))
140
(define (to-tableau? card-list end-slot)
141
(if (empty-slot? end-slot)
143
(if (eq? (get-suit (get-top-card end-slot))
144
(get-suit (car card-list)))
145
(cond ((= (length (get-cards end-slot)) 1)
146
(or (= (get-value (car card-list))
147
(+ 1 (get-value (get-top-card end-slot))))
148
(= (+ 1 (get-value (car card-list)))
149
(get-value (get-top-card end-slot)))))
150
((= (get-value (get-top-card end-slot))
151
(+ 1 (get-value (cadr (get-cards end-slot)))))
152
(= (get-value (car card-list))
153
(+ 1 (get-value (get-top-card end-slot)))))
154
((= (+ 1 (get-value (get-top-card end-slot)))
155
(get-value (cadr (get-cards end-slot))))
156
(= (+ 1 (get-value (car card-list)))
157
(get-value (get-top-card end-slot))))
161
(define (droppable? start-slot card-list end-slot)
162
(cond ((or (= end-slot start-slot)
170
(to-foundation? card-list end-slot))
172
(to-tableau? card-list end-slot))))
174
(define (button-released start-slot card-list end-slot)
175
(and (droppable? start-slot card-list end-slot)
176
(cond ((or (= end-slot 6)
180
(and (move-n-cards! start-slot end-slot card-list)
183
(move-n-cards! start-slot end-slot card-list)))))
185
(define (button-clicked slot-id)
187
(not (empty-slot? 0))
188
(deal-cards-face-up 0 '(1))))
190
(define (play-foundation-helper start-slot end-slots)
191
(define card (get-top-card start-slot))
192
(if (to-foundation? (list card) (car end-slots))
193
(and (remove-card start-slot)
194
(move-n-cards! start-slot (car end-slots) (list card))
196
(if (eq? (cdr end-slots) '())
198
(play-foundation-helper start-slot (cdr end-slots)))))
200
(define (button-double-clicked slot-id)
201
(cond ((member slot-id '(1 2 3 4 5 7 8 9 10 12 13 14 15 17 18 19 20))
202
(and (not (empty-slot? slot-id))
203
(play-foundation-helper slot-id '(6 11 16 21))))
204
((member slot-id '(6 11 16 21))
205
(autoplay-foundations))
208
(define (autoplay-foundations)
209
(define (autoplay-foundations-tail)
210
(if (or-map button-double-clicked '(1 2 3 4 5 7 8 9 10 12 13 14 15 17 18 19 20))
211
(delayed-call autoplay-foundations-tail)
213
(if (or-map button-double-clicked '(1 2 3 4 5 7 8 9 10 12 13 14 15 17 18 19 20))
214
(autoplay-foundations-tail)
217
(define (game-continuable)
218
(give-status-message)
222
(and (= (length (get-cards 6)) 26)
223
(= (length (get-cards 11)) 26)
224
(= (length (get-cards 16)) 26)
225
(= (length (get-cards 21)) 26)))
227
(define (check-a-foundation card-list end-slot)
230
(if (to-foundation? card-list end-slot)
232
(check-a-foundation card-list (+ 5 end-slot)))))
234
(define (check-to-foundations slot-id)
237
(if (or (empty-slot? slot-id)
241
(not (check-a-foundation (list (get-top-card slot-id)) 6)))
242
(check-to-foundations (+ 1 slot-id))
243
(hint-move slot-id 1 (check-a-foundation (list (get-top-card slot-id)) 6)))))
245
(define (check-imbedded card-list foundation-id)
246
(if (> (length card-list) 0)
247
(if (to-foundation? card-list foundation-id)
249
(check-imbedded (cdr card-list) foundation-id))
252
(define (check-slot-contents slot-id)
253
(cond ((and (not (empty-slot? 6))
254
(eq? (get-suit (get-top-card slot-id))
255
(get-suit (get-top-card 6)))
256
(check-imbedded (get-cards slot-id) 6))
257
(check-imbedded (get-cards slot-id) 6))
258
((and (not (empty-slot? 11))
259
(eq? (get-suit (get-top-card slot-id))
260
(get-suit (get-top-card 11)))
261
(check-imbedded (get-cards slot-id) 11))
262
(check-imbedded (get-cards slot-id) 11))
263
((and (not (empty-slot? 16))
264
(eq? (get-suit (get-top-card slot-id))
265
(get-suit (get-top-card 16)))
266
(check-imbedded (get-cards slot-id) 16))
267
(check-imbedded (get-cards slot-id) 16))
268
((and (not (empty-slot? 21))
269
(eq? (get-suit (get-top-card slot-id))
270
(get-suit (get-top-card 21)))
271
(check-imbedded (get-cards slot-id) 21))
272
(check-imbedded (get-cards slot-id) 21))
273
((and (empty-slot? 6)
274
(check-imbedded (get-cards slot-id) 6))
275
(check-imbedded (get-cards slot-id) 6))
276
((and (empty-slot? 11)
277
(check-imbedded (get-cards slot-id) 11))
278
(check-imbedded (get-cards slot-id) 11))
279
((and (empty-slot? 16)
280
(check-imbedded (get-cards slot-id) 16))
281
(check-imbedded (get-cards slot-id) 16))
282
((and (empty-slot? 21)
283
(check-imbedded (get-cards slot-id) 21))
284
(check-imbedded (get-cards slot-id) 21))
285
((and (> (length (get-cards slot-id)) 1)
286
(or (and (not (= slot-id 2))
287
(not (empty-slot? 2))
288
(to-tableau? (reverse (get-cards slot-id)) 2)
289
(not (= (get-value (cadr (reverse (get-cards slot-id))))
290
(get-value (get-top-card 2)))))
291
(and (not (= slot-id 3))
292
(not (empty-slot? 3))
293
(to-tableau? (reverse (get-cards slot-id)) 3)
294
(not (= (get-value (cadr (reverse (get-cards slot-id))))
295
(get-value (get-top-card 3)))))
296
(and (not (= slot-id 4))
297
(not (empty-slot? 4))
298
(to-tableau? (reverse (get-cards slot-id)) 4)
299
(not (= (get-value (cadr (reverse (get-cards slot-id))))
300
(get-value (get-top-card 4)))))
301
(and (not (= slot-id 5))
302
(not (empty-slot? 5))
303
(to-tableau? (reverse (get-cards slot-id)) 5)
304
(not (= (get-value (cadr (reverse (get-cards slot-id))))
305
(get-value (get-top-card 5)))))
306
(and (not (= slot-id 7))
307
(not (empty-slot? 7))
308
(to-tableau? (reverse (get-cards slot-id)) 7)
309
(not (= (get-value (cadr (reverse (get-cards slot-id))))
310
(get-value (get-top-card 7)))))
311
(and (not (= slot-id 8))
312
(not (empty-slot? 8))
313
(to-tableau? (reverse (get-cards slot-id)) 8)
314
(not (= (get-value (cadr (reverse (get-cards slot-id))))
315
(get-value (get-top-card 8)))))
316
(and (not (= slot-id 9))
317
(not (empty-slot? 9))
318
(to-tableau? (reverse (get-cards slot-id)) 9)
319
(not (= (get-value (cadr (reverse (get-cards slot-id))))
320
(get-value (get-top-card 9)))))
321
(and (not (= slot-id 10))
322
(not (empty-slot? 10))
323
(to-tableau? (reverse (get-cards slot-id)) 10)
324
(not (= (get-value (cadr (reverse (get-cards slot-id))))
325
(get-value (get-top-card 10)))))
326
(and (not (= slot-id 12))
327
(not (empty-slot? 12))
328
(to-tableau? (reverse (get-cards slot-id)) 12)
329
(not (= (get-value (cadr (reverse (get-cards slot-id))))
330
(get-value (get-top-card 12)))))
331
(and (not (= slot-id 13))
332
(not (empty-slot? 13))
333
(to-tableau? (reverse (get-cards slot-id)) 13)
334
(not (= (get-value (cadr (reverse (get-cards slot-id))))
335
(get-value (get-top-card 13)))))
336
(and (not (= slot-id 14))
337
(not (empty-slot? 14))
338
(to-tableau? (reverse (get-cards slot-id)) 14)
339
(not (= (get-value (cadr (reverse (get-cards slot-id))))
340
(get-value (get-top-card 14)))))
341
(and (not (= slot-id 15))
342
(not (empty-slot? 15))
343
(to-tableau? (reverse (get-cards slot-id)) 15)
344
(not (= (get-value (cadr (reverse (get-cards slot-id))))
345
(get-value (get-top-card 15)))))
346
(and (not (= slot-id 17))
347
(not (empty-slot? 17))
348
(to-tableau? (reverse (get-cards slot-id)) 17)
349
(not (= (get-value (cadr (reverse (get-cards slot-id))))
350
(get-value (get-top-card 17)))))
351
(and (not (= slot-id 18))
352
(not (empty-slot? 18))
353
(to-tableau? (reverse (get-cards slot-id)) 18)
354
(not (= (get-value (cadr (reverse (get-cards slot-id))))
355
(get-value (get-top-card 18)))))
356
(and (not (= slot-id 19))
357
(not (empty-slot? 19))
358
(to-tableau? (reverse (get-cards slot-id)) 19)
359
(not (= (get-value (cadr (reverse (get-cards slot-id))))
360
(get-value (get-top-card 19)))))
361
(and (not (= slot-id 20))
362
(not (empty-slot? 20))
363
(to-tableau? (reverse (get-cards slot-id)) 20)
364
(not (= (get-value (cadr (reverse (get-cards slot-id))))
365
(get-value (get-top-card 20)))))))
369
(define (check-a-tslot slot1 slot2)
372
(if (and (not (= slot2 6))
375
(not (empty-slot? slot2))
376
(not (= slot1 slot2))
377
(not (empty-slot? slot1))
378
(to-tableau? (list (get-top-card slot1)) slot2)
380
(= (length (get-cards slot1)) 1)
381
(not (= (get-value (cadr (get-cards slot1)))
382
(get-value (get-top-card slot2))))))
383
(if (and (not (= slot1 1))
384
(not (empty-slot? slot2))
385
(to-tableau? (list (get-top-card slot2)) slot1)
386
(check-slot-contents slot2))
387
(hint-move slot2 1 slot1)
388
(hint-move slot1 1 slot2))
389
(check-a-tslot slot1 (+ 1 slot2)))))
391
(define (check-tableau slot-id)
393
(and (not (empty-slot? 1))
395
(if (or (= slot-id 6)
398
(check-tableau (- slot-id 1))
399
(or (check-a-tslot slot-id 2)
400
(check-tableau (- slot-id 1))))))
402
(define (check-for-empty slot-id)
405
(if (and (not (= slot-id 6))
408
(empty-slot? slot-id))
410
(check-for-empty (+ 1 slot-id)))))
412
(define (check-rev-tableau slot1 slot2)
415
(if (or (empty-slot? slot2)
420
(check-rev-tableau slot1 (+ 1 slot2))
421
(if (and (to-tableau? (reverse (get-cards slot1)) slot2)
422
(= (abs (- (get-value (cadr (reverse (get-cards slot1))))
423
(get-value (get-top-card slot2))))
426
(check-rev-tableau slot1 (+ 1 slot2))))))
428
(define (check-for-bottom slot-id)
431
(if (or (empty-slot? slot-id)
432
(= 1 (length (get-cards slot-id)))
436
(check-for-bottom (+ 1 slot-id))
437
(or (check-rev-tableau slot-id 2)
438
(check-for-bottom (+ 1 slot-id))))))
440
(define (contents-check slot-id)
443
(if (and (not (= slot-id 6))
446
(not (empty-slot? slot-id))
447
(check-slot-contents slot-id))
449
(contents-check (+ 1 slot-id)))))
451
(define (check-empty-slot)
452
(if (not (check-for-empty 2))
454
(cond ((contents-check 2)
455
(hint-move (contents-check 2) 1 (find-empty-slot tableau)))
456
((check-for-bottom 2)
457
(hint-move (check-for-bottom 2) 1 (find-empty-slot tableau)))
458
((not (empty-slot? waste))
459
(hint-move waste 1 (find-empty-slot tableau)))
463
(if (not (empty-slot? 0))
464
(list 0 (_"Deal a card"))
468
(or (check-to-foundations 1)
472
(list 0 (_"No hint available right now"))))
474
(define (get-options)
477
(define (apply-options options)
483
(set-features droppable-feature)
485
(set-lambda new-game button-pressed button-released button-clicked
486
button-double-clicked game-continuable game-won get-hint get-options
487
apply-options timeout droppable?)