;;; Random comics, part 2 (load "goreydisplay.scm") (load "annotations.scm") ;;; The easiest kind of random story just sticks random images together ; make a random story, choosing len images randomly followed by "the end" (define totally-random-story (lambda (len) (cond ((= len 0) (list (tell "The End."))) (else (cons (show (+ 1 (random 30))) (totally-random-story (- len 1))))))) ; --------------------------------------------------------------------------- ;;; Going beyond totally-random story requires functions that can use ;;; the list of annotations ; given a predicate p? that returns true or false, remove all ; elements e of a list where (p? e) is false (define filter (lambda (p? l) (cond ((null? l) ()) ((p? (car l)) (cons (car l) (filter p? (cdr l)))) (else (filter p? (cdr l)))))) ; pick the Nth element of a list (N=1 means the car) ; (assumes n is an integer greater than 0) (define pick (lambda (n l) (if (= n 1) (car l) (pick (- n 1) (cdr l))))) ; pick a random element of the list (define random-pick (lambda (l) (pick (+ 1 (random (length l))) l))) ; find list of transitions that start with picture p (define transition-starts-with (lambda (p) (filter (lambda (ann) (= (car ann) p)) annotations))) ; --------------------------------------------------------------------------- ; make a random story with len pictures that begins at start ; (might stop early, if no suitable transition exists) ; ** This is the version from class; it has the (if ...) for the length ; ** after (transition-starts-with start); the different version below ; ** produces the same output as this one -- don't work from this one ; ** when writing random-structured-story (define random-unstructured-story-2-helper (lambda (start len) (let ((trans (transition-starts-with start))) (cons (show start) (if (or (= len 1) (null? trans)) (list (tell "The End.")) (random-unstructured-story-2-helper (cadr (random-pick trans)) (- len 1))))))) ; make a random story with len pictures that begins at start ; (might stop early, if no suitable transition exists) (define random-unstructured-story-helper (lambda (start len) (let ((trans (if (= len 1) () (transition-starts-with start)))) (cons (show start) (if (null? trans) (list (tell "The End.")) (random-unstructured-story-helper (cadr (random-pick trans)) (- len 1))))))) ; make a random story using transitions present in annotations ; - pick where the story starts, then use the helper function (define random-unstructured-story (lambda (len) (cons (tell "A series of unfortunate random events.") (random-unstructured-story-helper (car (random-pick annotations)) len)))) ; --------------------------------------------------------------------------- ; Tell a story using (tell-story ... gorey-earbrass-list) and ; then return the story that was just told ; (if story is #f, it returns #f) (define tell-it (lambda (story) (tell-story story gorey-earbrass-list) story)) ; Try to find a random story with structure in a certain number of attempts, ; and then tell the story (define try-to-tell-it (lambda (struct attempts) (let ((story (random-structured-story struct))) ;; a story with N transitions has N+1 pictures, plus 2 'tell' titles ;; for a total of N+3 (at least when the story doesn't end early) (cond ((= (length story) (+ (length struct) 3)) (tell-it story)) ((<= attempts 1) #f) (else (try-to-tell-it struct (- attempts 1))))))) ; --------------------------------------------------------------------------- ;; an example story structure (define s1 '(action-to-action subject-to-subject scene-to-scene scene-to-scene action-to-action subject-to-subject))