Näytetään tekstit, joissa on tunniste Racket-harjoitukset. Näytä kaikki tekstit
Näytetään tekstit, joissa on tunniste Racket-harjoitukset. Näytä kaikki tekstit

maanantai 29. toukokuuta 2017

Kuvakoodausta kevään Racket MOOC:ssa

Kevään Racket MOOC on jälleen ohi. Tämä oli sarjassansa 4. Koodiaapinen MOOC. Kurssin vetäjän näkökulmasta hauskinta on ollut seurata kuvakoodausjaksojen satoa. Heti ensimmäisen viikon jälkeen palautusseinällä kuhisi tällaisia kuvia:


Tässä tehtävänä oli koodata jokin yksinkertainen lippu tai logo, mutta mukaan mahtuu myös monta aivan omaa luomusta.

Kurssin viimeisessä ohjelmointitehtävässä sai päästää oman luovuutensa täysin valloilleen Racket Turtlen kanssa ja tällaisia kuvia sieltä sitten syntyi:



Eikä kurssilla toki tarvinnut pitäytyä still-kuvissa, sai niitä myös animoida. Tässä muutama makupala:

Testaa animaatiota liikuttamalla jäätelöä hiirellä
Testaa animaatiota
Testaa animaatiota liikuttamalla hiirtä
Moni kurssilainen innostuikin ohjelmoinnista juuri kuvakoodaamisen kautta. Siitä on hyvä aloittaa ensi syksynä 7. luokkalaisten kanssa kun uusi OPS tulee ohjelmointeinen voimaan. Täältä saat lisätietoja mm. kuvakoodaamisesta: racket.koodiaapinen.fi.

torstai 30. kesäkuuta 2016

Peliohjelmointikurssilla opittua

Kahdeksannen luokan peliohjelmointikurssi jatkui keväällä. Ensimmäisellä kokoontumiskerralla tiimit viimeistelivät suunnitelmansa OneDrive:ssa oleviin dokumentteihin. Me opettajat toimimme katselmoijina ja kyselimme epäselviä asioita sekä tarkennuksia ja lopulta suunnitelmat olivat jotakuinkin yksiselitteisiä niin, että graafikot ja koodarit saattoivat aloittaa omat hommansa.

Koodarit aloittivat tutustumalla opettajan Racket:illä koodaamaan pelipohjaan, jossa oli valmiina hahmojen piirtäminen ruudulle, tietorakenteet "peli" sekä "hahmo", hahmojen liikkumiseen sekä pelaajan ja toisen pelihahmon törmäyksen havaitsemiseen liittyvät funktiot sekä pelimoottori big-bang. Tietorakenteen kentille oli myös valmiiksi koodaattu set- ja get-funktiot.

Peli-tietorakenteessa oli seuraavat kentät:
  • tilanne : Symboli (esim. 'alku 'käynnissä 'pause 'loppu)
  • taso : Luku
  • pisteet : Luku
  • aika : Luku
  • pelaajat : Lista<hahmo>
  • dynaamiset : Lista<hahmo>
  • staattiset : Lista<hahmo>
 Hahmo-tietorakenteessa oli seuraavat kentät:
  • tyyppi : Symboli (esim. 'pejaaja 'kerättävä 'vaara)
  • id : Luku
  • tila : Symboli (esim. 'elossa 'kuollut)
  • varusteet : Lista<symboli> (esim. 'lippis 'pipo)
  • sijainti : Posn (x- ja y-koordinaatti)
  • suunta : Posn (vektori jossa x:n ja y:n suuntainen siirtymä)
  • laskuri : Luku (jos 0 niin ei liiku)
  • asento : Symboli (esim. 'vasen 'oikea)
Vaikka pelipohjassa oli paljon koodia, se ei vielä toteuttanut yhdenkään pelin logiikkaa joten ensimmäinen vaihe oli suunnitella miten kunkin ryhmän peli käyttäisi tietorakenteita hyväkseen, millaisia tiloja pelillä ja hahmolla piti olla jne. Tämä tehtiin isolle paperiarkille.

T'ässä pelissä sipsipussin piti kerätä hyppimällä juomia ja vältellä sivulta tulevia Shrekkejä (toinen "vuoristo"-taso jäi toteuttamatta)
Kun suunnitelma oli valmis, lähdimme tekemään pelejä yhdessä. Vaikka pelit olivatkin hyvin erilaisia, yllättävän monessa pelissä oli samoja piirteitä, jotka saatoimme koodata yhdessä opettajan johdolla kuitenkin niin, että kukin koodaripari sovelsi vaiheen omaan peliinsä sopivaksi. Lähdimme ensin luomaan kuhunkin peliin liittyviä hahmoja ja laitoimme ne liikkumaan oikeaan suuntaan (säätämällä suuntavektoria). Koska meillä ei ollut grafiikoita, ryhmät käyttivät erivärisiä ympyröitä, kolmioita ja nelikulmioita hahmojen kuvina. Ensimmäisinä koodasimme siis funktiot: tee-hahmo ja piirrä-hahmo. Kutsuimme tee-hahmo-funktiota riittävän monta kertaa, että saimme big-bangin käynnistyttyä muutamia hahmoja liikkumaan. Seuraava vaihe oli lisätä funktio, joka toteuttaa pelaajan liikkumisen käyttämällä nuolinäppäimiä. Koodasimme siis funktion: hoida-näppäimet. Kun pelaaja liikkui saatoimme lisätä törmäyksen havaitsemisen sekä pisteiden lisäämisen tai vähentämisen riippuen törmäyksen kohteesta. Nämä toteutettiin funktioiden: päivitä-peli ja törmäsikö? avulla. Lopuksi lisäsimme funktion, joka automaattisesti arpoi peliin lisää hahmoja. Tämä toteutettiin funktion lisää-hahmoja ja arvo-hahmot avulla.

Zombipelissä piti ampua sivuilta tulevia zombeja (huomaa läpinäkyvä ase ja matalalla liitävät ammukset)
Näiden perustoimintojen lisäksi, yhdessä pelissä hahmolle (sipsipussi) piti lisätä painovoima, eli se piti saada hyppäämään ja sen jälkeen putoamaan takaisin. Toisessa pelissä pisteiden laskenta toimi niin, että kolmen "vihanneksen" jälkeen pisteet nollautuivat kokonaan, eli peli loppui ja alkoi taas uudelleen. Kolmannessa pelissä hahmojen lisäksi taustakuva liikkui ajan suhteen, näin saatiin aikaan hahmon putoamisilluusio. Neljännessä pelissä hahmo ampui luoteja hiiren avulla, joten siihen piti lisätä myös hoida-hiiri-funktio. Viides peli jäi alkutekijoihinsä, koska koodareilta loppui mielenkiinto koodaamiseen melko nopeasti. Tämän ryhmän kanssa teimme niin, että graafikot siirtyivät kuvien valmistuttua koodaamaan ja ne ottivat käyttöön Scratch-työkalun, että saisivat jotain valmiiksi siinä  lyhyessä ajassa mitä oli enää jäljellä.

Tässä pelissä sankari hyppää katolta ja kerää matkallaan ES:iä ja nugetteja ja samalla väistelee lintuja (pallot kuvaavat ruokia, jotka jäivät graafikoilta toteuttamatta)
Pelejä koodattiin 7 kaksoistuntia ja samaan aikaan graafikot tekivät peligrafiikoita kuvataiteen opettajan ohjauksessa. Ensimmäisen kerran yritimme liittää kuvia ja koodia yhteen toukokuun alussa. Siinä vaiheessa tuli ilmi montakin ongelmaa, hahmojen kuvissa oli turhia valkoisia taustoja ja kuvia ei oltu rajattu mahdollisimman pieniksi, jotta törmäysehdot toimisivat moitteetta. Myöskään putoamisilluusion luomiseen tarkoitetut talon palaset eivät olleet sellaiset kuin piti (palat olivat eri kokoisia). Graafikot saivat tärkeää palautetta ja he palasivat korjaamaan kuvia, ja koodarit koodasivat pelejä hieman lisää. Kurssin loppu tuli kuitenkin vastaan aivan liian nopeasti, ja lopulta sovimme niin että opettaja koodaa jokaista peliä eteenpäin max 1h per peli. Lopulta neljän pelin loppuun koodamiseen meni 2h15min. Hankalin peli oli zombiepeli, koska siinä sekä zombit että ammukset liikkuivat ja ammuksen ja zombin törmäys piti havaita, kuten myös zombin ja pelaajan törmäys.

Tässä pelissä tehtävänä oli syödä taivaalta putoavia ruokia ja vältellä vihanneksi, tosin vihannekset jäivät graafikoilta piirtämättä ja tilalle tuli läjä sitä itseään.
Pelin lisäksi ryhmän piti tehdä pelille mainossivu, ja tämä toteutettiin blogikirjoituksen muodossa. Ryhmän graafikko ja tarinavastaava tekivät tämän kurssin lopussa. Vielä viimeiselläkin kerralla työstimme vielä pelejä, koska grafiikoissa oli edelleen puutteita: kerrostalon seinässä oli reikiä joista paistoi taivas, pitsapalassa oli turhaa näkymätöntä reunaa ja zombit ja zombien ampuja oli vielä piirtopöydällä. Lopulta kaikki viisi peliä olivat jotakuinkin pelattavassa kunnossa, hyvin riisuttuina versioina tosin mutta kuitenkin. Muutama graafinen elementti jäi puuttumaan, ilmeisesti pienten kommunikaatio-ongelmien takia ja zombien ampujan asekin jäi läpinäkyväksi ja ammusten lähtötaso säätämättä mutta näin voi käydä kun aika vain loppuu kesken.

Tässä pelissä piti hyppiä tasoilta toiselle ja kerätä rahoja, tasoja piti olla eri värisiä ja niiden piti kadota ja tulla taas esiin mutta tämä peli ei toteutunut aivan suunnitellulla tavalla
Kaiken kaikkiaan tämä oli hyvin mielenkiintoinen projekti. Tässä kurssissa tarkoitus ei ollut varsinaisesti oppia ohjelmointia vaan pääpaino oli uuden pelin ideoinnissa sekä projektityöskentelyn opettelussa. Ainakin ryhmille tuli selväksi, että jokaisen työpanosta tarvitaan, eikä peli tule valmiiksi jos jokin osa-alue jää tekemättä. Pelin suunnittelu oli aluksi vaikeaa, mutta lopulta suunnitelluista peleistä tuli jopa hieman turhan monimutkaisia toteutettavaksi näin lyhyen kurssin aikana. Pelipohja toimi siinä mielessä, että sen avulla pystyttiin tekemään nämä pelit, mutta kovin helppokäyttöinen se ei vieläkään ole. Lausekielen (tällä kurssilla Racket) käyttäminen näin suppealla kurssilla ei ehkä vastaa tarkoitustaan varsinkin kuin osalla koodareista ei ollut aikaisempaa kokemusta ohjelmoinnista. Asian (ohjelmointi) syväoppiminen ja pelin valmiiksi saaminen eivät ehkä toteudu saman kurssin puitteissa... Ensi lukuvuonna 8. luokan kurssin nimi onkin pelkkä "ohjelmointi". Katsotaan saako "ohjelmointi" enemmän tilaa, kun "peli"-aspekti jää pois.

Tässä pelien esittelyt löytyvät kurssin blogissa.

perjantai 27. marraskuuta 2015

Programming Arduino UNO with Racket

Some weeks ago I found out about this Arduino-RaspberryPi robot that you can program using Racket language and DrRacket. I contacted the creators and got some Arduino boards and accessories to play with.

Normally you would program Arduino using C/C++ and their own development environment. Since I have chosen to use Racket for teaching programming in my math class and other computer science classes, to make it easier to me and my students I would prefer to use Racket also in my physics class. And thanks to Mr Raimondi and Mr Margolis now I can!

In addition to DrRacket installation you need to install Arduino UNO USB driver to your laptop. It comes with the Arduino IDE. Arduino UNO needs to have the ASIP firmware installed, also you need to include one Racket - file "AsipMain.rkt" and you are good to go.

Here are our first two working demos:

First one blinks two leds:



(require "AsipMain.rkt")
(define LED 13)
(define LED2 12)

(open-asip)

(set-pin-mode! LED OUTPUT_MODE)
(set-pin-mode! LED2 OUTPUT_MODE)

(define (my-program)
  (begin
    (digital-write LED HIGH)
    (sleep 0.2)
    (digital-write LED LOW)
    (digital-write LED2 HIGH)
    (sleep 0.2)
    (digital-write LED2 LOW)
    (my-program)))

(my-program) 


And in the second one the led is controlled from the laptop's keyboard (spacebar):



(require "AsipMain.rkt")
(require 2htdp/universe)
(require 2htdp/image)


(define LED 13)
(open-asip)
(set-pin-mode! LED OUTPUT_MODE)

(define (draw-image y)
  empty-image)

(define (key1 y n)
  (if (key=? n " ")

      (begin (digital-write LED HIGH)
             #t)
      y))      

(define (key2 y n)
  (if (key=? n " ")

      (begin (digital-write LED LOW)
             #f)         
      y))

(big-bang #f
          (on-key key1)
          (on-release key2)
          (to-draw draw-image))


One of my students, 13 year old Lauri wrote a big part of this code and connected the wires for the demo. Thanks! We will develop this further in the coming weeks. I'm planning to use this to teach physics and programming this spring.

perjantai 21. elokuuta 2015

Mondrian Art - Racket Turtle

Kuulin tästä ohjelmointioppitunnista, jossa tarkoituksena on ohjelmoida Mondrian Art - kuvia (katso myös Artsy.net). Pitihän sitä kokeilla myös omalla Racket Turtlella. Tein ensin pohjan johon generoin satunnaisesti eri kokoisia ja eri värisiä laatikoita eri paikkoihin. Sitten väritin reunat Racket Turtlella.

Tässä oma näkemykseni Mondrian Art:ista:

Mondrian Art ohjelmoituna DrRacket:llä 

Täsäs koodi jolla generoin pohjakuvan:

(require teachpacks/racket-turtle)
(require 2htdp/image)

(define BG (empty-scene 500 500))
(define colors (list "red" "yellow" "blue" "black"))
 

(define (get-color i)
  (list-ref colors i))

(define (place-rectangle x y bg)
  (place-image (rectangle (* 40 (random 5)) 

                          (* 40 (random 5)) 
                          "solid" 
                          (get-color (random 4)))
                           x y bg))

(define (create-bg x y times bg)
  (if (< times 0)
      bg
      (create-bg (+ x (* 20 (random 5))) 

                 (+ y (* 20 (random 5))) 
                 (sub1 times) 
                 (place-rectangle x y bg))))

(define IMG (create-bg 0 250 10 

                   (create-bg  300 0 10 
                          (create-bg 0 0 100 BG))))

Tämä koodi aikaansai siis seuraavan kuvan:

Pohjakuva (BG-IMG1)
 Tämän päälle piti enää lisätä mustia viivoja Racket Turtlen avulla. 

(define TURTLE-BG-IMG1
(list (set-bg-image BG-IMG1)
      (change-color "black")
      (pen-up) (go-to 20 300)
      ;horizontal rows
      (pen-down)(change-pen-size 5)(go-to 20 500)

      (pen-up)(go-to 40 0)
      (pen-down)(change-pen-size 3)(go-to 40 300)

      (pen-up)(go-to 120 0)
      (pen-down)(change-pen-size 4)(go-to 120 300)

      (pen-up)(go-to 140 180)
      (pen-down)(change-pen-size 3)(go-to 140 500)

      (pen-up)(go-to 160 420)
      (pen-down)(change-pen-size 2)(go-to 160 500)

      (pen-up)(go-to 180 340)
      (pen-down)(change-pen-size 2)(go-to 180 500)

      (pen-up)(go-to 220 0)
      (pen-down)(change-pen-size 3)(go-to 220 340)

      (pen-up)(go-to 260 0)
      (pen-down)(change-pen-size 4)(go-to 260 500)

      (pen-up)(go-to 280 30)
      (pen-down)(change-pen-size 2)(go-to 280 150)

      (pen-up)(go-to 300 360)
      (pen-down)(change-pen-size 3)(go-to 300 500)

      (pen-up)(go-to 320 20)
      (pen-down)(change-pen-size 3)(go-to 320 120)

      (pen-up)(go-to 360 0)
      (pen-down)(change-pen-size 4)(go-to 360 360)

      (pen-up)(go-to 380 280)
      (pen-down)(change-pen-size 3)(go-to 380 500)

      (pen-up)(go-to 420 280)
      (pen-down)(change-pen-size 3)(go-to 420 360)

      (pen-up)(go-to 460 280)
      (pen-down)(change-pen-size 3)(go-to 460 500)

      (pen-up)(go-to 320 20)
      ; vertical rows
      (pen-down)(change-pen-size 4)(go-to 500 20)

      (pen-up)(go-to 400 20)
      (pen-down)(change-pen-size 2)(go-to 500 20)

      (pen-up)(go-to 120 30)
      (pen-down)(change-pen-size 4)(go-to 280 30)

      (pen-up)(go-to 280 80)
      (pen-down)(change-pen-size 4)(go-to 500 80)

      (pen-up)(go-to 280 120)
      (pen-down)(change-pen-size 4)(go-to 320 120)

      (pen-up)(go-to 40 110)
      (pen-down)(change-pen-size 3)(go-to 120 110)

      (pen-up)(go-to 120 150)
      (pen-down)(change-pen-size 4)(go-to 280 150)

      (pen-up)(go-to 120 180)
      (pen-down)(change-pen-size 5)(go-to 220 180)

      (pen-up)(go-to 40 230)
      (pen-down)(change-pen-size 4)(go-to 120 230)

      (pen-up)(go-to 20 300)
      (pen-down)(change-pen-size 2)(go-to 140 300)

      (pen-up)(go-to 260 280)
      (pen-down)(change-pen-size 4)(go-to 500 280)

      (pen-up)(go-to 140 340)
      (pen-down)(change-pen-size 3)(go-to 220 340)

      (pen-up)(go-to 300 360)
      (pen-down)(change-pen-size 4)(go-to 380 360)

      (pen-up)(go-to 380 440)
      (pen-down)(change-pen-size 5)(go-to 500 440)

      (pen-up)(go-to 400 450)))
(define image1 (draw TURTLE-BG-IMG1))
(crop 0 0 500 500 image1) 

sunnuntai 12. heinäkuuta 2015

Racket Turtle (versio 0.5)

Racket Turtle on kehittänyt itselleen kesän aikana uusia taitoja. Nyt kynän paksuutta ja viivan tyyliä voi muutella, taustan värin voi vaihtaa ja Turtlelle voi aktivoida myös "leimasintoiminnon". Lisäksi piirtoalueen kokoa ja piirtonopeutta voi säätää. Turtlea voi ohjata myös kävelemään suoraan tiettyyn koordinaattipisteeseen, Turtlelle voi aktivoida peilaustoiminnon ja origon paikan voi säätää haluamakseen. Ohjeet Racket Turtlen käyttöön löytyy täältä.

Lisäys 16.9.2015:
Racket Turtlen voi nyt asentaa koneelle suoraan Racket Package managerin kautta. Mene DrRacket:in valikkoon File -> Package Manager. Kirjoita Package Source - kenttään: teachpacks ja paina <enter>. Paketti asenttuu automaattisesti profiiliisi (HUOM! ei vaadi asennusoikeuksia). Tämän jälkeen voit käyttää Racket Turtlea seuraavien ohjeiden mukaisesti:

Jokaisen koodiesimerkin (alla) alussa pitää olla nämä määritykset:

(require 2htdp/image)
(require teachpacks/racket-turtle)


1. Taustavärin ja kynän paksuuden muuttaminen sekä kynän värin määrittely vaihtuvaksi.


Näiden kuvien piirtämisessä on käytetty rekursiota, jossa kuljettu matka kasvaa kierros kierrokselta, ensimmäisessä kasvaa myös kynän paksuus. Kynän väriksi on annettu yhden värin asemasta lista värejä, joita Turtle toistaa.

(define VÄRIT (list "red" "blue" "green" "yellow" "purple"))
 

(define (levenevä-spiraali2 p l k kerrat)
  (if (<= kerrat 0)
      empty
      (cons (sivu p l k)

           (levenevä-spiraali2 (+ p 5)
                               (+ l 1) 
                               k 
                               (sub1 kerrat))))))

(define levenevä-spiraali (list (change-bg-color "black")
                                (change-color VÄRIT) 
                                (levenevä-spiraali2 1 1 45 45)))
(draw levenevä-spiraali)


Levenevä kynän paksuus ja toistuvat värit
(define VÄRIT2 (list "red" "green" "yellow" "purple")) 

(define (spiraali k p kerrat)
  (if (< kerrat 0)
      empty
      (append (list (forward p)(turn-left k)) 

              (spiraali k (+ p 2)(sub1 kerrat)))))

(define spiraalikuvio
  (list (change-pen-size 2)
        (change-bg-color "black")
        (change-color VÄRIT2)
        (spiraali 91 1 152)))

(draw spiraalikuvio)


Toistuvilla väreillä saa aikaan näyttäviä kuvioita
Spiraalikuvio WeSchemessä

2. Kynän tilalla on leimasin toiminto, joka piirtää leiman Turtlen sijainnin kohdalle. Leimasimelle voi antaa listan kuvia, jotka se piirtää yksi toisensa jälkeen.


Kuvan kukkalista on tehty rekursiivisesti samoin kuin alemman kuvan tähdet. Värit on saatu random-toiminnolla.

(define (lehti koko väri)  (ellipse (* 8 koko) koko "solid" väri))

(define (lehdet koko väri)
  (overlay (lehti koko väri)
           (rotate 90 (lehti koko väri))))

(define (tee-kukka2 koko väri)
  (overlay (circle (/ koko 2) "solid" "white")
           (lehdet koko väri)
           (rotate 45 (lehdet koko väri))))

(define (kukka-spiraali k p kerrat)
  (if (< kerrat 0)
      empty
      (append (list (forward p)(turn-left k)) 

              (kukka-spiraali k (+ p 6)(sub1 kerrat)))))

(define (tee-kukat määrä koko)
  (if (<= määrä 0)
      empty
      (cons (rotate koko (tee-kukka2 koko 

                                     (make-color (random 255)
                                                 (random 255)
                                                 (random 255))))    
            (tee-kukat (sub1 määrä)(add1 koko)))))
                  
(define kukkaspiraali (list (stamper-on (tee-kukat 20 1))
                            (pen-up)
                            (kukka-spiraali 25 1 20)))

(draw kukkaspiraali)


Kukkaspiraali, jossa random-värisiä kukkia
Kukkaspiraali WeSchemessä

(define (tee-tähdet määrä koko)
  (if (<= määrä 0)
      empty
      (cons (rotate koko 

                   (star koko 
                         "solid" 
                         (make-color (random 255)
                                     (random 255)
                                     (random  255)))) 
            (tee-tähdet (sub1 määrä)(add1 koko)))))       
      

(define tähtispiraali (list (stamper-on (tee-tähdet 100 1))
                            (pen-up)
                            (spiraali 91 1 100)))

(draw tähtispiraali)

Rekursiiviset random-tähdet spiraalissa
Tähtispiraali WeSchemessä.

3. Taustaruudukon piirtäminen, origon sijoittaminen kuvan keskelle, piirtoalueen koon muuttaminen isommaksi, kynän tyylin muuttaminen sekä kuvan piirtämisen koordinaattipisteiden avulla.


Tässä kuvassa punaiset pampulat on tehty leimasimella ja katkoviiva Turtlen kynällä. Taustaruudukon pikkuruutujen kokoa ja väriä voi muuttaa. Kuvan koko on 600x600.

(define koordinaatistokuva
  (list 
(set-origin)
        (set-bg-grid 30 30 "blue")
        (mirror-x-on)
        (mirror-y-on)
        (stamper-on (circle 5 "solid" "red"))
        (change-pen-style "dot")
        (change-pen-size 3)
        (change-color "red")  
        (pen-up)
        (go-to 60 0)
        (pen-down)
        (go-to 120 60)
        (go-to 60 60)
        (go-to 60 120)
        (go-to 0 60)
        (go-to -60 120)
        (go-to -60 60)
        (go-to -120 60)
        (go-to -60 0)))


(draw-custom koordinaatistokuva 600 600 0)


Koordinaatistoharjoitus
Koordinaatistokuva WeSchemessä

4. Peilaustoiminnolla piirtäminen


Tässä on aktivoitu peilaus sekä x-akselin, että y-akselin suunnassa (animaation taustan värin vaihtelu johtuu  GIMP2:sta). Myös kynän paksuutta on muutettu.

(define (tee-kaari väri koko kynä)
  (list (change-color väri)
        (change-pen-size kynä)
        (repeat (round (* (/ 90 koko))) 

                       (list (forward koko) (turn-left koko)))))

(define (tee-lehti väri koko kynä)
  (list (tee-kaari väri koko kynä)
        (turn-left 90)
        (tee-kaari väri koko kynä)))

(define (tee-kukka väri koko kynä)
  (list (mirror-x-on)
        (mirror-y-on)
        (repeat 2 (tee-lehti väri koko kynä))))
 

(define peilauskukka (list (tee-kukka "red" 3 5)
                           (turn-left 45)
                           (tee-kukka "pink" 3 2)))

(draw-and-store peilauskukka)


Turtle peilaustoiminnolla
 Peilauskukka WeSchemessä.

5. Kuvion tallentaminen gif-animaationa


Turtlen piirtämän kuvion voi tallentaa myös animoituna gif:inä. Toiminto on tuskallisen hidas eikä aina edes toimi kunnolla pitkien animaatioiden kanssa. Tässä kuitenkin onnistunut spiraalikukka-animaatio.

(define (tee-kukat2 määrä koko väri)
  (if (<= määrä 0)
      empty
      (cons (rotate koko (tee-kukka2 koko väri))

            (tee-kukat2 (sub1 määrä)(add1 koko) väri))))

(define multi-kukka-spiraali
  (list
   (change-bg-color "black")
   (set-origin)
   (pen-up)
        (stamper-on (tee-kukat2 50 1 "yellow"))
        (kukka-spiraali 25 1 15)
        (turn-left 90)
        (stamper-on (tee-kukat2 50 1 "blue"))
        (go-to 0 0)
        (kukka-spiraali 25 1 15)
        (turn-left 120)
        (stamper-on (tee-kukat2 50 1 "red"))
        (go-to 0 0)
        (kukka-spiraali 25 1 15)))


(draw-and-store multi-kukka-spiraali)

Spiraalikukka-animaatio

6. Taustakuvan asettaminen


Voit myös asettaa animaation taustaksi minkä tahansa kuvan. Taustakuvaksi voi asettaa myös aikaisemmin Turtlella piirretyn kuvan.

(define taustakuva (draw koordinaatisto-kuva))

(define kukkaspiraali-koordinaatistossa
  (list
   (set-bg-image taustakuva)
   (set-origin)
   (pen-up)
        (stamper-on (tee-kukat2 50 1 "red"))
        (go-to 0 0)
        (kukka-spiraali 25 1 15)))

(draw kukkaspiraali-koordinaatistossa)

Taustakuvan asettaminen Racket Turtlelle
Kukkaspiraali-koordinaatistossa WeSchemessä

Racket Turtle toimii myös WeScheme-palvelussa. WeSchemen rajoitusten takia kynän paksuutta tai sen tyyliä ei voi muuttaa eikä animaatioita tallentaa animoituina gif:einä. Muut toiminnot toimivat vastaavalla tavalla.

torstai 18. kesäkuuta 2015

Neulekuvion koodaaminen Racket:illä (hih)

#Dime2015 - kurssin FB-ryhmässä keskusteltiin neulekuvioiden tekemisestä Excelillä ja menin sanomaan, että voisikan niitä myös koodata. Päätin todistaa väitteeni ja etsin netistä kivan neulekuvion (kuvassa kuvio B).

Tutkin kuviota tovin ja totesin, että sehän on kivan symmetrinen, tarvitsi vain tehdä yksi elementti ja kiertää sitä eri asentoihin. Tässä on kuvion peruselementti:


Tämän sain aikaan laittamalla erikokoisia ja värisiä neliöitä ja kolmioita vierekkäin ja allekkain. Lopullinen kuvio on tässä:


Ja tässä Racket-koodi, jolla kuvio syntyi:

(require 2htdp/image)
(define COLOR1 "black")
(define COLOR2 "white")
(define COLOR3 "blue")
(define SIVU 10)

(define (perus-pala väri)
  (rectangle SIVU SIVU "solid" väri))

(define (leveä-pala väri)
  (rectangle SIVU (/ SIVU 2) "solid" väri))

(define (korkea-pala väri)
  (rectangle (/ SIVU 2) SIVU "solid" väri))

(define (kolmio-pala väri)
  (flip-vertical (right-triangle SIVU SIVU "solid" väri)))

(define (kulma-kolmio-pala väri)
  (flip-vertical (right-triangle (/ SIVU 2) (/ SIVU 2) "solid" väri)))

(define (kulma-pala väri)
  (rectangle (/ SIVU 2) (/ SIVU 2) "solid" COLOR1))
 
(define V (perus-pala COLOR2))
(define M (perus-pala COLOR1))
(define S (perus-pala COLOR3))
(define PV (korkea-pala COLOR2))
(define PM (korkea-pala COLOR1))
(define PPV (korkea-pala COLOR2))
(define PPM (korkea-pala COLOR1))
(define PVV (leveä-pala COLOR2))
(define PVM (leveä-pala COLOR1))
(define NV (kulma-pala COLOR2))
(define NM (kulma-pala COLOR2))
(define MK (kolmio-pala COLOR1))
(define NMK (kulma-kolmio-pala COLOR1))

(define R1 (beside NM PVM PVV PVV PVV PVV PVV PVV PVM PVM PVM PVV PVV PVM NMK))
(define R2 (beside PM V S S S S S V V M V V M MK))
(define R3 (beside PV S V S S S S S V V V M MK))
(define R4 (beside PV S S V S S S S V V M MK))
(define R5 (beside PV S S S V S S V V M MK))
(define R6 (beside PV S S S S V V V M MK))
(define R7 (beside PV S S S S V V M MK))
(define R8 (beside PV V S S V V M MK))
(define R9 (beside PM V V V V M MK))
(define R10 (beside PM M V V M MK))
(define R11 (beside PM V V M MK))
(define R12 (beside PV V M MK))
(define R13 (beside PV M MK))
(define R14 (beside PM MK))
(define R15 NMK)

(define osa1 (above/align "left" R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15))
(define osa2 (overlay (rotate 180 osa1) osa1))
(define osa3 (beside osa2 (rotate 90 osa2)))
(define osa4 (above osa3 (flip-vertical osa3)))
(define kuvio (beside osa4 osa4 osa4 osa4))

tiistai 26. toukokuuta 2015

7. luokan matematiikan tunneilla koodattiin Racket - pelejä

Syksyllä kun aloitimme Racket - koodauksen opiskelun, menin lupaamaan oppilaille, että koodaisimme vielä pelin. Keväällä viimeisen matikan kokeen jälkeen oli tullut aika lunastaa lupaukset...

Käytimme pelin koodaamiseen tekemääni Peruspelin pohjaa, eli hyvin pitkälle vietyä koodia, johon oppilaiden piti täydentää vain muutamia rivejä Racket - koodia. Päätin käyttää pelin tekemiseen Bootstrap - projektin WeScheme - sivustoa. Se mahdollistaa pelin koodaamisen selaimen kautta. Koska WeScheme toimii Google - tilin kautta, tein ryhmälle yhden yhteisen Google - tilin ja kopioin valmiiksi kahdeksan Peruspeli - pohjaa. Tähän päädyin, koska halusin, että peliä tehtäisiin pareittain useamman tunnin aikana (ja molempien oppilaiden piti päästä koodiin käsiksi).

Huom! Jos haluat kokeilla peruspelipohjaa, kirjaudu ensin WeScheme-sivustolle ja avaa sitten peruspelin linkki ja tallenna.
WeScheme.org sivustolle kirjaudutaan Google-tunnuksilla
Ensimmäiset kaksi tuntia meni pelin suunnitteluun ja grafiikoiden työstämiseen. Pelin idea on hyvin yksinkertainen: pelaaja liikkuu näppäimillä ylös ja alas, ja samalla väistelee vaaroja ja kerää kerättäviä, jotka liikkuvat vaakasuoraan. Oppilaat etsivät netistä taustakuvat sekä pelaajan, vaaran ja kerättävän kuvan. Tässä yhteydessä kävimme läpi myös sen, miten Googlen kuvahausta filteröidään näkyville vain sellaiset kuvat, joita saa uudelleenkäyttää ja muokata (kuinkahan moni lopulta näin teki?).

Pelaajan, kerättävän ja vaaran kuvista piti poistaa taustat (tehdä tausta läpinäkyväksi). Tähän käytimme GIMP2:sta (joku toinen ohjelma olisi voinut olla kätevämpi). Kuvat (png) ladattiin jokaisen omaan peliin WeSchemessä (kuvat tallentuvat samalla GoogleDriveen). Kuvan lataaminen generoi valmiin linkin koodin (HUOM! kursorin piti olla oikeassa kohdassa koodia, ettei generoinut linkkiä väärään kohtaan):

(bitmap/url "https://drive.google.com/uc?export=download&id=0B5CH7_F_YAvoX2RrbDl3N3JGam8")

Kuvat ladataan WeSchemeen Images-napin kautta
Kuvien lataamisen jälkeen niitä piti tietysti skaalata (scale) oikean kokoisiksi. Vaara ja kerättävä myös siirrettiin oikeille lähtöpaikoilleen, eli pelikentän reunoille. Tämä tehtiin muuttamalla kahden vakion arvioa:

(define VAARA-LÄHTÖ-X -50)
(define KERÄTTÄVÄ-LÄHTÖ-X 750)

Kun tämän jälkeen pelihahmot piti saada liikkeelle. Alussa "liikuta-varaa" - funktio näytti tältä:

;(check-expect (liikuta-vaaraa ..) ..)
;(check-expect (liikuta-vaaraa ..) ..)

;; liikuta-vaaraa : Number -> Number
(define (liikuta-vaaraa x)
  x)


Mietimme ensin mihin suuntaan vaaran piti liikkua ja teimme pari esimerkkiä. Jos vaara on kohdassa x=100 niin funktiokutsun jälkeen se on kohdassa x=110 (eli liikkuu oikealle). Tämä kirjoitettiin check-expect - lauseeseen:

(check-expect (liikuta-vaaraa 100) 110)

Kun funktion toiminta oli ymmärretty, täydennettiin funktion koodi toimivaksi:
;; liikuta-vaaraa : Number -> Number
(define (liikuta-vaaraa x)
  (+ x 10))


Vastaava operaatio tehtiin kerättävälle. Tietysti mielessä piti pitää mihin suuntaan halusi hahmojen etenevän (mahdollisesti tarvittiin miinusmerkkiäkin).

Nyt hahmot jatkoivat eteenpäin tulematta koskaan takaisin joten lisäsimme testin, jolla voitiin testata ollaanko vielä sallitulla alueella. Aloitimme chack-expect - pohdinnoilla, ja sitten kirjoitimme funktion.

(check-expect (alueella? -100) false)
(check-expect (alueella? 100) true)
(check-expect (alueella? 1000) false)

;; alueella? : Number -> Boolean
(define (alueella? x)
  (<= -50 x 750))
 

Tässä piti tajuta ottaa mukaan välin päätepisteet (jos käytti samoja lukemia kuin VAARA-LÄHTÖ-X ja KERÄTTÄVÄ-LÄHTÖ-X) muuten hahmo jäi nykimään eikä lähtenyt enää liikkeelle ollenkaan.

Seuraava vaihe oli näppäinohjauksen lisääminen pelaajalle. Suunnittelimme senkin ensin yhdessä check-expect lauseiden avulla. Nuolinäppäimet ovat "up" ja "down", tässä voi käyttää myös "w" ja "s" näppäimiä:

(check-expect (siirrä-pelaajaa 100 "up") 120)
(check-expect (siirrä-pelaajaa 100 "down") 80)
(check-expect (siirrä-pelaajaa 100 " ") 100)

;; siirrä-pelaajaa : Number Key -> Number
(define (siirrä-pelaajaa y näppäin)
  (cond [(key=? näppäin "up")(+ y 20)]

        [(key=? näppäin "down")(- y 20)]
        [else y]))

Nyt hahmot liikkuivat mutta mitään ei tapahtunut vaikka ne törmäsivät. Peruspelissä hahmojen törmääminen päätellään siitä, ovatko ne pelaajan ympärille piirretyn laatikon sisällä. Säädimme ensin laatikon koon sopivaksi ja katselimme sitä "pause"-moodissa (painetaan pelissä p-näppäintä).

(define TÖRMÄYSVARA-X 50)
(define TÖRMÄYSVARA-Y 80)


Pause - moodissa nähdään hahmojen sijainnit sekä laatikon koko (keltainen)
Koko pelin vaikein lauseke oli törmäysehtojen kirjoittaminen. Aloitimme x-suunnasta. Jotta törmäys tapahtuisi, täytyisi hahmon x-koodinaatin (x2) olla laatikon koordinaattien sisällä. Vasemman reunan x-koodinaatti saataisiin laskemalla: x1 - TÖRMÄYSVARA-X ja oikea laita laskemalla x1 + TÖRMÄYSVARA-X. Matemaattisesti ilmaistuna siis:

(x1 - TÖRMÄYSVARA-X) <  x2  < (x1 + TÖRMÄYSVARA-X)


Törmäysvarat
Ensimmäinen ehto Racket - muotoon kirjoitettuna olisi:

(define (törmäsikö? x1 y1 x2 y2)
  
(< (- x1 TÖRMÄYSVARA-X) 
       x2 
      (+ x1 TÖRMÄYSVARA-X))

Tätä testattaessa käy nopeasti ilmi, että törmäys tapahtuu aina kun pelaaja ja vaara/kerättävä ovat samalla linjalla, joten tarkistus on tehtävä myös y-koordinaatille. Tähän tarvitaan myös and:iä. Valmis funktio oli tällainen:

(define (törmäsikö? x1 y1 x2 y2)
  
(and (< (- x1 TÖRMÄYSVARA-X) 
         x2 
        (+ x1 TÖRMÄYSVARA-X))
        (< (- y1 TÖRMÄYSVARA-Y) 
         y2 
        (+ y1 TÖRMÄYSVARA-Y))))

Viimeinen silaus pelille saadaan, kun lisätään pisteiden päivittäminen. Pelissä on kaksi tilannetta "törmäys-vaara" ja "törmäys-kerättävä". Tämänkin funktion suunnittelu tehtiin check-expect:ien kanssa:

(check-expect (päivitä-pisteet 100 "törmäys-vaara") 90)
(check-expect (päivitä-pisteet 100 "törmäys-kerättävä") 110)

;; päivitä-pisteet : Number String -> Number
(define (päivitä-pisteet pisteet tapahtuma)
  (cond [(string=? tapahtuma "törmäys-vaara") (- pisteet 10)]

        [(string=? tapahtuma "törmäys-vaara") (+ pisteet 10)] ))        
  
Pelien tekemiseen meni kaikkiaan 6 matematiikan oppituntia (niistä kaksi kuvien käsittelyyn). Aivan kaikki parit eivät saaneet peliänsä valmiiksi mutta valmiitakin pelejä saatiin aikaiseksi. Yksi pari jatkoi koodauskerhossa aloitettua peliänsä (Bootstrap II pelipohjalla tehty). Pelin tekeminen tuntui kiinnostavan oppilaita, ja oli tärkeää että jokaisella oli oma ideansa toteutettavaksi. Peliä tehdessään oppilaat kyselivät mm. miten kerättävät saisi liikkumaan pystysuuntaan tai pelaajan sivusuuntaan, miten voisi vaihtaa pelaajan hahmoa, zoomata lähemmäs tms. Peruspelin pohjalla ei näitä muutoksia kuitenkaan tässä ajassa olisi pystynyt tekemään, vaikka kaikki on tietysti periaatteessa mahdollista... Aikaa oli nytkin hieman liian vähän, asioiden sulatteluun menee  yllättävän kauan. Pari tuntia olisi tarvittu vielä lisää niin olisimme saaneet kaikki pelit valmiiksi, ja ehtineet hieman pelatakin niitä.

Tällaisia esimerkkejä siitä millaisia pelejä matikan tunnilla syntyi (osasta puuttuu pisteiden laskeminen). Pelaaminen joko nuolinäppäimillä tai s ja w näppäimillä. Peli alkaa välilyönnillä (myös uusi peli alkaa välilyönnillä). Voit katsoa törmäysaluetta pause - moodilla (paina "p"):

Ammu tuomari - peli (pelaa)
Racket War:issa kerätään Sprite - juomia ja vältellään punaista rakettia (pelaa)
Apinapelissä kerätään banaaneja ja vältellään leijonaa (pelaa)
Homer-pelissä pisteitä saa, jos hamppari osuu Homerin suuhun, pisteitä lähtee jos se joutuu roskikseen (pelaa)
Avaruuspelissä ammutaan vihreitä ammuksia ja pujotellaan asteroidien välistä (pelaa)
Tämä ryhmä oli koodanneet Racket - kielellä jo aikaisemmin, pohjalla oli n. 10 tuntia Racket-koodausta. Osalle oppilaista oli selvästikin syntynyt jonkinlaista ymmärrystä ohjelmoinnista, joten pelin tekeminen ei tuntunut ollenkaan mahdottomalta. Mielenkiinnolla odotan mitä tämä porukka saa aikaan syksyllä kun peliohjelmoinnin kurssi alkaa. 

maanantai 18. toukokuuta 2015

tiistai 31. maaliskuuta 2015

Racket Turtle GitHub:ssa


Racket Turtlella voidaan piirtää geometrisia kuvioita käyttäen Racket-kieltä ja DrRacket:iä. Koodin voi ladata nyt GitHub:ista. Päivitän koodia jatkossakin sinne, eli kannattaa latada koodi zip-pakettina suoraan sieltä.

Tässä lyhyet käyttöohjeet Racket Turtlelle:

1) Asenna DrRacket täältä : http://download.racket-lang.org/ 
2) Lataa Racket Turtle:n koodi täältä (Download ZIP): https://github.com/tyynetyyne/racket_turtle
3) Pura ZIP-paketti
4) Avaa racket_turtle_esimerkit.rkt tiedosto DrRacket:lla
5) Paina "run"
    Huom! jos DrRacket ei tunnistanut tiedoston ohjelmointikieltä automaattisesti, valitse se valikosta
     --> Language --> Choose Language --> Student Languages --> Beginning Student

Nyt voit testata Racket-Turtlen esimerkkikoodeja. Kirjoita DrRacket:in REPL:iin (alempaan ikkunaan): (piirrä neliö) ja paina <enter> ja Racket-Turtle piirtää sen.

Tämä toimii, koska racket_turtle_esimerkit.rkt tiedostossa on määritelty neliölle ohjeet näin:

(define neliö
  (list (forward 100)
        (turn-left 90)
        (forward 100)
        (turn-left 90)
        (forward 100)
        (turn-left 90)
        (forward 100)))


Racket-Turtle osaa myös toistorakenteita eli repeat - käskyn avulla voit ensin määritellä yksinkertaisen kuvion (sivu), jota toistetaan haluamasi määrä:

(define sivu
  (list (forward 100)
        (turn-left 90)))

(define toisto-neliö
  (repeat 4 sivu))


Racket-Turtlen kynän voi myös nostaa ilmaan/laskea, sekä sen värin voi muuttaa haluamakseen:

(define siirry
  (list (pen-up)
        (forward 100)
        (pen-down)
        (change-color "red")))


Racket-Turtlen avulla voidaan opetella kirjoittamaan myös funktioita. Tämän esimerkkikoodin avulla voidaan piirtää minkä tahansa kokoinen neliö (x on sivun pituus):

(define (muuttuva-sivu x)
  (list (forward x)
        (turn-left 90)))

(define (muuttuva-neliö x)
  (repeat 4 (muuttuva-sivu x)))


GitHub:ssa on myös racket_turtle_harjoitukset_1.rkt tiedosto, josta löytyy 7.luokan matematiikan tunnille sopivia geometrian harjoituksia.

Omat oppilaani ovat tykänneet leikkiä Racket Turtlella joten uskon, että tästä on iloa myös teille muillekin! Tässä Lielahden koulun 7F-luokan oppilaiden Racket Turtle taidetta, jota he piirsivät matematiikan tunnilla:

7. luokkalaisten Racket Turtle - taidetta

lauantai 28. maaliskuuta 2015

Uusia mahdollisuuksia matematiikan opiskeluun Racket - kielen avulla

Olin eilen Innokas - verkoston Kiinnostaako koodaus ja robotiikka - jatkokoulutuksessa opettamassa  Racket - ohjelmointia. Aamupäivän pajassa kävimme läpi Racket - kielen perusteita (peruslaskuja sekä piirtämistä) sekä sitä miten Racket-Turtlea voi käyttää geometrian opetuksessa.

Racket ohjelmointia I - piirtäminen (PDF)
Racket - Turtle - koodi (ZIP)  
Emme meinanneet päästä lounastauolle, kun tämä kuvio piti saada koodattua Racket-Turtlella
Iltapäivällä työskentelimme Peruspeli 1:n kimpussa. Peruspelissä on kaksi eri pohjaa, joiden avulla voidaan opettaa ohjelmoinnin perusperiaatteet: ehtolauseet, haarautuva koodi sekä funktion kirjoittaminen.

Racket ohjelmointia II - peruspeli (PDF)
Peruspeli 1 - koodi (ZIP)

Opettelimme ajattelemista tämän Peruspeli 1a:n avulla, milloin vaara (pun) ja kerättävä (vihr) ovat riittävän lähellä?
Vastaanotto oli innostunutta ja taas kerran tuli mieleen, että kyllä on mukavaa innostaa ja innostua yhdessä.

lauantai 21. maaliskuuta 2015

Bootstrap I - pelin kimpussa

Kevään aikana olen tutustunut amerikkalaisen Bootstrap-projektin ohjelmointimateriaaleihin yläkoulun matematiikan opiskelussa. Heidän lähestymistapansa on mielenkiintoinen, ei vähiten siksi, että hekin käyttävät Racket-kieltä vaan sen takia, että materiaalin keskiössä on matematiikka, ei ohjelmointi. Projektissa jokainen oppilas tekee itselleen oman "videopelin" melko valmiiseen pohjaan. Pelipohja on suunniteltu niin, että oppilaan pitää ratkaista jonkin verran matemaattisia ongelmia, mutta kirjoittaa mahdollisimman vähän ja mahdollisimman yksinkertaista koodia.
 
Vaikka periaatteessa Bootstrap I - pelipohja on aivan toimiva sellaisenaan (se on riisuttu niin yksinkertaiseksi kuin pelin koodaamisen lausekielellä nyt voi riisua), niin olen törmännyt sen kanssa muutamaan harmilliseen asiaan:
  • Pelipohja on toteutettu niin, että sillä voi tehdä yhden ja saman pelin variaatioita ja sitten tulee seinä vastaan. Esim. vaara (DANGER) ja kerättävä (TARGET) liikkuvat vain x:n suunnassa, eikä sitä voi muuttaa mitenkään. Myös koko big-bang on piilotettu, joten esim. hiiren tai kosketusnäytön eventtien lisääminen ei onnistu mitenkään helposti.
  • Pelipohjan käyttämä kirjasto kääntää koordinaatiston ns. "oikeinpäin" (Racket:issa (0, 0) on normaalisti vasemmassa ylänurkassa, Bootstrap:illä se on vasemmalla alhaalla). Äkkiseltään ajatus tuntuu loistavalta, mutta kun kaikki muut toiminnot kuten overlay/xy toimii Racketissä vasemman ylänurkan origon logiikalla niin tämä Boostrapin versio aiheuttaa vain turhaa hämmennystä.
  • Bootstrap:in pelipohjassa on mainio "kolmio"-trace, jolla nähdään miten hahmojen etäisyyden laskemiseen tarvittava kolmio muodostuu livenä. Vaikka kolmio auttaakin Pythagoraan lauseen hahmottamisessa niin näkisin, että paikallaan olevaa kolmiota olisi helpompi tutkia ja oikeita lukuja voisi pyöritellä helpommin kuin hahmojen koordinaatit näkyisivät kuvassa (nyt ne eivät näy, sen sijaan etäisyydet näytetään sitten kun ne on ohjelmoitu).
  • Pelipohjassa ärsytti myös se, että Bootstrap - kirjasto on taas yksi "black box", jonka toimintaa voi vain arvailla, eikä kaikkia pelin asetuksia pääse muuttamaan (pelin korkeus, leveys, hahmojen lähtösijainnit jne.) 
  • Kerholaisteni kanssa törmäsin myös siihen, että 5.-7. luokkalaisille oli melkoisen vaikea opettaa Pythagoraan lausetta, kun potenssit sekä neliöjuurikin puuttuivat sanavarastosta. Törmäys pitäisi siis voida todeta myös ilman Pythagoraan lausetta.
Kokeilin pystyisikö vastaavan pelipohjan kirjoittamaan kokonaan ilman rajoittavaa Bootstrap - kirjastoa, ja tällaisen version sain aikaan: Peruspeli-pohja. Oppilaan koodattavaksi on jätetty vastaavat osuudet kuin Bootstrap I - pelissäkin, mutta valmis koodi on jätetty tiedoston loppuun niitä oppilaita ja opettajia varten, jotka haluavat nähdä mitä "kulissien takana" tapahtuu ja vaikka jatkaa pelin muokkaamista vielä pidemmälle. Tein pelipohjasta kaksi eri versiota: 1a versiossa törmäys havaitaan ilman Pythagoraan lausetta ja 1b, jossa Pythagoraan lause on käytössä.

Koodista ei tullut aivan niin selkeää kuin olisin toivonut: törmäystä havainnolistavien kolmioiden/suorakulmioiden ja koordinaattien tulostaminen teki siitä turhankin monimutkaista. Kumpi on sitten loppupeleissa tärkeämpää, tarjota apuja niille oppilaille, jotka eivät heti hahmota miten hahmojen törmäysehdon voi koodata vai antaa helppo ja selkeä pohja innostuneille pikkukoodareille jatkaa pelin kehittelyä eteenpäin?

Tältä näyttää valmis Peruspeli (1a):


Ja tältä näyttää valmis Peruspeli (1b):