Added pp1.

This commit is contained in:
lucic71 2020-05-07 09:54:00 +03:00
parent 88c96b234c
commit 4fbe09e71f
5 changed files with 781 additions and 0 deletions

View File

@ -0,0 +1,85 @@
#lang racket
(provide fill-abilities)
(provide compose-abilities)
(provide hourglass)
(provide (struct-out ability))
(provide (struct-out abilities))
(provide get-ability-image)
(provide get-ability-time)
(provide get-ability-pos)
(provide get-ability-next)
(require "random.rkt")
(require lang/posn)
(require 2htdp/image)
; Imaginea si range-ul în care vor aparea abilitațile
; Nu modificați
(define POSITION_RANGE '((300 2000) (30 550)))
(define (hourglass color) (underlay
(rectangle 40 40 "solid" color)
(polygon
(list (make-posn 0 0)
(make-posn 25 0)
(make-posn 0 25)
(make-posn 25 25))
"outline"
(make-pen "darkslategray" 5 "solid" "round" "round"))))
; ABILITY
; image: corresponding image for ability
; time: how much the ability lasts
; pos: position
; next: function that receives variables from state and modifies them
(struct ability (image time pos next) #:transparent)
; ABILITIES
; visible abilities
; active abilities
(struct abilities (visible active) #:transparent)
; Fiecare funcție returneaza o componenta a unei abilități.
(define (get-ability-image ability) (ability-image ability))
(define (get-ability-time ability) (ability-time ability))
(define (get-ability-pos ability) (ability-pos ability))
(define (get-ability-next ability) (ability-next ability))
; Returneaza o poziție aleatorie în POSITION_RANGE.
(define (random-position range)
(apply make-posn (map ((curry apply) random) range)))
; Returnează o listă de n elemente alese aleatoriu din lista L.
(define (choice-abilities n L)
(sample (discrete-dist L) n))
; Va parcurge abitatile și pentru cele care au poziția null va asigna
; una aletorie.
; Folosiți random-position
(define (position-abilities abilities)
(map (lambda (curr-ability)
(if (null? (get-ability-pos curr-ability))
(struct-copy ability
curr-ability
[pos (random-position POSITION_RANGE)])
curr-ability))
abilities))
; Fiecare abilitate are o funcție next care modifica stare jocului
; Compuneti toate funcțiile next în una singură
; Hint: compose
(define (compose-abilities L)
(apply compose (foldr (lambda (L-ability acc) (cons (ability-next L-ability) acc)) '() L)))
; Primiște o listă de abilități inițiale, un număr n
; și o listă cu toate abilități posibile.
; Va adauga elemente aleatoare la lista inițială pană aceasta are lungimea n
; Atentie n poate fi chiar si 0 cand vrem sa jucam fara nicio abilitate.
; Folosiți choice-abilities.
(define (fill-abilities initial n abilities)
(cond [(zero? n) '()]
[(<= n (length initial)) initial]
[else (position-abilities (append initial
(choice-abilities (- n (length initial)) abilities)))]))

View File

@ -0,0 +1,45 @@
; Constante pentru joc
; Nu modificați imaginile de referință sunt create pentru aceste valori.
#lang racket
(require lang/posn)
(provide (all-defined-out))
(define fps 28.0)
(define scene-height 960)
(define scene-width 640)
(define ground-height (quotient scene-height 6))
(define ground-y (- scene-height ground-height))
(define initial-gravity 1.3)
(define initial-momentum 15.0)
(define bird-width 81)
(define bird-height 57)
(define bird-x (quotient scene-width 3))
(define bird-initial-y (quotient scene-height 2))
(define pipe-width 104)
(define pipe-height scene-height)
(define pipe-gap 232.75)
(define pipe-self-gap 280)
(define initial-scroll-speed 7.0)
(define added-number (quotient scene-height 8))
(define random-threshold (- (- scene-height (* 2 added-number)) pipe-self-gap))
(define no-pipes 6)
(define text-height 50)
(define text-x (- scene-width 50))
(define text-y 50)
(define text-posn (make-posn (- scene-width 50) 50))
(define abilities-posn (make-posn (- scene-width 50) 80))
(define DISPLAYED_ABILITIES 4)
(define SHOW_SCORE #t)
; checker stuff
(define (disable-score) (set! SHOW_SCORE #f))
(define (disable-bonus) (set! DISPLAYED_ABILITIES 0))
(define (enable-bonus) (set! DISPLAYED_ABILITIES 4))

View File

@ -0,0 +1,561 @@
#lang racket/gui
;Ignorați următoarele linii de cod. Conțin import-uri și export-uri necesare checker-ului.
(require 2htdp/image)
(require 2htdp/universe)
(require lang/posn)
(require "random.rkt")
(require "abilities.rkt")
(require "constants.rkt")
;---------------------------------------checker_exports------------------------------------------------
(provide next-state)
(provide next-state-bird)
(provide next-state-bird-onspace)
(provide change)
(provide get-pipes)
(provide get-pipe-x)
(provide next-state-pipes)
(provide add-more-pipes)
(provide clean-pipes)
(provide move-pipes)
(provide invalid-state?)
(provide check-ground-collision)
(provide check-pipe-collisions)
(provide draw-frame)
(provide get-initial-state)
(provide get-bird)
(provide get-bird-y)
(provide get-bird-v-y)
; pipe
(provide get-pipes)
(provide get-pipe-x)
; score25
(provide get-score)
(provide get-abilities)
(provide get-abilities-visible)
(provide get-abilities-active)
; variables
(provide get-variables)
(provide get-variables-gravity)
(provide get-variables-momentum)
(provide get-variables-scroll-speed)
;---------------------------------------checker_exports------------------------------------------------
; Checker-ul contine un numar de teste, fiecare cu numele sau. In acest fisier veti gasi comentarii
; care incep cu TODO %nume_test, unde trebuie sa modificati sau sa implementati o functie, pentru
; a trece testul %nume_test.
;
;Initial state
; Primul pas pe care trebuie sa il facem este sa cream starea initiala a jocului.
; Aceasta va fi salvata in (get-initial-state), si trebuie sa incapsuleze toate informatiile
; necesare jocului, si anume: informatii despre pasare, despre pipes si despre powerups.
; Recomandam ca in pasare, sa retineti, printre altele, informatii despre y-ul curent
; si viteza pe y
; Pe parcursul temei, in state, salvati coordonatele colturilor din stanga sus ale obiectelor.
; Aceasta va face mai usoara atat logica miscarii obiectelor, cat si testarea cerintelor.
; Toate coordonatele oferite in comentarii sau in fisierul constants.rkt, se refera la
; coltul din stanga sus ale obiectelor!
;Inițial state
; Primul pas pe care trebuie să îl facem este să creăm starea inițială a jocului.
; Aceasta va fi salvată în (get-initial-state), și trebuie să incapsuleze toate informațiile
; necesare jocului, și anume: informații despre pasăre, despre pipes și, pentru bonus,
; despre powerups și despre variabilele de mediu.
; Recomandăm ca în pasăre, să rețineți, printre altele, informații despre y-ul curent
; și viteză pe y.
; Pe parcursul temei, în state, salvați coordonatele colțurilor din stânga sus ale obiectelor.
; Aceasta va face mai ușoară atât logică mișcării obiectelor, cât și testarea cerințelor.
; Toate coordonatele oferite în comentarii sau în fișierul variables.rkt se referă la
; colțul din stânga sus ale obiectelor!
;TODO 1
; După ce definiți structurile lui (get-initial-state) și a păsării, introduceți în prima
; pe cea din urmă. Colțul din stânga sus a păsării se va află inițial la:
; y = bird-inițial-y
; și x = bird-x.
; (get-initial-state) va fi o funcție care va returna starea inițială a jocului.
; BIRD:
; v: pozitia pe verticala
; v-y: viteza pe verticala
(struct bird (y v-y) #:transparent)
; PIPE:
; gap-y: pozitia gap-ului pe verticala
; x: pozitia pe orizontala
(struct pipe (gap-y x) #:transparent)
; VARIABLES:
; gravity
; momentum
; scroll-speed
(struct variables (gravity momentum scroll-speed) #:transparent)
; STATE:
; bird
; pipes
; variables
; score
(struct state (bird pipes variables score abilities) #:transparent)
; Getters for variables
(define (get-variables state) (state-variables state))
(define (get-variables-gravity variables)
(variables-gravity variables))
(define (get-variables-momentum variables)
(variables-momentum variables))
(define (get-variables-scroll-speed variables)
(variables-scroll-speed variables))
;TODO 8
; În starea jocului, trebuie să păstrăm informații despre pipes. Pe parcursul jocului,
; pipe-urile se vor schimba, unele vor fi șterse și vor fi adăugate altele.
; După ce definiți structura pentru pipe și pentru mulțimea de pipes din stare,
; adăugați primul pipe în starea jocului. Acesta se va află inițial în afară ecranului.
; Celelalte pipe-uri vor fi adăugate ulterior, poziționându-le după acest prim pipe.
; Atenție! Fiecare pipe este format din 2 părți, cea superioară și cea inferioară,
; acestea fiind despărțite de un gap de înălțime pipe-self-gap.
; Colțul din stânga sus al gap-ului dintre componentele primului pipe se va afla inițial la:
; y = (+ added-number (random random-threshold)), pentru a da un element de noroc jocului,
; și x = scene-width,
; pentru a-l forța să nu fie inițial pe ecran.
; Atenție! Recomandăm să păstrați în stare colțul din stânga sus al chenarului lipsa
; dintre cele 2 pipe-uri!
(define (get-initial-pipes)
(list (pipe (+ added-number (random random-threshold))
scene-width)))
;TODO 16
; Vrem o modalitate de a păstra scorul jocului. După ce definiți structura
; acestuia, adăugați scorul inițial, adică 0, în starea inițială a jocului.
; Atenție get-initial-state trebuie sa fie o funcție
; și trebuie apelată în restul codului.
(define (get-initial-state)
(state (bird bird-initial-y 0)
(get-initial-pipes)
(variables initial-gravity
initial-momentum
initial-scroll-speed)
0
(delay (abilities (fill-abilities '()
DISPLAYED_ABILITIES
ABILITIES)
'()))))
;TODO 2
; După aceasta, implementați un getter care extrage din structura voastră
; pasărea, și un al doilea getter care extrage din structura pasăre
; y-ul curent pe care se află această.
(define (get-bird state)
(state-bird state))
(define (get-bird-y bird)
(bird-y bird))
;TODO 4
; După aceasta, implementati un getter care extrage din structura voastră
; viteza pe y a păsării.
(define (get-bird-v-y bird)
(bird-v-y bird))
;TODO 3
; Trebuie să implementăm logică gravitației. next-state-bird va primi drept
; parametri o structură de tip pasăre, și gravitația(un număr real). Aceasta va adaugă
; pozitiei pe y a păsării viteza acesteia pe y, si va adaugă vitezei pe y a păsării,
; gravitația.
(define (next-state-bird curr-bird gravity)
(let ([curr-y (get-bird-y curr-bird)] [curr-v-y (get-bird-v-y curr-bird)])
(bird (+ curr-y curr-v-y) (+ curr-v-y gravity))))
;TODO 6
; Dorim să existe un mod prin care să imprimăm păsării un impuls.
; Definiți funcția next-state-bird-onspace care va primi drept parametri
; o structură de tip pasăre, momentum(un număr real), și va schimba viteza
; pe y a păsării cu -momentum.
(define (next-state-bird-onspace curr-bird momentum)
(let ([curr-v-y (get-bird-v-y curr-bird)])
(bird (get-bird-y curr-bird) (- momentum))))
; Change
; Change va fi responsabil de input-ul de la tastatură al jocului.
;TODO 7
; Acesta va primi drept parametri o structură de tip stare, și tasta pe
; care am apăsat-o. Aceasta va imprimă păsării momentum-ul, apelând
; funcția next-state-bird-onspace. Pentru orice altă tasta, starea rămâne aceeași.
(define (change curr-state pressed-key)
(let ([curr-bird (get-bird curr-state)]
[curr-mom (get-variables-momentum (get-variables curr-state))])
(cond [(key=? pressed-key " ")
(struct-copy state
curr-state
[bird (next-state-bird-onspace curr-bird curr-mom)])]
[else curr-state])))
;TODO 9
; După ce ați definit structurile pentru mulțimea de pipes și pentru un singur pipe,
; implementați getterul get-pipes, care va extrage din starea jocului mulțimea de pipes,
; sub formă de lista.
(define (get-pipes state)
(state-pipes state))
;TODO 10
; Implementați get-pipe-x ce va extrage dintr-o singură structura de tip pipe, x-ul acesteia.
(define(get-pipe-x pipe)
(pipe-x pipe))
(define (get-pipe-gap-y pipe)
(pipe-gap-y pipe))
;TODO 11
; Trebuie să implementăm logica prin care se mișcă pipes.
; Funcția move-pipes va primi drept parametri mulțimea pipe-urilor din stare
; și scroll-speed(un număr real). Aceasta va scădea din x-ul fiecărui pipe
; scroll-speed-ul dat.
(define (move-pipes pipes scroll-speed)
(map (lambda (curr-pipe)
(let ([curr-x (get-pipe-x curr-pipe)])
(struct-copy pipe
curr-pipe
[x (- curr-x scroll-speed)])))
pipes))
;TODO 12
; Vom implementa logica prin care pipe-urile vor fi șterse din stare. În momentul
; în care colțul din DREAPTA sus al unui pipe nu se mai află pe ecran, acesta trebuie
; șters.
; Funcția va primi drept parametru mulțimea pipe-urilor din stare.
;
; Hint: cunoaștem lățimea unui pipe, pipe-width
(define (clean-pipes pipes)
(filter (lambda (curr-pipe)
(>= (+ (get-pipe-x curr-pipe) pipe-width) 0))
pipes))
;TODO 13
; Vrem să avem un sursa continuă de pipe-uri.
; Implementati funcția add-more-pipes, care va primi drept parametru mulțimea pipe-urilor
; din stare și, dacă avem mai puțin de no-pipes pipe-uri, mai adăugăm una la mulțime,
; având x-ul egal cu pipe-width + pipe-gap + x-ul celui mai îndepărtat pipe, în raport
; cu pasărea.
(define (add-more-pipes pipes)
(if (equal? (length pipes) no-pipes)
pipes
(letrec ([last-pipe (car (reverse pipes))] [last-pipe-x (get-pipe-x last-pipe)])
(append pipes
(list (pipe (+ added-number (random random-threshold))
(+ last-pipe-x pipe-gap pipe-width)))))))
;TODO 14
; Vrem ca toate funcțiile implementate anterior legate de pipes să fie apelate
; de către next-state-pipes.
; Aceasta va primi drept parametri mulțimea pipe-urilor și scroll-speed-ul,
; și va apela cele trei funcții implementate anterior, în această ordine:
; move-pipes, urmat de clean-pipes, urmat de add-more pipes.
(define (next-state-pipes pipes scroll-speed)
(letrec ([moved-pipes (move-pipes pipes scroll-speed)]
[cleaned-pipes (clean-pipes moved-pipes)]
[added-pipes (add-more-pipes cleaned-pipes)])
added-pipes))
;TODO 17
; Creați un getter ce va extrage scorul din starea jocului.
(define (get-score state)
(state-score state))
;TODO 19
; Vrem să creăm logica coliziunii cu pământul.
; Implementati check-ground-collision, care va primi drept parametru
; o structura de tip pasăre, și returnează true dacă aceasta are coliziune
; cu pământul.
;
; Hint: știm înălțimea păsării, bird-height, și y-ul pământului, ground-y.
; Coliziunea ar presupune ca un colț inferior al păsării să aibă y-ul
; mai mare sau egal cu cel al pământului.
(define (check-ground-collision bird)
(let ([bird-bottom-corner (+ (get-bird-y bird) bird-height)])
(>= bird-bottom-corner ground-y)))
; invalid-state?
; invalid-state? îi va spune lui big-bang dacă starea curentă mai este valida,
; sau nu. Aceasta va fi validă atât timp cât nu avem coliziuni cu pământul
; sau cu pipes.
; Aceasta va primi ca parametru starea jocului.
;TODO 20
; Vrem să integrăm verificarea coliziunii cu pământul în invalid-state?.
;TODO 22
; Odată creată logică coliziunilor dintre pasăre și pipes, vrem să integrăm
; funcția nou implementată în invalid-state?.
(define (invalid-state? state)
(let ([bird (get-bird state)] [pipes (get-pipes state)])
(or (check-ground-collision bird) (check-pipe-collisions bird pipes))))
;TODO 21
; Odată ce am creat pasărea, pipe-urile, scor-ul și coliziunea cu pământul,
; următorul pas este verificarea coliziunii dintre pasăre și pipes.
; Implementati funcția check-pipe-collisions care va primi drept parametri
; o structură de tip pasăre, mulțimea de pipes din stare, și va returna
; true dacă există coliziuni, și false în caz contrar. Reiterând,
; fiecare pipe este format din 2 părți, cea superioară și cea inferioară,
; acestea fiind despărțite de un gap de înălțime pipe-self-gap. Pot există
; coliziuni doar între pasăre și cele două părți. Dacă pasărea se află în
; chenarul lipsă, nu există coliziune.
;
; Hint: Vă puteți folosi de check-collision-rectangle, care va primi drept parametri
; colțul din stânga sus și cel din dreapta jos ale celor două dreptunghiuri
; pe care vrem să verificăm coliziunea.
(define (check-pipe-collisions bird pipes)
; A1 - upper left corner of bird
; A2 - bottom right corner of bird
; B1 - upper left corner of upper pipe
; B2 - bottom right corner of upper pipe
; C1 - upper left corner of bottom pipe
; C2 - bottom right corner of bottom pipe
(ormap (lambda (pipe)
(let ([A1 (make-posn bird-x (get-bird-y bird))]
[A2 (make-posn (+ bird-x bird-width) (+ (get-bird-y bird) bird-height))]
[B1 (make-posn (get-pipe-x pipe) 0)]
[B2 (make-posn (+ (get-pipe-x pipe) pipe-width) (get-pipe-gap-y pipe))]
[C1 (make-posn (get-pipe-x pipe) (+ (get-pipe-gap-y pipe) pipe-self-gap))]
[C2 (make-posn (+ (get-pipe-x pipe) pipe-width) scene-height)])
(or (check-collision-rectangles A1 A2 B1 B2)
(check-collision-rectangles A1 A2 C1 C2))))
pipes))
(define (check-collision-rectangles A1 A2 B1 B2)
(match-let ([(posn AX1 AY1) A1]
[(posn AX2 AY2) A2]
[(posn BX1 BY1) B1]
[(posn BX2 BY2) B2])
(and (< AX1 BX2) (> AX2 BX1) (< AY1 BY2) (> AY2 BY1))))
;Next-state
; Next-state va fi apelat de big-bang la fiecare cadru, pentru a crea efectul de
; animație. Acesta va primi ca parametru o structură de tip stare, și va întoarce
; starea corespunzătoare următorului cadru.
;TODO 5
; Trebuie să integrăm funcția implementată anterior, și anume next-state-bird,
; în next-state.
;TODO 15
; Vrem să implementăm logică legată de mișcarea, ștergerea și adăugarea pipe-urilor
; în next-state. Acesta va apela next-state-pipes pe pipe-urile din starea curentă.
;TODO 18
; Vrem ca next-state să incrementeze scorul cu 0.1 la fiecare cadru.
(define (next-state curr-state)
(letrec ([curr-bird (get-bird curr-state)]
[curr-pipes (get-pipes curr-state)]
[curr-vars (get-variables curr-state)]
[curr-gravity (get-variables-gravity curr-vars)]
[curr-scroll-speed (get-variables-scroll-speed curr-vars)]
[curr-score (get-score curr-state)])
(struct-copy state
curr-state
[bird (next-state-bird curr-bird curr-gravity)]
[pipes (next-state-pipes curr-pipes curr-scroll-speed)]
[score (+ curr-score 0.1)])))
; draw-frame
; draw-frame va fi apelat de big-bang dupa fiecare apel la next-state, pentru a afisa cadrul curent.
;TODO 23
; Fiecare cadru va fi desenat in urmatorul mod:
; bird peste ground, peste scor, peste pipes, peste empty-scene.
;
; Hint: score-to-image primeste un numar real si intoarce scor-ul sub forma de imagine;
; Scor-ul îl puteți plasa direct la coordonatele date, fără a mai face translatiile menționate mai jos.
; Noi tinem minte coltul din stanga sus al imaginii, insa, la suprapunerea unei imagini A peste o alta imagine,
; coordonatele unde plasam imaginea A reprezinta centrul acesteia. Trebuie facute translatiile de la coltul din stanga
; sus la centrul imaginilor.
; Variabile folosite in aceasta functie:
; bird -> bird-width si bird-height
; ground -> ground-y si ground-height, acesta va acoperi intreaga latime a ecranului
; scor -> text-x si text-y
; pipes -> pipe-width si pipe-height
(define bird-image (rectangle bird-width bird-height "solid" "yellow"))
(define ground-image (rectangle scene-width ground-height "solid" "brown"))
(define initial-scene (rectangle scene-width scene-height "solid" "white"))
(define (get-pipe-img pipe-height) (rectangle pipe-width pipe-height "solid" "green"))
(define text-family (list "Gill Sans" 'swiss 'normal 'bold #f))
(define (score-to-image x)
(if SHOW_SCORE
(apply text/font (~v (round x)) 24 "indigo" text-family)
empty-image))
(define (place-ground scene)
(place-image ground-image (quotient scene-width 2) (+ ground-y (quotient ground-height 2)) scene))
(define (place-score score scene)
(place-image (score-to-image score) text-x text-y scene))
(define (place-bird bird-y scene)
(place-image bird-image (+ bird-x (quotient bird-width 2)) (+ bird-y (quotient bird-height 2)) scene))
(define (draw-frame state)
(let ([bird-y (get-bird-y (get-bird state))]
[score (get-score state)]
[pipes (get-pipes state)])
(place-bird bird-y (place-score score (place-ground (place-pipes pipes initial-scene))))))
; Folosind `place-image/place-images` va poziționa pipe-urile pe scenă.
(define (place-pipes pipes scene)
(if (empty? pipes)
scene
(letrec ([upper-pipe-x (+ (get-pipe-x (car pipes))
(quotient pipe-width 2))]
[upper-pipe-y (quotient (get-pipe-gap-y (car pipes)) 2)]
[lower-pipe-x upper-pipe-x]
[lower-pipe-y (quotient (+ scene-height (get-pipe-gap-y (car pipes)) pipe-self-gap) 2)])
(place-pipes (cdr pipes)
(place-image (get-pipe-img (- scene-height (get-pipe-gap-y (car pipes)) pipe-self-gap))
lower-pipe-x
lower-pipe-y
(place-image (get-pipe-img (get-pipe-gap-y (car pipes)))
upper-pipe-x
upper-pipe-y
scene))))))
; Bonus
; Completați abilities.rkt mai întâi, aceste funcții căt, apoi legați
; această funcționalitate la jocul inițial.
; Abilitatea care va încetini timpul va dura 10 de secunde, va avea imaginea (hourglass "mediumseagreen")
; va avea inițial poziția null si va modifica scrolls-speed dupa formulă
; scroll-speed = max(5, scroll-speed - 1)
(define slow-ability (ability (hourglass "mediumseagreen")
10
null
(lambda (scroll-speed)
(max 5 (sub1 scroll-speed)))))
; Abilitatea care va accelera timpul va dura 30 de secunde, va avea imaginea (hourglass "tomato")
; va avea inițial poziția null si va modifica scrolls-speed dupa formulă
; scroll-speed = scroll-speed + 1
(define fast-ability (ability (hourglass "tomato")
30
null
add1))
; lista cu toate abilităţile posibile în joc
(define ABILITIES (list fast-ability slow-ability))
; Întoarce abilităţile din stare, cu o reprezentare
; intermediară care trebuie să conțină două liste:
; - lista abilităţilor vizibile (încarcate în scenă dar nu neaparat vizibile pe ecran).
; - lista abilităţilor activate (cu care pasărea a avut o coloziune).
(define (get-abilities x) (force (state-abilities x)))
; Întoarce abilităţile vizibile din reprezentarea intermediară.
(define (get-abilities-visible x) (abilities-visible x))
; Întoarce abilităţile active din reprezentarea intermediară.
(define (get-abilities-active x) (abilities-active x))
; Șterge din reprezentarea abilităţilor vizibile pe cele care nu mai sunt vizibile.
; echivalent cu clean-pipes.
(define (clean-abilities abilities)
'your-code-here)
; (let ([visible (get-abilities-visible abilities)])
; (filter (lambda (curr-ability)
; (>= (+ (posn-x (get-ability-pos curr-ability)) 20) 0))
; visible)))
; Muta abilităţile vizibile spre stanga.
; echivalent cu move-pipes.
(define (move-abilities abilities scroll-speed)
'your-code-here)
; (let ([visible (get-abilities-visible abilities)])
; (map (lambda (curr-ability)
; (let ([curr-x (posn-x (get-ability-pos curr-ability))]
; [curr-y (posn-y (get-ability-pos curr-ability))])
; (struct-copy ability
; curr-ability
; [pos (make-posn (- curr-x scroll-speed) curr-y)])))
; visible)))
; Scurge timpul pentru abilităţile activate și le sterge pe cele care au expirat.
; Puteți să va folosiți de variabila globală fps.
(define (time-counter abilities)
'your-code-here)
; (let ([active (get-abilities-active abilities)])
; (filter (lambda (curr-ability)
; (positive? (get-ability-time curr-ability)))
; (map (lambda (curr-ability)
; (let ([curr-time (get-ability-time curr-ability)])
; (struct-copy ability
; curr-ability
; [time (- curr-time (/ 1 fps))])))
; active))))
; Generează următoarele abilitați vizibile.
; *Atentie* La orice moment pe scena trebuie să fie exact DISPLAYED_ABILITIES
; abilităţi vizibile
; Folosiți funcția fill-abilities din abilities.rkt cât si cele scrise mai sus:
; move-abilities, clean-abilities, time-counter, etc..
(define (next-abilities-visible visible scroll-speed)
'your-code-here)
; (letrec ([moved-abilities (move-abilities visible scroll-speed)]
; [cleaned-abilities (clean-abilities moved-abilities)]
; [filled-abilities (fill-abilities cleaned-abilities
; (- DISPLAYED_ABILITIES (length cleaned-abilities))
; ABILITIES)])
; filled-abilities))
; Generează structura intermediară cu abilități.
; Observați ca nu există next-abilities-active aceastea sunt acele abilităti
; întoarse next-abilities-visible care au o coliziune cu pasărea.
; Puteti folosi `filer`/`filter-not` ca sa verificați ce abilităti au și abilitați
; nu au coliziuni cu pasărea sau puteti folosi `partition`
(define (next-abilities abilities bird scroll-speed)
'your-code-here)
; Dând-use variabilele actuale și abilitațile calculați care vor
; variabile finale folosite în joc
; Folositi compose-abilities
; Atenție când apelați `next-variables` în next-state dați ca paremetru
; initial-variables și nu variabilele aflate deja în stare
; In felul acesta atunci când
(define (next-variables variables abilities)
'your-code-here)
; Folosind `place-image/place-images` va poziționa abilităţile vizibile la ability pos.
(define (place-visible-abilities abilities scene)
'your-code-here)
; Folosind `place-image/place-images` va poziționa abilităţile active
; în partea de sus a ecranului lângă scor.
; Imaginiile vor scalate cu un factor de 0.75 și așezate plecând
; de la ability-posn (constantă globală) cu spații de 50 de px.
; Imaginea cu indexul i va fi așezată la (ability-posn.x - 50*i, ability-posn.y)
(define (place-active-abilities abilities scene)
'your-code-here)
(module+ main
(big-bang (get-initial-state)
[on-tick next-state (/ 1.0 fps)]
[to-draw draw-frame]
[on-key change]
[stop-when invalid-state?]
[close-on-stop #t]
[record? #f]))

View File

@ -0,0 +1,33 @@
#lang racket
(require math)
(provide make-predictive)
(provide remove-predictive)
(provide discrete-dist)
(provide (rename-out [_random random]))
(provide (rename-out [_sample sample]))
(define r random)
(define s sample)
(define seq '(32))
(define (_random . x) (apply r x))
(define (_sample . x) (apply s x))
(define (fake-random . x)
(when (> (length seq) 1) (set! seq (cdr seq)))
(car seq))
(define (fake-sample . x)
(match-let* ([(list d n) x]
[L (discrete-dist-values d)])
(cond [(> (- n (length L)) 0)
(append L (make-list (- n (length L)) (car L)))]
[(equal? n 0) '()]
[else L])))
(define (make-predictive x)
(set! seq (cons 0 x))
(set! r fake-random)
(set! s fake-sample))
(define (remove-predictive)
(set! r sample)
(set! s random))

View File

@ -0,0 +1,57 @@
I. Structuri folosite
---------------------
Structura principala folosita pentru aceasta tema este state, care inglobeaza
alte structuri cum ar fi bird, pipe, variables si abilities. Valoarea initiala
a acestei structuri se poate obtine prin apelul functiei get-initial-state,
care contine toate datele necesare de la momentul 0 al jocului.
II. Logica jocului
------------------
Pentru a eficientiza timpul si efortul de lucru am impartit scheletul de cod
in mai multe parti care se ocupa cu lucruri diferite ce vor fi puse cap la
cap in final.
1. BIRD
In prima parte a TODO-urilor, fisierul main se ocupa cu definirea getterilor
si logicii miscarii bird-ului, ca in final sa rezulte functia next-state-bird
care poate asigura functionarea bird-ului pe parcursul jocului.
2. PIPES
Logica pentru pipes se asemana cu cea de la bird, elementul nou fiind ca se
definesc functiile de move-pipes, clean-pipes si add-more-pipes care se
integreaza in next-state-pipes. Aici am folosit foarte mult functionale precum
map sau filter si functia struct-copy pentru a obtine structuri noi.
3. SCORE
Pentru aceasta parte a fost nevoie doar de un getter si integrarea variabilei
score in state.
4.COLLISIONS
Pentru verificarea coliziunilor am integrat functiile check-ground-collision
si check-pipe-collision in invalid-state?. Implementarea a fost relativ usoara,
deoarece in schelet a fost data functia check-collision-rectangles care ajuta
la detectarea coliziunilor dintre dreptunghiuri.
5. DRAWING
Pentru punerea pe ecran a imaginilor am definit mai multe functii cum ar fi
place-ground sau place-bird care apelate in draw-frame au facut posibila
afisarea bird-ului, pipe-urilor, etc. Dificultatea aici a fost functia
place-pipes deoarece am incercat o abordare cu place-images care insa n-a mers.
Asa ca am luat fiecare pipe in parte, am calculat coordonatele si le-am pus
peste scena goala.
6. ABILITIES
Pentru abilities am folosit functiile delay si force pentru a intarzia
calcularea lor pana in momentul cand era nevoie, deoarece altfel checkerul
nu-mi dadea punctajul pentru subpunctele respective. Aici nu am reusit sa
implementez afisarea pe ecran a abilitatilor, ci doar logica obtinerii
abilitatilor vizibile.
III. Concluzii si rezultate
---------------------------
Cand am incercat sa testez pe checker am observat ca pentru ultimul test de
la bonus, checkerul da o eroare pe care n-am putut sa o rezolv. El valideaza
toate testele pana la logica punerii abilitatilor pe ecran. Per total a fost
o tema foarte folositoare deoarece mi-a intarit cunostintele despre functionale,
intarzieri, structuri, etc in racket.