Advertisement
Guest User

Untitled

a guest
Jun 11th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 18.22 KB | None | 0 0
  1. #lang racket
  2.  
  3. ;;; ---------------------------------------------------------------------------
  4. ;;; Prosty system obiektowy z dziedziczeniem
  5.  
  6. (define (ask object message . args)
  7.   (let ((method (get-method object message)))
  8.     (if (method? method)
  9.     (apply method (cons object args))
  10.     (error "Brak metody" message (cadr method)))))
  11.  
  12. (define (get-method object message)
  13.   (object message))
  14.  
  15. (define (no-method name)
  16.   (list 'no-method name))
  17.  
  18. (define (method? x)
  19.   (not (no-method? x)))
  20.  
  21. (define (no-method? x)
  22.   (if (pair? x)
  23.       (eq? (car x) 'no-method)
  24.       false))
  25.  
  26. ;;; ----------------------------------------------------------------------------
  27. ;;; Osoby, miejsca i rzeczy są nazwanymi obiektami
  28.  
  29. (define (make-named-object name)
  30.   (lambda (message)
  31.     (cond ((eq? message 'name) (lambda (self) name))
  32.       (else (no-method name)))))
  33.  
  34. ;;; Osoby i rzeczy są mobilne, ich miejsce może ulec zmianie
  35.  
  36. (define (make-mobile-object name location)
  37.   (let ((named-obj (make-named-object name)))
  38.     (lambda (message)
  39.       (cond ((eq? message 'place)    (lambda (self) location))
  40.         ((eq? message 'install)
  41.          (lambda (self)
  42.            (ask location 'add-thing self)))
  43.         ;; Poniższa metoda nie powinna być wołana przez użytkownika
  44.         ;; Zobacz change-place
  45.         ((eq? message 'set-place)
  46.          (lambda (self new-place)
  47.            (set! location new-place)
  48.            'place-set))
  49.         (else (get-method named-obj message))))))
  50.  
  51. (define (make&install-mobile-object name place)
  52.   (let ((mobile-obj (make-mobile-object name place)))
  53.     (ask mobile-obj 'install)
  54.     mobile-obj))
  55.  
  56. ;;; Rzecz to coś, co może mieć właściciela
  57.  
  58. (define (make-thing name birthplace)
  59.   (let ((owner     'nobody)
  60.     (mobile-obj (make-mobile-object name birthplace)))
  61.     (lambda (message)
  62.       (cond ((eq? message 'owner)    (lambda (self) owner))
  63.         ((eq? message 'ownable?) (lambda (self) true))
  64.         ((eq? message 'owned?)
  65.          (lambda (self)
  66.            (not (eq? owner 'nobody))))
  67.         ;; Poniższa metoda nie powinna być wołana przez użytkownika
  68.         ;; Zobacz take i lose
  69.         ((eq? message 'set-owner)
  70.          (lambda (self new-owner)
  71.            (set! owner new-owner)
  72.            'owner-set))
  73.         (else (get-method mobile-obj message))))))
  74.  
  75. (define (make&install-thing name birthplace)   
  76.   (let ((thing  (make-thing name birthplace)))
  77.     (ask thing 'install)
  78.     thing))
  79.  
  80. ;;; Pewne elementy wystroju nie mogą mieć właściciela
  81. (define (make-not-ownable-thing name birthplace)
  82.   (let ((owner     'nobody)
  83.     (mobile-obj (make-mobile-object name birthplace)))
  84.     (lambda (message)
  85.       (cond ((eq? message 'owner)    (lambda (self) owner))
  86.         ((eq? message 'ownable?) (lambda (self) false))
  87.         ((eq? message 'owned?)
  88.          (lambda (self)
  89.            (not (eq? owner 'nobody))))
  90.         ;; Poniższa metoda nie powinna być wołana przez użytkownika
  91.         ;; Zobacz take i lose
  92.         (else (get-method mobile-obj message))))))
  93.  
  94. (define (make&install-not-ownable-thing name birthplace)   
  95.   (let ((thing  (make-not-ownable-thing name birthplace)))
  96.     (ask thing 'install)
  97.     thing))
  98.  
  99. ;;; Implementacja miejsc
  100.  
  101. (define (make-place name)
  102.   (let ((neighbor-map '())     
  103.     (things       '())
  104.     (named-obj (make-named-object name)))
  105.     (lambda (message)
  106.       (cond ((eq? message 'things) (lambda (self) things))
  107.         ((eq? message 'neighbors)
  108.          (lambda (self) (map cdr neighbor-map)))
  109.         ((eq? message 'exits)
  110.          (lambda (self) (map car neighbor-map)))
  111.         ((eq? message 'neighbor-towards)
  112.          (lambda (self direction)
  113.            (let ((places (assq direction neighbor-map)))
  114.          (if places
  115.              (cdr places)
  116.             false))))
  117.             ((eq? message 'add-neighbor)
  118.              (lambda (self direction new-neighbor)
  119.                (cond ((assq direction neighbor-map)
  120.                       (display-message (list "Kierunek już przypisany"
  121.                           direction name))
  122.               false)
  123.                      (else
  124.                       (set! neighbor-map
  125.                             (cons (cons direction new-neighbor) neighbor-map))
  126.               true))))
  127.         ((eq? message 'accept-person?)
  128.          (lambda (self person)
  129.           true))
  130.  
  131.         ;; Poniższe metody nie powinny być wołane przez użytkownika
  132.         ;; Zobacz change-place
  133.             ((eq? message 'add-thing)
  134.              (lambda (self new-thing)
  135.                (cond ((memq new-thing things)
  136.                       (display-message (list (ask new-thing 'name)
  137.                          "już jest w" name))
  138.               false)
  139.                      (else (set! things (cons new-thing things))
  140.               true))))
  141.             ((eq? message 'del-thing)
  142.              (lambda (self thing)
  143.                (cond ((not (memq thing things))
  144.                       (display-message (list (ask thing 'name)
  145.                          "nie jest w" name))
  146.               false)
  147.                      (else (set! things (delq thing things))
  148.               true))))
  149.  
  150.             (else (get-method named-obj message))))))
  151.  
  152. ;;; ----------------------------------------------------------------------------
  153. ;;; Implementacja osób
  154.  
  155. (define (make-person name birthplace threshold)
  156.   (let ((possessions '())
  157.     (mobile-obj  (make-mobile-object name birthplace)))
  158.     (lambda (message)
  159.       (cond ((eq? message 'person?)     (lambda (self) true))
  160.         ((eq? message 'possessions) (lambda (self) possessions))
  161.         ((eq? message 'list-possessions)
  162.          (lambda (self)
  163.            (ask self 'say
  164.             (cons "Mam"
  165.               (if (null? possessions)
  166.                   '("nic")
  167.                   (map (lambda (p) (ask p 'name))
  168.                       possessions))))
  169.            possessions))
  170.         ((eq? message 'say)
  171.          (lambda (self list-of-stuff)
  172.            (display-message
  173.          (append (list "W miejscu" (ask (ask self 'place) 'name)
  174.                    ":"  name "mówi --")
  175.              (if (null? list-of-stuff)
  176.                  '("Nieważne.")
  177.                  list-of-stuff)))
  178.            'said))
  179.         ((eq? message 'have-fit)
  180.          (lambda (self)
  181.            (ask self 'say '("Jestem zły!!!"))
  182.            'I-feel-better-now))
  183.         ((eq? message 'look-around)
  184.          (lambda (self)
  185.            (let ((other-things
  186.                (map (lambda (thing) (ask thing 'name))
  187.                                (delq self
  188.                                      (ask (ask self 'place)
  189.                                           'things)))))
  190.                  (ask self 'say (cons "Widzę" (if (null? other-things)
  191.                           '("nic")
  192.                           other-things)))
  193.          other-things)))
  194.  
  195.         ((eq? message 'take)
  196.          (lambda (self thing)
  197.            (cond [(memq thing possessions)
  198.               (ask self 'say
  199.                (list "Już mam" (ask thing 'name)))
  200.               true]
  201.              [(and (let ((things-at-place (ask (ask self 'place) 'things)))
  202.                  (memq thing things-at-place))
  203.                (is-a thing 'ownable?))
  204.               (if (ask thing 'owned?)
  205.               (let ((owner (ask thing 'owner)))
  206.                 (ask owner 'lose thing)
  207.                 (ask owner 'have-fit))
  208.               'unowned)
  209.  
  210.               (ask thing 'set-owner self)
  211.               (set! possessions (cons thing possessions))
  212.               (ask self 'say
  213.                (list "Biorę" (ask thing 'name)))
  214.               true]
  215.              [else
  216.               (display-message
  217.                (list "Nie możesz wziąć" (ask thing 'name)))
  218.               false])))
  219.         ((eq? message 'lose)
  220.          (lambda (self thing)
  221.            (cond ((eq? self (ask thing 'owner))
  222.               (set! possessions (delq thing possessions))
  223.               (ask thing 'set-owner 'nobody)
  224.               (ask self 'say
  225.                (list "Tracę" (ask thing 'name)))
  226.               true)
  227.              (else
  228.               (display-message (list name "nie ma"
  229.                          (ask thing 'name)))
  230.               false))))
  231.         ((eq? message 'move)
  232.          (lambda (self)
  233.                (cond ((and (> threshold 0) (= (random threshold) 0))
  234.               (ask self 'act)
  235.               true))))
  236.         ((eq? message 'act)
  237.          (lambda (self)
  238.            (let ((new-place (random-neighbor (ask self 'place))))
  239.          (if new-place
  240.              (ask self 'move-to new-place)
  241.             false))))
  242.  
  243.         ((eq? message 'move-to)
  244.          (lambda (self new-place)
  245.            (let ((old-place (ask self 'place)))
  246.          (cond ((eq? new-place old-place)
  247.             (display-message (list name "już jest w"
  248.                            (ask new-place 'name)))
  249.             false)
  250.                ((ask new-place 'accept-person? self)
  251.             (change-place self new-place)
  252.             (for-each (lambda (p) (change-place p new-place))
  253.                   possessions)
  254.             (display-message
  255.               (list name "idzie z"    (ask old-place 'name)
  256.                      "do"         (ask new-place 'name)))
  257.             (greet-people self (other-people-at-place self new-place))
  258.             true)
  259.                (else
  260.             (display-message (list name "nie może iść do"
  261.                            (ask new-place 'name))))))))
  262.         ((eq? message 'go)
  263.          (lambda (self direction)
  264.            (let ((old-place (ask self 'place)))
  265.          (let ((new-place (ask old-place 'neighbor-towards direction)))
  266.            (cond (new-place
  267.               (ask self 'move-to new-place))
  268.              (else
  269.               (display-message (list "Nie możesz pójść" direction
  270.                          "z" (ask old-place 'name)))
  271.               false))))))
  272.         ((eq? message 'install)
  273.          (lambda (self)
  274.            (add-to-clock-list self)
  275.            ((get-method mobile-obj 'install) self)))
  276.         (else (get-method mobile-obj message))))))
  277.  
  278. (define (make&install-person name birthplace threshold)
  279.   (let ((person (make-person name birthplace threshold)))
  280.     (ask person 'install)
  281.     person))
  282.  
  283. ;;; Łazik umie sam podnosić rzeczy
  284.  
  285. (define (make-rover name birthplace threshold)
  286.   (let ((person (make-person name birthplace threshold)))
  287.     (lambda (message)
  288.       (cond ((eq? message 'act)
  289.          (lambda (self)
  290.            (let ((possessions (ask self 'possessions)))
  291.                  (if (null? possessions)
  292.                      (ask self 'grab-something)
  293.                      (ask self 'lose (car possessions))))))
  294.             ((eq? message 'grab-something)
  295.          (lambda (self)
  296.            (let* ((things (ask (ask self 'place) 'things))
  297.                       (fthings
  298.                        (filter (lambda (thing) (is-a thing 'ownable?))
  299.                                things)))
  300.          (if (not (null? fthings))
  301.              (ask self 'take (pick-random fthings))
  302.             false))))
  303.         ((eq? message 'move-arm)
  304.          (lambda (self)
  305.                (display-message (list name "rusza manipulatorem"))
  306.            '*bzzzzz*))
  307.         (else (get-method person message))))))
  308.  
  309. (define (make&install-rover name birthplace threshold)
  310.   (let ((rover  (make-rover name birthplace threshold)))
  311.     (ask rover 'install)
  312.     rover))
  313.  
  314.  
  315.  
  316. (define (make-ghost name birthplace threshold)
  317.   (let ((person (make-person name birthplace threshold)))
  318.     (lambda (message)
  319.       (cond ((eq? message 'take)
  320.          (lambda (self thing)
  321.            (display-message (list name "jest duchem, więc nie może podnosić przedmiotów"))))
  322.         ((eq? message 'lose)
  323.          (lambda (self thing)
  324.            (display-message (list name "duch nie może być w posiadaniu przedmiotów, więc nie może też żadnego upuścić"))))
  325.         (else (get-method person message))))))
  326.  
  327. (define (make&install-ghost name birthplace threshold)
  328.   (let ((ghost (make-ghost name birthplace threshold)))
  329.     (ask ghost 'install)
  330.     ghost))
  331.  
  332. ;; TODO: nowe rodzaje przedmiotów lub postaci
  333.  
  334. ;;; --------------------------------------------------------------------------
  335. ;;; Obsługa zegara
  336.  
  337. (define *clock-list* '())
  338. (define *the-time* 0)
  339.  
  340. (define (initialize-clock-list)
  341.   (set! *clock-list* '())
  342.   'initialized)
  343.  
  344. (define (add-to-clock-list person)
  345.   (set! *clock-list* (cons person *clock-list*))
  346.   'added)
  347.  
  348. (define (remove-from-clock-list person)
  349.   (set! *clock-list* (delq person *clock-list*))
  350.   'removed)
  351.  
  352. (define (clock)
  353.   (newline)
  354.   (display "---Tick---")
  355.   (set! *the-time* (+ *the-time* 1))
  356.   (for-each (lambda (person) (ask person 'move))
  357.         *clock-list*)
  358.   'tick-tock)
  359.          
  360.  
  361. (define (current-time)
  362.   *the-time*)
  363.  
  364. (define (run-clock n)
  365.   (cond ((zero? n) 'done)
  366.     (else (clock)
  367.           (run-clock (- n 1)))))
  368.  
  369. ;;; --------------------------------------------------------------------------
  370. ;;; Różne procedury
  371.  
  372. (define (is-a object property)
  373.   (let ((method (get-method object property)))
  374.     (if (method? method)
  375.     (ask object property)
  376.     false)))
  377.  
  378. (define (change-place mobile-object new-place)
  379.   (let ((old-place (ask mobile-object 'place)))
  380.     (ask mobile-object 'set-place new-place)
  381.     (ask old-place 'del-thing mobile-object))
  382.   (ask new-place 'add-thing mobile-object)
  383.   'place-changed)
  384.  
  385. (define (other-people-at-place person place)
  386.   (filter (lambda (object)
  387.         (if (not (eq? object person))
  388.         (is-a object 'person?)
  389.         false))
  390.       (ask place 'things)))
  391.  
  392. (define (greet-people person people)
  393.   (if (not (null? people))
  394.       (ask person 'say
  395.        (cons "Cześć"
  396.          (map (lambda (p) (ask p 'name))
  397.              people)))
  398.       'sure-is-lonely-in-here))
  399.  
  400. (define (display-message list-of-stuff)
  401.   (newline)
  402.   (for-each (lambda (s) (display s) (display " "))
  403.         list-of-stuff)
  404.   'message-displayed)
  405.  
  406. (define (random-neighbor place)
  407.   (pick-random (ask place 'neighbors)))
  408.  
  409. (define (filter predicate lst)
  410.   (cond ((null? lst) '())
  411.     ((predicate (car lst))
  412.      (cons (car lst) (filter predicate (cdr lst))))
  413.     (else (filter predicate (cdr lst)))))
  414.  
  415. (define (pick-random lst)
  416.   (if (null? lst)
  417.       false
  418.       (list-ref lst (random (length lst)))))  ;; See manual for LIST-REF
  419.  
  420. (define (delq item lst)
  421.   (cond ((null? lst) '())
  422.     ((eq? item (car lst)) (delq item (cdr lst)))
  423.     (else (cons (car lst) (delq item (cdr lst))))))
  424.  
  425. ;;------------------------------------------
  426. ;; Od tego miejsca zaczyna się kod świata
  427.  
  428. (initialize-clock-list)
  429.  
  430. ;; Tu definiujemy miejsca w naszym świecie
  431. ;;------------------------------------------
  432.  
  433. (define hol              (make-place 'hol))
  434. (define piętro-wschód    (make-place 'piętro-wschód))
  435. (define piętro-zachód    (make-place 'piętro-zachód))
  436. (define ksi              (make-place 'ksi))
  437. (define continuum        (make-place 'continuum))
  438. (define plastyczna       (make-place 'plastyczna))
  439. (define wielka-wschodnia (make-place 'wielka-wschodnia))
  440. (define wielka-zachodnia (make-place 'wielka-zachodnia))
  441. (define kameralna-wschodnia (make-place 'kameralna-wschodnia))
  442. (define kameralna-zachodnia (make-place 'kameralna-zachodnia))
  443. (define schody-parter    (make-place 'schody-parter))
  444. (define schody-piętro    (make-place 'schody-piętro))
  445. ;
  446. (define portiernia       (make-place 'portiernia))
  447. (define schody-2piętro   (make-place 'schody-2piętro))
  448. (define pokój-dbiernacki (make-place 'pokój-dbiernacki))
  449. (define schody-3piętro   (make-place 'schody-3piętro))
  450. (define pokój-fsieczkowski (make-place 'pokój-fsieczkowski))
  451. (define pokój-mpiróg     (make-place 'pokój-mpiróg))
  452. (define pokój-mmaterzok  (make-place 'pokój-mmaterzok))
  453.  
  454. ;; TODO: nowe lokacje
  455.  
  456. ;; Połączenia między miejscami w świecie
  457. ;;------------------------------------------------------
  458.  
  459. (define (can-go from direction to)
  460.   (ask from 'add-neighbor direction to))
  461.  
  462. (define (can-go-both-ways from direction reverse-direction to)
  463.   (can-go from direction to)
  464.   (can-go to reverse-direction from))
  465.  
  466. (can-go-both-ways schody-parter 'góra 'dół schody-piętro)
  467. (can-go-both-ways hol 'zachód 'wschód wielka-zachodnia)
  468. (can-go-both-ways hol 'wschód 'zachód wielka-wschodnia)
  469. (can-go-both-ways hol 'południe 'północ schody-parter)
  470. (can-go-both-ways piętro-wschód 'południe 'wschód schody-piętro)
  471. (can-go-both-ways piętro-zachód 'południe 'zachód schody-piętro)
  472. (can-go-both-ways piętro-wschód 'zachód 'wschód piętro-zachód)
  473. (can-go-both-ways piętro-zachód 'północ 'południe kameralna-zachodnia)
  474. (can-go-both-ways piętro-wschód 'północ 'południe kameralna-wschodnia)
  475. (can-go-both-ways schody-parter 'wschód 'zachód plastyczna)
  476. (can-go-both-ways hol 'północ 'południe ksi)
  477. (can-go-both-ways piętro-zachód 'zachód 'wschód continuum)
  478. ;
  479. (can-go-both-ways schody-piętro 'góra 'dół schody-2piętro)
  480. (can-go-both-ways schody-2piętro 'góra 'dół schody-3piętro)
  481. (can-go-both-ways schody-2piętro 'wschód 'zachód pokój-dbiernacki)
  482. (can-go-both-ways schody-3piętro 'wschód 'zachód pokój-fsieczkowski)
  483. (can-go-both-ways schody-3piętro 'zachód 'wschód pokój-mmaterzok)
  484. (can-go-both-ways schody-3piętro 'północ 'południe pokój-mpiróg)
  485. (can-go-both-ways hol 'południowy-zachód 'połnocny-wschód portiernia)
  486.  
  487. ;; TODO: połączenia dla nowych lokacji
  488.  
  489. ;; Osoby dramatu
  490. ;;---------------------------------------
  491.  
  492. (define student   (make&install-person 'student hol 0))
  493.  
  494. (define fsieczkowski
  495.   (make&install-person 'fsieczkowski wielka-wschodnia 3))
  496. (define mpirog    (make&install-person 'mpirog wielka-wschodnia 3))
  497. (define mmaterzok (make&install-person 'mmaterzok wielka-wschodnia 3))
  498. (define jma       (make&install-person 'jma piętro-wschód 2))
  499. (define klo       (make&install-person 'klo kameralna-wschodnia 2))
  500. (define ref       (make&install-person 'ref ksi 0))
  501. (define aleph1    (make&install-rover 'aleph1 continuum 3))
  502. ;
  503. (define dbiernacki (make&install-person 'dbiernacki pokój-dbiernacki 2))
  504. (define portier    (make&install-person 'portier portiernia 0))
  505. (define ghost      (make&install-ghost  'duszek hol 3))
  506.  
  507.  
  508. (define słój-pacholskiego (make&install-thing 'słój-pacholskiego schody-piętro))
  509. (define trytytki     (make&install-thing 'trytytki continuum))
  510. (define cążki-boczne (make&install-thing 'cążki-boczne continuum))
  511. ;
  512. (define ławka        (make&install-not-ownable-thing 'ławka hol))
  513. (define mikrofalówka (make&install-thing 'mikrofalówka ksi))
  514. (define wygodne-krzesło (make&install-thing 'wygodne-krzesło pokój-dbiernacki))
  515.  
  516. ;; TODO: dodatkowe osoby i przedmioty
  517.  
  518. ;; Polecenia dla gracza
  519. ;;------------------------------------------------
  520.  
  521. (define *player-character* student)
  522.  
  523. (define (look-around)
  524.   (ask *player-character* 'look-around)
  525.   #t)
  526.  
  527. (define (go direction)
  528.   (ask *player-character* 'go direction)
  529.   (clock)
  530.   #t)
  531.  
  532. (define (escape)
  533.   (ask *player-character* 'act)
  534.   (clock)
  535.   #t)
  536.  
  537. (define (exits)
  538.   (display-message (ask (ask *player-character* 'place) 'exits))
  539.   #t)
  540.  
  541. (define (take thing)
  542.   (ask *player-character* 'take thing)
  543.   #t)
  544.  
  545. (define (lose thing)
  546.   (ask *player-character* 'lose thing))
  547.  
  548. (define (possesions)
  549.   (ask *player-character* 'list-possessions)
  550.   #t)
  551.  
  552. (define (say stuff)
  553.   (ask *player-character* 'say stuff)
  554.   #t)
  555.  
  556. (define (wait)
  557.   (clock)
  558.   #t)
  559.  
  560. ;; TODO: dodatkowe polecenia dla gracza
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement