CloudFlare suffered a massive security issue affecting all of its customers, including Rosetta Code. All passwords not changed since February 19th 2017 have been expired, and session cookie longevity will be reduced until late March.--Michael Mol (talk) 05:15, 25 February 2017 (UTC)

Tamagotchi emulator

From Rosetta Code
Tamagotchi emulator is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

If you don't know what Tamagotchi is, take a look at the Wikipedia page about it.

This task is about creating a Tamagotchi emulator, a virtual pet that you must take care of.

Your virtual pet must, like real pets, at least: get hungry, get bored, age and poop!
Against hunger, you must create a way to feed it. Against boredom, you must play with or pet it. The poop must be cleaned, otherwise the pet might get sick and if it is not cured, it might die from its disease. Finally, the pet should grow older and eventually die.

On screen, your program must display the virtual pet status data - age, hunger and happiness levels, when the pet poops, its poop must also be displayed. Ah, well, an avatar of the pet must be there too, but I guess that's obvious!

What else? Well, use your creativityโ€ฆ
Every pet needs a name. What kind of games, or โ€˜mini gamesโ€™ one can play with his pet? And so on!

But, above of all, have fun!

EchoLisp[edit]

The tamagotchi status is saved in permanent storage. The tamagotchi cycles can be started manually, or in the preferences function, or at predefined intervals : every function. The following code may be loaded from the EchoLisp library : (load 'tamagotchi). This tamagotchi does not play, but gets bored, and needs to talk. It must be feed two times between each cycle. It will die at age around 42 (42 cycles).

 
 
(define-constant CYCLE_TIME 30000) ;; 30 sec for tests, may be 4 hours, 1 day ...
(string-delimiter "")
(struct tamagotchi (name age food poop bored))
 
;; utility : display tamagotchi thoughts : transitive verb + complement
(define (tama-talk tama)
(writeln (string-append
"๐Ÿ˜ฎ : "
(word-random #:any '( verbe trans inf -vintran)))
" les "
(word-random #:any '(nom pluriel))))
 
;; load tamagotchi from persistent storage into *tama* global
(define (run-tamagotchi)
(if (null? (local-get '*tama*))
(writeln "Please (make-tamagotchi <name>)")
(begin
(make-tamagotchi (tamagotchi-name *tama*) *tama*)
(tama-cycle *tama*)
(writeln (tama-health *tama*)))))
 
;; make a new tamagotchi
;; or instantiate an existing
;; tama : instance ot tamagotchi structure
(define (make-tamagotchi name (tama null))
(when (null? tama)
(set! tama (tamagotchi name 0 2 0 0))
(define-global '*tama* tama)
(local-put '*tama*))
 
;; define the <name> procedure :
;; perform user action / save tamagotchi / display status
 
(define-global name
(lambda (action)
(define tama (local-get '*tama*))
[case action
((feed) (set-tamagotchi-food! tama (1+ (tamagotchi-food tama))))
((talk) (tama-talk tama) (set-tamagotchi-bored! tama (max 0 (1- (tamagotchi-bored tama)))))
((clean) (set-tamagotchi-poop! tama (max 0 (1- (tamagotchi-poop tama)))))
((look) #t)
;; debug actions
((_cycle) (tama-cycle tama))
((_reset) (set! *tama* null) (local-put '*tama*))
((_kill) (set-tamagotchi-age! tama 44))
((_self) (writeln tama))
(else (writeln "actions: feed/talk/clean/look"))]
 
(local-put '*tama*)
(tama-health tama))))
 
;; every n msec : get older / eat food / get bored / poop
(define (tama-cycle tama)
(when (tama-alive tama)
(set-tamagotchi-age! tama (1+ (tamagotchi-age tama)))
(set-tamagotchi-bored! tama (+ (tamagotchi-bored tama) (random 2)))
(set-tamagotchi-food! tama (max 0 (- (tamagotchi-food tama) 2)))
(set-tamagotchi-poop! tama (+ (tamagotchi-poop tama) (random 2))))
(local-put '*tama*))
 
;; compute sickness (too much poop, too much food, too much bored)
(define (tama-sick tama)
(+ (tamagotchi-poop tama)
(tamagotchi-bored tama)
(max 0 (- (tamagotchi-age tama) 32)) ;; die at 42
(abs (- (tamagotchi-food tama) 2))))
 
;; alive if sickness <= 10
(define (tama-alive tama)
(<= (tama-sick tama) 10))
 
;; display num icons from a list
(define (icons list num)
(for/fold (str " ") ((i [in-range 0 num] ))
(string-append str (list-ref list (random (length list))))))
 
;; display boredom/food/poops icons
(define (tama-status tama)
(if (tama-alive tama)
(string-append
" [ "
(icons '(๐Ÿ’ค ๐Ÿ’ญ โ“ ) (tamagotchi-bored tama))
(icons '(๐Ÿผ ๐Ÿ” ๐ŸŸ ๐Ÿฐ ๐Ÿœ ) (tamagotchi-food tama))
(icons '(๐Ÿ’ฉ) (tamagotchi-poop tama))
" ]")
" R.I.P" ))
 
;; display health status = f(sickness)
(define (tama-health tama)
(define sick (tama-sick tama))
;;(writeln 'health:sickยฐ= sick)
(string-append
(format "%a (๐ŸŽ‚ %d) " (tamagotchi-name tama)(tamagotchi-age tama))
(cond
([<= sick 2] (icons '(๐Ÿ˜„ ๐Ÿ˜ƒ ๐Ÿ˜€ ๐Ÿ˜Š ๐Ÿ˜Ž๏ธ ๐Ÿ‘ ) 1 )) ;; ok <= 2
([<= sick 4] (icons '(๐Ÿ˜ช ๐Ÿ˜ฅ ๐Ÿ˜ฐ ๐Ÿ˜“ ) 1))
([<= sick 6] (icons '(๐Ÿ˜ฉ ๐Ÿ˜ซ ) 1))
([<= sick 10] (icons '(๐Ÿ˜ก ๐Ÿ˜ฑ ) 1)) ;; very bad
(else (icons '(โŒ ๐Ÿ’€ ๐Ÿ‘ฝ ๐Ÿ˜‡ ) 1))) ;; dead
(tama-status tama)))
 
;; timer operations
;; run tama-proc = cycle every CYCLE_TIME msec
 
(define (tama-proc n)
(define tama (local-get '*tama*))
(when (!null? tama)
(tama-cycle tama)
(writeln (tama-health tama))))
 
;; boot
;; manual boot or use (preferences) function
(every CYCLE_TIME tama-proc)
(run-tamagotchi)
 
 
Output:

User commands are function calls : (albert 'clean). The rest is automatic display : one status line / cycle.

(lib 'struct)
(lib 'sql) ;; for words
(lib 'words)
(lib 'timer)
(lib 'dico.fr);; will talk in french
(load 'tamagotchi)
Please (make-tamagotchi <name>)   
    
    (make-tamagotchi 'albert)

    albert (๐ŸŽ‚ 1) ๐Ÿ˜“ [ ๐Ÿ’ญ ]    
    albert (๐ŸŽ‚ 2) ๐Ÿ˜ฐ [ ๐Ÿ’ญโ“ ]    ;; needs to talk
    (albert 'talk)
    ๐Ÿ˜ฎ : dรฉlรฉaturer     les      fidรจles    
    albert (๐ŸŽ‚ 2) ๐Ÿ˜“ [ โ“ ]
    (albert 'talk)
    ๐Ÿ˜ฎ : facetter     les      dรฉcorations    
    albert (๐ŸŽ‚ 2) ๐Ÿ˜ƒ [ ]
    albert (๐ŸŽ‚ 3) ๐Ÿ˜ฅ [ ๐Ÿ’ค ๐Ÿ’ฉ ]    
    (albert 'feed)
    albert (๐ŸŽ‚ 3) ๐Ÿ˜ช [ ๐Ÿ’ค ๐Ÿ” ๐Ÿ’ฉ ] ;; needs cleaning
    (albert 'clean)
    albert (๐ŸŽ‚ 3) ๐Ÿ˜Š [ ๐Ÿ’ญ ๐ŸŸ ]
    (albert 'talk)
    ๐Ÿ˜ฎ : manifester     les      canyons    
    albert (๐ŸŽ‚ 3) ๐Ÿ˜ƒ [ ๐Ÿฐ ] ;; all is ok
    albert (๐ŸŽ‚ 4) ๐Ÿ‘ [ ]    
    albert (๐ŸŽ‚ 5) ๐Ÿ˜ƒ [ ]    
    albert (๐ŸŽ‚ 6) ๐Ÿ˜ฅ [ โ“ ๐Ÿ’ฉ ]    
    (albert 'clean)
    albert (๐ŸŽ‚ 6) ๐Ÿ˜ช [ ๐Ÿ’ค ]
    albert (๐ŸŽ‚ 7) ๐Ÿ˜ฐ [ ๐Ÿ’ญ ๐Ÿ’ฉ ]    
    albert (๐ŸŽ‚ 8) ๐Ÿ˜“ [ ๐Ÿ’ญ ๐Ÿ’ฉ ]    
    (for ((i 10)) (albert 'feed))
    albert (๐ŸŽ‚ 8) ๐Ÿ˜ฑ [ ๐Ÿ’ญ ๐Ÿ”๐Ÿผ๐Ÿ”๐Ÿผ๐Ÿœ๐Ÿผ๐ŸŸ๐Ÿ”๐Ÿ”๐ŸŸ ๐Ÿ’ฉ ] ;; very sick
    albert (๐ŸŽ‚ 9) ๐Ÿ˜ฑ [ โ“ ๐Ÿฐ๐Ÿฐ๐ŸŸ๐ŸŸ๐Ÿผ๐ŸŸ๐Ÿœ๐Ÿœ ๐Ÿ’ฉ๐Ÿ’ฉ ]    
    (albert 'talk)
    ๐Ÿ˜ฎ : assortir     les      dรฉchiffrages    
    albert (๐ŸŽ‚ 9) ๐Ÿ˜ฑ [ ๐Ÿผ๐Ÿผ๐ŸŸ๐ŸŸ๐Ÿœ๐Ÿ”๐Ÿผ๐Ÿฐ ๐Ÿ’ฉ๐Ÿ’ฉ ]
    albert (๐ŸŽ‚ 10) ๐Ÿ˜ก [ ๐Ÿ’ญ ๐Ÿฐ๐ŸŸ๐ŸŸ๐ŸŸ๐ŸŸ๐Ÿœ ๐Ÿ’ฉ๐Ÿ’ฉ๐Ÿ’ฉ ]  

    (for ((i 20)) (albert 'talk)) ;; can talk without getting tired
    ๐Ÿ˜ฎ : rรฉaliser     les      dรฉlassements    
    ๐Ÿ˜ฎ : ratiboiser     les      รฉtatistes    
    ๐Ÿ˜ฎ : commenter     les      diphtongues    
    ๐Ÿ˜ฎ : jurer     les      samouraรฏs    
    ๐Ÿ˜ฎ : bousculer     les      mรฉchages    
    ๐Ÿ˜ฎ : รฉpรฉpiner     les      dรฉnicotiniseurs    
    ๐Ÿ˜ฎ : tรฉmoigner     les      pรฉniches    
    ๐Ÿ˜ฎ : pateliner     les      maquereaux    
    ๐Ÿ˜ฎ : conseiller     les      diminutifs    
    ๐Ÿ˜ฎ : gratiner     les      perdreaux    
    ๐Ÿ˜ฎ : klaxonner     les      รฉlues    
    ๐Ÿ˜ฎ : ganser     les      dรฉvoltages    
    ๐Ÿ˜ฎ : rรฉconcilier     les      pixels    ;; reconciliate the pixels
    ๐Ÿ˜ฎ : rocher     les      รฉcrasรฉs    
    ๐Ÿ˜ฎ : guรชtrer     les      transgressions    
    ๐Ÿ˜ฎ : lanterner     les      pisseurs    
    ๐Ÿ˜ฎ : opรฉrer     les      rasades    
    ๐Ÿ˜ฎ : actionner     les      loukoums    
    ๐Ÿ˜ฎ : dรฉgarnir     les      artichauts    
    ๐Ÿ˜ฎ : chanfreiner     les      rajeunissements    
 
    (for ((i 14)) (albert 'feed)) ;; do'nt feed it too much .. it will die
    albert (๐ŸŽ‚ 10) ๐Ÿ˜‡ R.I.P ;; died at age 10
    albert (๐ŸŽ‚ 10) โŒ R.I.P    
    albert (๐ŸŽ‚ 10) ๐Ÿ‘ฝ R.I.P    
    albert (๐ŸŽ‚ 10) ๐Ÿ˜‡ R.I.P    
    albert (๐ŸŽ‚ 10) ๐Ÿ˜‡ R.I.P  
  
    (make-tamagotchi 'simon)
    simon
    simon (๐ŸŽ‚ 1) ๐Ÿ˜“ [ ๐Ÿ’ค ๐Ÿ’ฉ ]    

Forth[edit]

( current object )
0 value o
' o >body constant 'o
: >o ( o -- ) postpone o postpone >r postpone 'o postpone ! ; immediate
: o> ( -- ) postpone r> postpone 'o postpone ! ; immediate
 
( chibi: classes with a current object and no formal methods )
0 constant object
: subclass ( class "name" -- a ) create here swap , does> @ ;
: class ( "name" -- a ) object subclass ;
: end-class ( a -- ) drop ;
: var ( a size "name" -- a ) over dup @ >r +!
 : postpone o r> postpone literal postpone + postpone ; ;
 
( tamagotchi )
class tama
cell var hunger
cell var boredom
cell var age
cell var hygiene
cell var digestion
cell var pooped
end-class
 
: offset ( -- ) \ go to column #13 of current line
s\" \e[13G" type ;
 
: show ( "field" -- )
' POSTPONE literal POSTPONE dup
POSTPONE cr POSTPONE id. POSTPONE offset
POSTPONE execute POSTPONE ? ; immediate
: dump ( -- )
show hunger show boredom show age show hygiene
cr ." pooped" offset pooped @ if ." yes" else ." no" then ;
 
\ these words both exit their caller on success
: -poop ( -- )
digestion @ 1 <> ?exit digestion off pooped on
cr ." tama poops!" r> drop ;
: -hunger ( -- )
digestion @ 0 <> ?exit hunger ++
cr ." tama's stomach growls" r> drop ;
 
: died-from ( 'reason' f -- )
if cr ." tama died from " type cr bye then 2drop ;
: by-boredom ( -- ) "boredom" boredom @ 5 > died-from ;
: by-sickness ( -- ) "sickness" hygiene @ 1 < died-from ;
: by-hunger ( -- ) "hunger" hunger @ 5 > died-from ;
: by-oldness ( -- ) "age" age @ 30 > died-from ;
 
: sicken ( -- ) pooped @ if hygiene -- then ;
: digest ( -- ) -poop -hunger digestion -- ;
: die ( -- ) by-boredom by-sickness by-hunger by-oldness ;
 
( tamagotchi ops )
: spawn ( -- )
cr ." tama is born!"
hunger off boredom off age off pooped off
5 hygiene ! 5 digestion ! ;
 
: wait ( -- )
cr ." ** time passes **"
boredom ++ age ++
digest sicken die ;
 
: look ( -- ) 0
boredom @ 2 > if 1+ cr ." tama looks bored" then
hygiene @ 5 < if 1+ cr ." tama could use a wash" then
hunger @ 0 > if 1+ cr ." tama's stomach is grumbling" then
age @ 20 > if 1+ cr ." tama is getting long in the tooth" then
pooped @ if 1+ cr ." tama is disgusted by its own waste" then
0= if cr ." tama looks fine" then ;
 
: feed ( -- )
hunger @ 0= if cr ." tama bats the offered food away" exit then
cr ." tama happily devours the offered food"
hunger off 5 digestion ! ;
 
: clean ( -- )
pooped @ 0= if cr ." tama is clean enough already." exit then
cr ." You dispose of the mess." pooped off 5 hygiene ! ;
 
: play ( -- )
boredom @ 0= if cr ." tama ignores you." exit then
cr ." tama plays with you for a while." boredom off ;
 
( game mode )
\ this just permanently sets the current object
\ a more complex game would use >o ... o> to set it
create pet tama allot
pet to o
 
cr .( You have a pet tamagotchi!)
cr
cr .( commands: WAIT LOOK FEED CLEAN PLAY)
cr ( secret commands: SPAWN DUMP )
spawn look
cr
 

Boredom kills tama faster than anything else.