torstai 17. joulukuuta 2015

Lietsun koodauskerhon syksy 2015

Tänä syksynä kerhon aloitti huimat 21 kerholaista (luokilta 5 - 8). Joulukuussa mukana oli vielä 13 innokasta koodaria. Syksyn aikana kerholaiset ovat saaneet valita erilaisia projekteja oman kiinnostuksensa mukaan. Tässä niistä muutamia.

Lego-robotit

Kerhossamme on rakennettu ja koodattu syksyn aikana mm. kolmea sumo-robottia, yhtä koirarobottia, kahta viivan seuraajaa, yhtä musiikkia soittavaa robottia sekä yhtä "fantasia-ajoneuvoa". Viivan seuraajat eivät vielä seuraa viivaa, mutta yritys on kova. Tässä pieni pätkä toisen viivan seuraajan koodia:

EV3:n ohjelmointi ympäristö on graafinen
Tässä sumorobotit ottavat toisistaan mittaa:


Ja tässä robottikoira yrittää kävellä (tosin vähän hassusti käy):

Racket - koodaus

Racket:llä syntyi syksyn aikana nämä hienot kuvat (osa vaati jopa rekursiivisen funktiokutsun ja listojen käyttämisen!). Myös yksi Packman animaatio/peli on hyvässä vauhdissa.

Death Pack Crystal

Death Pack Ellipse

Juuson talo


Death Star 2.0


Crazy Pixel
3D - mallinnus

Kaksi kerholaista teki 3D - malleja, sekä Blenderillä että SketchUp:illa. Myös ensimmäinen kerhossa mallinnettu esine tulostettiin 3D - tulostimella (lentokone).

Tässä kerhossa tehtyjä SketchUp - malleja:

Ilves - logo

Näsinneula

Laurin talo
Arduino - koodaus

Tänä syksynä kokeilimme ensimmäisen kerran ohjelmoida Arduinoa ja saimme ledit vilkkumaan. Teimme sen DrRacket - ohjelmalla käyttämäll ASIP - protokollaa:


Keväällä jatkuu

Keväällä onkin edessä sitten osallistuminen Tampereen Innokas kick-off:in näytöslajeihin sekä toimiminen tutoreina opettajien työpajoissa. Toukokuussa osallistumme myös Helsingissä järjestettävään Robocup Junior SM - kisoihin. Jännittävää!

tiistai 1. joulukuuta 2015

Peliohjelmointikurssin ensimmäinen askel: Whack-a-mole

Tänä syksynä aloitimme uuden mielenkiintoisen yhteistyöprojektin kuvataiteiden opettaja Jussi Kapasen kanssa: 8.lk peliohjelmointikurssi. Kurssin ideana on lähteä ideoimaan täysin uusi peli, luoda siihen tarina, pelilogiikka, grafiikat ja ohjelmoida se, kaikki tiimityönä niin kuin oikeassakin elämässä.

Ensimmäisellä kaksoistunnilla lähdimme liikkeelle niin, että muodostimme viisi devaustiimiä, jotka keksivät itselleen nimen. Jotta jokaiseen ryhmään tulisi tasaisesti koodareita, graafikoita jne. jokainen sai valita itselleen kaksi mieluisinta tehtävää, ja näin saimme jaettua porukan ryhmiin joihin jokaiseen tuli 2 koodaria, 1-2 graafikkoa ja 1 tarina/pelilogiikkasuunnittelija.

Luovan prosessin ainekset
Ennen kuin ryhmät päästettiin ideoimaan, Jussi esitteli hieman luovan prosessin taustoja, miten ideat löytyvät ja miten niiden ympärille rakennetaan kokonaisuus. Sitten keräsimme listan yksinkertaisia mutta koukuttavia pelejä, mietimme erilaisia pelikategorioita, jopa sitä miten seitsemän kuoleman syntiä liittyvät peleihin. Alustuksen jälkeen ryhmät saivat eteensä litoposterin ja tusseja ja he ryhtyivät ideoimaan omaa peliä. Ensimmäisellä kerralla ei tuntunut vielä syntyvän kovin paljoa  ideoita, mutta ryhmät oli saatu kasaan, ja jokaisella oli oma vastuualueensa.

Ensimmäisellä kerralla paperi jäi vielä aika tyhjäksi...
Koska ideointityötä tuntui hieman vaikeuttavan konkretian puute, päätimme tehdä ryhmien kanssa yhden helpon pikkupelin alusta loppuun niin, että koodarit pääsevät näkemään mitä koodaaminen on ja graafikot pääsevät käytännössä suunnittelemaan ja toteuttamaan peligrafiikkaa. Peliksi valikoitui Whack-a-mole, koska se on hyvin yksinkertainen peli, joka sallii vapausasteita grafiikan luomiseen, myyrän kun ei tarvitse olla myyrä...

Pelin koodaaminen lähti liikkeelle siitä, että suunnittelimme sen ensin yhdessä isolle valkoiselle paperille. Analysoimme mitkä asiat pelissä ovat vakioita ja mitkä muuttujia. Sitten esittelin miten käyttämämme pelimoottori toimii, ja kävimme läpi mitä funktioita (toiminnallisuuksia) pelissämme tarvitaan. Suunnittelimme myös pelin tietorakenteen paperille. Tätä "karttaa" tutkisimme sitten jokaisella koodauskerralla: mitä on jo tehty, mitä vielä puuttuu.

Tällä suunnitelmalla edettiin
Valitsin koodauskieleksi Racket-kielen, koska noin puolet kurssin koodareista oli jo koodannut Racket:illä 7. luokan matikan tunneilla ja koska se mahdollistaa grafiikoiden vaihtamisen helposti (koodi/pelilogiikka ja grafiikka ovat täysin erillään). Se mahdollistaa myös pelin muuntamisen helposti selaimella pelattavaksi versioksi (WeScheme). Harkitsin aluksi pelien tekemistä myös Scratch:illä mutta hylkäsin sen, koska siinä koodin kirjoittaminen vaatii sen, että grafiikka on jo valmiina. Lisäksi isomman pelin tekeminen Scratchillä ei houkutellut, koska kokemukseni viime vuodelta oli sellainen, että oppilaiden pelit menivät usein sellaiseen solmuun, ettei niitä pystynyt saamaan toimiviksi. Epäilen, että se johtuu osittain siitä, että siinä koodin logiikka hajoaa niin moneen pieneen osaan eri säikeisiin, jotka toimivat toisistaan riippumatta, että kokonaiskuvan saaminen koodin toiminnasta on lähes mahdotonta ja testaaminen/debuggaaminen hidasta ja hankalaa. Myös omien tietorakenteiden ja funktioiden puuttuminen vaikeuttaa monimutkaisemman  pelin tekemistä. Kolmas työkalu johon tutustuin oli MIT Appinventor mutta sen jätin pois, koska se olisi vaatinut Android puhelimia (tai emulaattoria), ja sen myötä aivan liikaa ylimääräistä säätöä, joka ei suoranaisesti liity ohjelmoinnilliseen ajatteluun tai pelin luovaan suunnitteluun.  

Koodarit työskentelivät niin, että jokainen teki omaa koodiansa, mutta tiimin sisällä vastuu oli molemmilla koodareilla yhteisesti. Eli, jos kävi niin, että toinen oli pois oppitunnilta, läsnä ollut koodari jatkoi koodia eteenpäin ja antoi sen seuraavalla kerralla koodauskaverillensa ja selitti mitä siihen oli lisätty. Ryhmät myös auttoivat toisiaan ja debuggasivat toistensa koodia. Tässä helpotti se, että koska teimme samaa peliä ryhmillä oli myös samoja ongelmia. Jokaisella kerralla alussa kertasimme suunnitelmamme kanssa mitä olimme tehneet viime viikolla, mitä pitäisi tehdä tällä tunnilla ja mitä jäi seuraavalle kerralle. 

Samalla kun teimme koodia, tutustuimme ohjelman rakennuspalikoihin: vakioihin, funktioihin ja muuttujiin, tietueisiin ja niiden kenttiin, ehtolauseeseen, hiiritapahtumiin (events) sekä testaamiseen check-expect:ien avulla. Myös boolean logiikkaa ja vertailuoperaattoreita jouduttiin käyttämään, kun koodasimme predikaattia, joka huomaa onko hiiren klikkaus osunut hahmoon vai ei. Koska meillä ei ollut tietoa tulevien "myyrien" koosta, teimme koodimme "hit-box":in sellaiseksi, että minkä tahansa kokoinen myyrän kuva toimii (säätyy kuvan koon mukaan).

Koodatessa opettelimme käyttämään myös Koodarin käsikirjaa, katsoimme sieltä mm. miten merkkijonoja käsitellään, että saimme pisteet näkymään ruudulle.  Koodaamiseen meni kolme kaksoistuntia, jonka ainaka graafikot ideoivat ja piirtelivät peligrafiikat. Neljännellä kaksoistunnilla kokoonnuimme koko ryhmä tietokoneluokkaan ja integroimme grafiikat peleihin. Monelle graafikolle ei ollut vielä selvinnyt, että kuvat piti eksportata GIMP2:sta .png muodossa, että niitä saattoi käyttää pelissä. Myös melkoinen määrä valkoista taustaa jouduttiin poistamaan pelihahmojen ympäriltä ja rajaamaan hahmojen kuvat tarkemmin, että koodiin ohjelmoitu "hit-box" toimisi oikein. Melkoisen sähellyksen jälkeen saimme kuitenkin kaikki pelit toimimaan.

Tämä harjoitus auttoi selvästi ryhmiä hahmottamaan, mitä pelin tekeminen vaatii, mitkä eri vaiheet ovat, mitä koodari tekee ja mitä graafikko tekee ja miten lopputulokseen vaaditaan jokaisen jäsenen panos.

Tämän jälkeen jatkoimme jälleen oman pelin suunnittelun kanssa koko devaustiimin voimin. Suunnittelun rinnalla porttasimme Racket - koodit WeScheme palveluun, jotta tehtyjä pelejä pääsisi pelaamaan selaimen kautta. Tässä ensimmäiset pelit!

Pelit toimivat myös iPadin kosketusnäytöllä.

Blacker Blue -tiimi


Mars - tiimi

Arcaid3 - tiimi
Swag Lords - tiimi
Tämä on erittäin mielenkiintoinen kokeilu, jännä nähdä mitä tästä vielä syntyy! Tulen tekemään myös tutoriaalivideon pelin koodaamisesta, kunhan ehdin sinne asti...

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.

maanantai 7. syyskuuta 2015

Racket packages

Viikko sitten ryhdyin tutkimaan miten saisin julkaistua Racket Turtle - kirjastoni oikeana package:na. Nythän koodini on ollut koko ajan Github:ssa mutta se on pitänyt ladata sieltä hankalasti .zip - paketissa, avata paketti ja vasta sitten ryhtyä koodaamaan. Huomasin koulutuksissa, että tämä on yllättävän vaikeaa opettajille ja oppilaille.

Ensin opiskelin Racket package creation:ia teoriassa täästä linkistä. Tavallinen .rkt tiedosto muuttuu package:ksi niin, että sijoittaa sen hakemistoon, jonka nimestä tulee package:n collection ja rkt-tiedoston nimestä kirjaston nimi. Nyt olin siis tekemässä  teachpacks nimistä collection:ia ja sen sisälle kirjastoa racket-turtle. Tavoitteeni oli siis, että kirjastoani voisi käyttää DrRacket:ssa näin:

(require teachpacks/racket-turtle)

Ensimmäinen vaihe tässä oli tehdä Racket - Turtlesta paikallinen kirjasto. Se tehtiin menemällä komentotulkin kautta hakemistoon teachpacks ja ajamalla siellä Racket Package Manager kutsu:

> raco pkg install

Nyt pystyin jo omalla koneellani käyttämään Racket Turtle:a kuin se olisi oikea package. Tämän jälkeen pakettini piti rekisteröidä Racket - package serverille. Ilmoitin, että pakettini nimi on "teachpacks" ja että se sijaitsee Githubissa osoitteessa: git://github.com/tyynetyyne/teachpacks.git

Nyt paketin pystyy kuka tahansa lataamaan ja asentamaan käyttöönsä esim. DrRacket:iin integroidun Package Managerin avulla. Package Managerin saa auki valitsemalla File->Package Manager. Package Source:ksi kirjoitetaan paketin nimi eli tässä tapauksessa teachpacks ja painetaan <enter>. Nyt paketti latautuu ja asenttuu koneelle (tämä ei vaadi admin oikeuksia). Nyt kirjaston voi ottaa käyttöön koodissa kirjoittamalla em. require - lause. Huimaa!

DrRacketin Package Manager - ikkuna
Lopuksi tein vielä dokumentaation pakettini palveluista käyttämällä Scribbleä ja tallensin .scrbl tiedostot myös Githubiin.  Scribble-tiedostojen olemassaolo sekä muutama muu asia piti vielä konffata info.rkt tiedoston avulla ja sitten olikin valmista. Tältä näyttää Scribble:stä HTML:ksi käännetty Racket Turtle - dokumentaatio.

Aivan ongelmitta tämä prosessi ei onnistunut, palvelimella oli hieman erilainen ympäristö kuin omalla koneellani, joten Scribble-dokumentaatio ei suostunut toimimaan heti. Pienen säädön jälkeen pakettini sai tänään "vihreää" (jouduin mm. poistamaan kaikki viittaukset Racket GUI komponentteihin kuten universe - kirjastoon).

Hienoa tässä on myös se, että voin päivittää pakettini päivittämällä tiedostot Githubiin ja seuraavana päivänä ne löytyvät uudesta paketista automaattisesti.



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 16. kesäkuuta 2015

Scribble ja Github - ohjeita

Mikä ihmeen Scribble ja mikä ihmeen Github?

Aloitin tekemään Koodausta kouluun - käsikirjasivustoa. Etsin työkalua, jolla tehdä nettisivut, joihin upottaa koodiesimerkkejä Racket-kielellä. Pitkään ei tarvinnut etsiä, sillä sellainen oli jo asennettuna koneelleni: DrRacket. Olin koodannut Racket-ohjelmia jo hyvän tovin, kunnes ymmärsin että DrRacket:iin on sisäänrakennettu oma HTML-dokumenttien kuvauskieli: Scribble. Eikä mikä tahansa kieli, se on yhteensopiva Racket-koodin kanssa, voin kirjoittaa Racket-koodia Scribble-koodin sekaan ja käännettäessä, se ajaa myös Racket-koodin eli voin samalla koodata kuvituksen tekstiini! Koodiesimerkit myös väritetään (varatut sanat jne omilla väreillään) ja Racket-kielen varatut sanat linkitetään varsinaiseen Racket-dokumentaatioon. Scribble-kääntäjälle annetaan komentorivillä parametrit, joiden kautta sille voi antaa mm. css-määrittelyt, eli sivustosta tulee juuri sellainen kuin itse haluat. Huimaa!
Tätä näyttää Scribblellä, Racketillä ja css:llä koodattu web-sivu
No, miten Github tähän liittyy? Github:in kautta voi hallita ja jakaa koodia, ja luonnollisesti siis myös Scribble, css- ja html-tiedostoja. Mutta en tiennyt ennen tätä harjoitusta, että se voi toimia myös webbiserverinä sivustolleni. Tein uuden repositoryn githubini juureen nimellä: tyynetyyne.github.io ja tallensin sinne Scribbellä tekemäni html-tiedostot sekä projektiin liittyvät css-tiedostot. Tarmo Toikkanen loi minulle ystävällisesti "racket.koodiaapinen.fi" alidomainin ja ohjasi sen osoittamaan em. Github-repoon. Minun piti vain lisätä tyynetyyne.github.io:n masterhaaraan yksi CNAME-niminen tiedosto, jonka sisällä lukee "racket.koodiaapinen.fi" ja varmistua, että siellä oli yksi index.html niminen tiedosto. 

Löysin Githubista jopa Latex-tuen Scribblelle (pr-math), joten voin kirjoittaa matemaattisia merkintöjä Scribble-koodin sekaan ja sivu näyttää sen oikein!

No, ei tämä nyt aivan noin yksinkertaista ollut. Ensinnäkin Scribblen käyttö vaatii hieman harjoittelua  ja konffaamista. Scribble.exe tulee kyllä koneellesi DrRacket:in mukana mutta, koska se toimii komentoriviltä, joudut asettamaan sen sijainnin PATH-ympäristömuuttujaan. Windows 7:ssa se tehdään näin. Path - muutujan pitkän listaan perään lisätään siis: "; c:\Program Files\Racket" (ilman hipsuja).

Komentorivin käynnistyksen jälkeen siirrytään siihen hakemistoon, jossa Scribble - koodi sijaitsee, ja sitten komentoriville kirjoitetaan sopiva komento. Scribblen komennot (flagit) on kuvattu täällä ja melkoisen testaamisen ja kokeilun jälkeen itselleni toimivin rimpsu oli lopulta tämä:

> scribble --html ++main-xref-in --style manual-style-koko.css --dest generoitu --redirect-main http://docs.racket-lang.org koodausta_kouluun_aloita_tasta.scrbl

Nämä punaisella merkityt ovat projektini css-tiedosto, sekä aloitussivun Scribble-tiedosto. Lopuksi tallensin rimpsun "koko.cmd" tiedostoon ja ajelin sitä sieltä. Ajon jälkeen hakemistoon ilmestyi  kansio, jonka nimi on "generoitu" ja sen sisällä on "koodausta_kouluun_aloita_tasta.html" sekä erinäinen määrä muita html-tiedostoja, jpg-tiedostoja, pari JavaScript-tiedostoa ja css-tiedostoja, jotka muodostavat sivustoni. Jos kaikki toimii ok, voin päivittää sekä source-tiedostot, että target-tiedostot Githubiin käyttämällä tätä Github - Windows clientia.

Hankalinta kaikessa oli saada linkit ohjautumaan oikeaan dokumentaatioon. Se vaati .scrbl tiedostoon merkinnät mihin linkataan:
@(require (for-label lang/htdp-beginner))
@(require (for-label (except-in 2htdp/image image?)))


Lisäksi linkkien ohjaaminen käyttämään Racket-serveriä vaati --redirect-main -flagin. Ja jotta linkitys ylipäätään tehtäisiin piti käyttää ++main-xref-in -flagiä.

Source-tiedostot
Target-tiedostot (generoitu)

Voisi sanoa, että on pieni ihme, että olen saanut Githubiin tehtyä nettisivut, koodaamalla ne Scribblellä, Racketilla, css:lla ja Latexilla. Kukapa olisi uskonut! Tästä on hyvä jatkaa.

Voit testata sivujani osoitteessa: http://racket.koodiaapinen.fi

keskiviikko 10. kesäkuuta 2015

Vinkkejä opetusvideoiden tekemiseen

Olen tässä viikon aikana testaillut erilaisia ohjelmia opetusvideoiden tekemiseen.

Ensimmäinen kokeiluni oli nauhoittaa webbikameralla kuvaa ja ulkoisen mikrofonin avulla ääntä.  Käytössäni oli MSLifeCam Studio - webbikamera ja iRig PRO:n kautta USB:iin kiinnitetty Beyerdynamic TG V50d - mikrofoni. Ensimmäinen testattu ohjelma, Adobe Presenter 10:n Video Express, ei suostunut edes ottamaan yhteyttä ko. kameraan. Ääni olisi toiminut ja läppärin sisäänrakennetun webbikamerakin näytti toimivan.  

Adoben ohjelma ei tykännyt MS:n webbikamerasta...
Seuraavaksi kokeilin äänittämistä MS LifeCam 3.6 ilmaisohjelmalla. Tämän kautta kuva tuli kyllä ok, mutta ohjelma ei tukenut ulkoisen mikrofonin valintaa, joten äänitykseen tuli mukaan  webbikameran oman mikrofoni mukana ikävä määrä ylimääräistä suhinaa ja kohinaa. Kohinan poistamiseksi seurasin tämän youtube - videon ohjeita. Jouduin lataamaan Audacity - ohjelman kohinan poistamiseksi sekä DVDVideoSoft Free Studio - ohjelman ääniraidan konvertoimiseksi Audacityn ymmärtämään muotoon.

Työlään kohinanpoistoharjoituksen jälkeen ymmärsin, että kunnon mikki on saatava käytöön ja seuraavaksi latasin Camtasia - ohjelman. Se osasi käyttää sekä ulkoista mikrofoniani, että MSLifeCam:ia. MUTTA audio ja video eivät pysyneetkään enää synkassa! Tätä mysteeriä kun lähdin selvittämään löysin tämän youtube - videon, jossa kerrottiin, miten webbikameran ja tietokoneen asetukset voisi konffataan niin, että homman saa toimimaan. Asetukset auttoivatkin jonkin verran mutta viivettä jäi silti jäljelle. Ilmeisesti ulkoinen äänikortti (iRig) lisää ääniraitaan viivettä joka tapauksessa, ja asialle ei yksinkertaisesti voi mitään. Onneksi Camtasiassa on toiminto, jolla voi erottaa ääniraidan videoraidasta, joten periaatteessa manuaalisesti synkronoinninkin voi tehdä (esim. taputusten avulla, katso video). Hankalaksi menee, jos haluaa laadukkaan kuvan ja äänen tietokoneen avulla, helpompaa olisi vain pystyttää videokamera jalustalle...

Camtasia Record 8 - äänitysasetukset
Helppokäyttöisessä Camtasiassa on webbikameralla äänityksen ja kuvaruudun videoksi kaappauksen lisäksi täysimittainen videoeditori, jonka avulla voi editoida usempaa video- ja ääniraitaa. Videon päälle voi liittäää kuvia ja "call-out" kuvioita (mm. tekstiä, alleviivauksia, nuolia, rinkuloita jne). Ohjelmassa on myös "quiz" toiminto, eli videoon saa mukaan ymmärtämistä tarkistavia kysymyksiä (vaatii tosin webbi-serverin).
Camtasia Studio 8 - videoeditori
Kuvaruudun kaappaamisessa kannattaa ottaa huomioon myös oman ruudun resoluutio. Jos käytössä on full HD näyttö, ei ehkä kannata äänittää koko ruutua, koska esim. valikkotekstit näkyvät jo niin pieninä, ettei niistä saa selvää. Ruudunkaappausohjelmissa voi rajata kaapattavan alueen järkevän kokoiseksi, jolloin videokuvan laatu on parempi. 

Kannattaa siis ehdottomasti käyttää hyväksi 30 päivän trial ennen opetusvideon äänitysohjelmiston ostamista. Koskaan ei voi tietää minkä niistä saa lopulta toimimaan oman laitteiston kanssa. Miksi ohjelmia vielä edes myydään ilman, että niitä voi testata ensin? Harmikseni jouduin ostamaan Pinnacle 18:n vain saadakseni selville, että myös se toimii epäluotettavasti webbikamerani kanssa, videon tallennus tiedostoon epäonnistui useammin kuin onnistui.   

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.