Kurssin viimeisimmän version löydät täältä: O1: 2024
Luku 3.6: Valintoja, valintoja
Tästä sivusta:
Pääkysymyksiä: Pitäisikö vielä treenata valintakäskyä? Miten saan pelini käyttäytymään ennalta-arvaamattomammin? Miten teen pelintapaisia, joissa voin liikuttaa hahmoa vapaasti eri suuntiin?
Mitä käsitellään? if
-käskyä edelleen. Satunnaisuutta.
Esimerkkejä yksityisestä metodista. Lisätehtävissä mm. tyyppi
o1.Direction
.
Mitä tehdään? Ohjelmoidaan: tarjolla on muutama pisteytetty tehtävä ja lisätehtäviä.
Suuntaa antava työläysarvio:? Pisteytettyihin tehtäviin menee tuskin tuntiakaan. Lisätehtävissä on haastavampiakin.
Pistearvo: A25.
Oheismoduulit: FlappyBug, Odds. Lisätehtävissä MoreApps (uusi).
FlappyBug-tehtävä (osa 13/17: toistuva este)
Alkusanat
FlappyBug-pelissämme maiseman poikki kulkee toistaiseksi este vain kerran. Se ei oikein tyydytä. Tyydyttävämpää olisi, jos ötökälle tulisi toistuvasti uusia esteitä ohitettavaksi.
Voimme lähestyä ongelmaa kahdella eri tavalla:
- Kun este on liikkunut pois näkyvistä maiseman vasemmasta reunasta eli ei ole enää "aktiivinen", luodaan uusi esteolio, joka sijaitsee oikealla. Korvataan peliin aiemmin liitetty esteolio tällä uudella esteellä. Vanha esteolio jää ilman käyttöä.
- Kun este on liikkunut pois näkyvistä maiseman vasemmasta reunasta eli ei ole enää "aktiivinen", siirretään se oikealle yksinkertaisesti vaihtamalla sen koordinaatteja. Teknisessä mielessä ötökkä siis kohtaa saman esteolion aina vain uudelleen, mutta käytännössä näyttää siltä kuin oikealta saapuisi toistuvasti uusia esteitä.
Kumpikaan vaihtoehdoista ei ole yksiselitteisesti parempi kuin toinen. Valitsemme nyt jälkimmäisen tavan, joka on helppo toteuttaa.
Tehtävänanto
Lisää ensin Obstacle
-luokkaan vaikutukseton ja parametriton metodi isActive
, joka
palauttaa true
, jos esteen oikea reuna on ruudun vasemmassa laidassa tai sen oikealla
puolella, ja false
muuten. Esimerkiksi jos 50-säteisen esteen keskipisteen x-koordinaatti
on -50, niin este juuri ja juuri luetaan vielä aktiiviseksi, mutta yhtään pienemmällä
koordinaatilla ei luettaisi.
Muokkaa sitten estettä liikuttavaa approach
-metodia. Obstacle
-luokassa on siitä
ennestään tällainen versio:
def approach() = {
this.currentPos = this.currentPos.addX(-ObstacleSpeed)
}
Muuta metodi sellaiseksi, että se tilanteesta riippuen joko liikuttaa estettä vasemmalle tai siirtää sen takaisin oikealle. Tarkemmin sanoen:
- Mikäli este oli kutsuhetkellä aktiivinen, niin se liikkuu kuten ennenkin.
- Mikäli este ei ollut aktiivinen, niin sen uudeksi x-koordinaatiksi tulee näkyvän pelimaailman leveys plus 250 (käytännössä 1250) ja y-koordinaatiksi puolet pelimaailman korkeudesta (käytännössä 200). Este lähtee siis uudelleen liikkeelle jonkin verran pelialueen oikean reunan takaa, pystysuunnassa keskeltä.
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.
Loppusanat
Maiseman poikki kulkee nyt este useasti mutta ilmestyen aina samaan kohtaan. Se ei oikein tyydytä. Tyydyttävämpää olisi, jos esteet ilmestyisivät arvaamattomampiin paikkoihin.
Miten saisimme esteen koordinaatit valittua satunnaisesti?
Tämä onkin ihan oma ongelmansa. Käsitellään satunnaisuutta ensin vähän yleisemmin.
Satunnaisluvuista
Random
-luokka
Hyviä uutisia: Scalassa on luokka nimeltä Random
, jolla voi helposti tuottaa satunnaislukuja:
import scala.util.Randomimport scala.util.Random val generaattori = new Random(74534161)generaattori: scala.util.Random = scala.util.Random@1413cb7 generaattori.nextInt(10)res0: Int = 3 generaattori.nextInt(10)res1: Int = 8 generaattori.nextInt(10)res2: Int = 7 generaattori.nextInt(10)res3: Int = 2 generaattori.nextInt(10)res4: Int = 3 generaattori.nextInt(10)res5: Int = 2
Random
-olioilla on erilaisia arvojen arpomiseen sopivia
metodeita. Usein hyödyllinen on metodi nextInt(n: Int)
, joka
arpoo luvun nollan ja n-1
:n väliltä.Voit itse kokeilla antaa samat käskyt REPLissä. Jos kokeilet, saat täsmälleen
saman luettelon satunnaislukuja nextInt
-metodin palautusarvoina: 3, 8, 7, 2, 3, 2 jne.
Mitä ihmettä? Lukujenhan piti olla satunnaisia.
Näennäissatunnaisluvut
The generation of random numbers is too important to be left to chance.
—Robert Coveyou
"Tuota 30 täysin satunnaista lukua väliltä 0–9" on ihmiselle paha pala purtavaksi. Yksi mahdollisuus on käyttää jotain "riittävän hyvää" matemaattista algoritmia, jolla muodostetaan lukujen sarja. Esimerkiksi:
- Valitse jokin luku N, esim. N=20
- Ota N:s piin desimaali. Se olkoon ensimmäinen "satunnaisluku".
- Määritä seuraava "satunnaisluku" ottamalla piin desimaali kohdasta 2*N.
- Sitten 3*N, 4*N ja niin edelleen
Myös tietokoneelle satunnaislukujen generointi on hankala ongelma. Aitoa satunnaisuutta se ei osaa nyhjäistä tyhjästä.
Linkki
Jos satunnaisuus aiheena kiinnostaa enemmän, lue Random.org-sivuston artikkeli Introduction to Randomness and Random Numbers. Ilmakehästä voi nyhjäistä.
Tietyn algoritmin tuottamat luvut ovat ns. näennäissatunnaislukuja (pseudorandom numbers). Samalla "aloitusluvulla" eli satunnaislukujen siemenellä (seed) saadaan aina sama näennäissatunnaislukujen sarja. Esimerkiksi yllä hahmotellussa algoritmissa N oli siemen, ja aina tätä algoritmia N:n arvolla 20 sovellettaessa saadaan samat luvut.
On kehitelty erilaisia algoritmeja näennäissatunnaislukujen generointiin. Esimerkiksi
Scalan luokka Random
käyttää erästä tällaista algoritmia (johon ei tällä kurssilla
perehdytä tarkemmin). Algoritmin siemenenä toimii luku, joka annetaan oliolle
konstruktoriparametriksi (esim. yllä luku 74534161).
Se, että algoritmi tuottaa tietyllä siemenluvulla aina saman näennäissatunnaislukujen sarjan, voi olla tilanteesta riippuen joko etu (esim. jos on tarpeen pystyä toistamaan tietty alun perin satunnaisesti valittu tapahtumasarja) tai haaste (jos halutaan joka kerta täysin erillinen satunnaislukusarja).
Siemenluku kellonajasta
On erilaisia tapoja valita siemenluku. Joskus voi olla perusteltua pyytää siemenluku käyttäjältä. Voidaan myös käyttää apuna jotakin ympäristön "riittävän satunnaista" piirrettä; perinteinen konsti on käyttää siemenenä tietokoneen ajohetkistä päiväystä ja kellonaikaa esimerkiksi nanosekunnin tarkkuudella.
Monissa tilanteissa ei ole väliä, mitä nimenomaista siemenlukua käytetään. Siksi
scala.util
-pakkaukseenkin on määritelty Random
-luokan lisäksi myös
Random
-niminen yksittäisolio, jolta voi pyytää kellonajan pohjalta "arvottuja"
satunnaislukuja luomatta erikseen Random
-oliota lainkaan:
import scala.util.Randomimport scala.util.Random Random.nextInt(10)res6: Int = 8 Random.nextInt(10)res7: Int = 6 Random.nextInt(10)res8: Int = 2
Jos kokeilet näitä käskyjä itse, saat (erittäin todennäköisesti) eri palautusarvot.
FlappyBug-tehtävä (osa 14/17: arvaamattomampi este)
Pohjustus: randomLaunchPosition
-metodi
Laaditaan Obstacle
-luokkaan uusi metodi, jonka tehtävänä on arpoa lähtösijainti ruudun
oikealta puolelta lähtevälle esteelle. Tässä alku:
private def randomLaunchPosition() = { val launchX = Laske yhteen ruudun leveys (1000), esteen säde ja satunnainen kokonaisluku väliltä 0—499. val launchY = Arvo satunnainen kokonaisluku, joka on vähintään 0 ja pienempi kuin ruudun korkeus (400). new Pos(launchX, launchY) }
Obstacle
-luokan sisäiseen käyttöön eikä kuulu julkiseen
rajapintaan. (Vrt. yksityiset muuttujat; luku 3.2.)Tehtävänanto
- Toteuta
randomLaunchPosition
. Käytä yllä olevaa koodia pohjana ja täydennä se puuttuvin osin. - Muokkaa
approach
-metodia niin, ettei se aseta vasemman laidan ohittanutta estettä vakiopaikkaan vaan kutsuurandomLaunchPosition
-metodia saadakseen sille uuden sijainnin. - Muokkaa
Obstacle
-luokkaa niin, ettei estettä luodessa enää anneta konstruktoriparametriksi lähtösijaintia vaan vain säde. Sen sijaan luotava esteolio käyttäärandomLaunchPosition
-metodiaan arpoakseen itselleen lähtösijainnin.
Ohjeita ja vinkkejä
- Käytä arpomisolioon
Random
-yksittäisolion metodia, niin saat eri pelikerroilla erilaisia tuloksia. - Voit myös kokeilla siemenluvun kirjaamista koodiin ja havaita, että tällöin este ilmestyy joka pelikerralla samoihin paikkoihin.
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.
Pelottavampaa grafiikkaa peliin
Hylkää FlappyBugApp
-ohjelman toistaiseksi käyttämä rockPic
. Vaihda esteen
kuvaksi Pic("obstacle.png")
, jonka skaalaat oikean kokoiseksi metodikutsulla
scaleTo(esteenHalkaisija)
. Pelaa jos uskallat.
Lisää tehtäviä
Odds-tehtävä (osa 9/9)
Lisää Odds-moduulin samannimiseen luokkaan metodi eventHappens
, joka arpoo,
toteutuuko tapahtuma, jolla on Odds
-olion kuvaama todennäköisyys tapahtua:
val nopallaKuutonen = new Odds(5, 1)nopallaKuutonen: Odds = 5/1 nopallaKuutonen.eventHappens()res9: Boolean = false nopallaKuutonen.eventHappens()res10: Boolean = false nopallaKuutonen.eventHappens()res11: Boolean = true
Metodia kutsuttaessa tulee satunnaisesti joko true
tai false
.
Tässä nopanheittoa kuvaavassa tapauksessa false
tulee koko lailla
viisi kertaa niin usein kuin true
.
Metodi on vaikutuksellinen, koska se kutsuu vaikutuksellista nextInt
-metodia.
Käytä siksi määrittelyssä tyhjiä kaarisulkeita parametriluettelona (luku 2.6).
Metodi nextInt
lasketaan vaikutukselliseksi, koska se vaikuttaa
satunnaislukugeneraattorin sisäiseen tilaan.
Muista, että Random
pitää ottaa käyttöön pakkauksesta scala.util
. Ja muista
että Random.nextInt(n)
palauttaa luvun nollan ja n-1
:n väliltä.
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.
Ohjastusta näppäimistöllä
MoreApps-moduulin pakkauksessa o1.trotter
on pieni sovellus, jossa voi juoksuttaa
virtuaalista heppaa ruudukkotaustaa vasten. Heppa liikkuu ruudusta toiseen kellon
tikittäessä. Sen suunta vaihtuu nuolinäppäimillä, tai ainakin on tarkoitus vaihtua.
Pakkauksesta löytyy luokka TrotterGame
, jota käytämme aihealueen mallina. Voit
tutustua sen koodiin muiltakin osin, mutta tämän tehtävän kannalta keskeiset asiat
on selitetty tässä:
val game = new TrotterGame(5, 40)game: o1.trotter.TrotterGame = a 5-by-5 grid game.horseHeadingres12: o1.Direction = Direction.Right game.horseHeading = Direction.Up
horseHeading
arvo on O1Libraryyn kuuluvaa tyyppiä Direction
. Direction
kuvaa
suuntia sellaisissa kaksiulotteisissa koordinaatistoissa,
joiden sijainteja kuvaamme Pos
-olioilla.var
-muuttuja, joten voimme sijoittaa sille uuden
arvon. Mielekkäitä arvoja ovat tässä Direction.Up
,
Direction.Down
, Direction.Right
ja Direction.Left
.Moduulista löytyy myös käyttöliittymä TrotterApp
, joka luo isomman ruudukon.
Kokeile ajaa se. Heppa liikkuu. Voit painella nuolinäppäimiä, mutta huomaat, että
hepan saa käännettyä niillä vain ylös.
TrotterApp
-ohjelmassa on valmiina grafiikan tuottava koodi ja onTick
-metodi.
Lisäksi siellä on alku onKeyDown
-metodille, jonka tehtävänä on tulkita näppäinten
(Key
) painallukset ja valita hepalle näppäintä vastaava suunta (Direction
).
Annettu koodi on tällainen:
override def onKeyDown(key: Key) = {
if (key == Key.Up) {
game.horseHeading = Direction.Up
}
}
Koodissa esiintyy kaksi eri Up
-käsitettä:
Key.Up
on vakio, joka tarkoittaa ylöspäin osoittavaa
nuolinäppäintä. Direction.Up
on suunta suoraan ylös,
kohti pienempiä y-koordinaatteja.Virallinen tehtäväsi on vain täydentää tämä metodi sellaiseksi, että se ohjaa
heppaa myös muihin kolmeen pääsuuntaan (Right
, Down
, Left
). Voit tehdä
tämän lisäämällä metodiin vastaavia if
-käskyjä (vaikka koodista näin konstein
tuleekin toisteista).
Voit myös kehitellä ohjelmaa pidemmälle haluamallasi tavalla.
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.
Kiihdytystä näppäimistöllä
MoreApps-moduulin pakkauksessa o1.charger
on edellistä muistuttava sovellus,
jossa kappaletta liikutetaan koordinaatistossa. Tässä sovelluksessa näppäimet antavat
“ryntääjälle” vauhtia, joka kasvaa näppäintä pohjassa pidettäessä.
Annettu koodi ei saa ryntääjää liikkeelle. Korjaa asia:
Täydennä
onKeyDown
-metodi vastaavaksi kuin aiemmassa tehtävässä: käyttöliittymän on havaittava neljän nuolinäppäimen painallukset ja kutsuttava niitä vastaavillaDirection
-parametreilla ryntääjänaccelerate
-metodia.Tutustu
Charger
-luokan koodiin. Luokan haluttu toiminta on kuvattu Scaladoc-kommenteissa ja niiden perusteella luodussa dokumentaatiossa. Suuri osa on jo toteutettu, mutta huomaat, että osia puuttuu.Täydennä
if
-käskyn haarat metodiinaccelerate
niin, että ne säätävät ryntääjän vauhtia ja kulkusuuntaa halutusti.Täydennä
move
-metodi niin, että se muuttaa ryntääjän sijaintia vauhdin ja suunnan perusteella.- Annetussa koodissa on esimerkki
Direction
-oliondx
-muuttujasta, joka kertoo, paljonko x-koordinaatti muuttuu, jos liikutaan yksi yksikkö kyseiseen suuntaan.Direction.Right
indx
on siis +1,Left
in -1, ja ylä- ja alasuuntien nolla. Vastaavasti on olemassady
. - Tuota tietoa hyödyntämällä on
move
yksinkertaisempi toteuttaa. (Voit myös palata etsimään vinkkiä edellisen tehtävänTrotterGame
-luokasta.)
- Annetussa koodissa on esimerkki
Kokeile ohjelmaa.
Ryntääjän kuvan soisi vastaavan sen suuntaa. Muutos on helppo. Tiedämme jo, että
Pic
-luokassa on pyörittämiseen sopivat metoditclockwise
jacounterclockwise
(luku 2.3). Lisäksi jokaisellaDirection
-oliolla on metoditoDegrees
, jota voi käyttää näin:Direction.Up.toDegreesres13: Double = 90.0 Direction.Left.toDegreesres14: Double = 180.0
Vapaasti muotoillen: metodi kertoo, montako astetta kyseinen suunta poikkeaa oikealle osoittavasta suunnasta vastapäivään lukien. Esimerkiksi
Direction.Up
on 90 astetta vastapäiväänDirection.Right
ista.Muokkaa käyttöliittymän
makePic
-metodia niin, että se pyöräyttää kuvan osoittamaan kohti menosuuntaa.
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.
Nopeuden mallintaminen Velocity
-luokalla
Äsken kuvasimme erikseen ryntääjän vauhtia (sijainnin muutosten suuruutta) ja suuntaa. Yhdessä vauhti ja suunta muodostavat nopeuden (velocity).
On luontevaa ja kätevää määritellä nopeuden käsitettä kuvaamaan oma luokkansa. Eikä sinun nyt tarvitse määritellä sitä itse: nopeus on monessa ohjelmassa hyödyllinen käsite, jota vastaava luokka löytyy kurssin ohjelmakirjastosta.
val test = new Velocity(Direction.Up, 12.3)testVelocity: o1.world.Velocity = Velocity(Direction.Up,12.3) test.directionres15: o1.world.Direction = Direction.Up test.speedres16: Double = 12.3
Velocity
-luokassa on paljon metodeita, joista osasta on hyötyä myöhemmin
ja osa sopii käytettäväksi juuri nyt:
- Silmäile
Velocity
-luokan dokumentaatiota. Huomaa erityisesti metoditfaster
,noFasterThan
janextFrom
. - Refaktoroi
Charger
-luokkaa (eli muokkaa koodia sen toiminnallisuutta muuttamatta): Korvaa erillisetangle
- jaspeed
- muuttujat yhdelläVelocity
-tyyppisellä muuttujalla. Käytä tätä muuttujaa metodienheading
,accelerate
jamove
uusituissa versioissa.- Älä koske luokan julkiseen rajapintaan. Metodien tulee edelleen tehdä samat asiat kuin ennenkin.
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.
Sulavaa liitoa näppäimistöllä
Äskeisessä ohjelmassamme on monia vajavaisuuksia. Härkä kääntyy kovin jähmeästi. Lisäksi tapa, jolla näppäimenpainalluksiin reagoidaan, ei ole teknisesti tyydyttävä:
- Ohjelmaa ajava ympäristö kutsuu
onKeyDown
-metodia, kun näppäin painuu alas. Lisäksi tuo metodi tulee kutsutuksi silloin tällöin niin kauan kuin näppäin pysyy alhaalla. Näiden myöhempienonKeyDown
-kutsujen määrä ei kuitenkaan ole standardi ja riippuu osin ympäristöstä, jossa ohjelmaa ajetaan. Ohjelmamme käyttäytyminen ei siksi ole luotettavalla pohjalla. - Saman
onKeyDown
-metodin luonteesta johtuen usean näppäimen käyttö yhdistelmänä ei toimi niin kuin voisi toivoa: jos näpäytät yhtä nuolinäppäintä toisen ollessa pohjassa, niin ohjelma "unohtaa" pohjassa olleen suunnan. (Kokeile.) Tämä ei tunnu luonnolliselta eikä lupaa hyvää, jos vaikka haluaisimme liikuttaa härkää vinoon kahden näppäimen yhdistelmällä.
Käsitellään pohjassa olevat näppäimet hieman toisin. Tämä toinen tapa on aavistuksen mutkikkaampi mutta toisaalta helpottaa sulavampien liikkeiden ohjelmointia.
Pakkauksessa o1.glider
on pohjakoodi "liituria" ohjaavalle ohjelmalle. Se muistuttaa
äskeistä ohjelmaa monin osin.
- Tutustu
GliderApp
-ohjelmaan. Huomaa ainakin nämä:onTick
-tapahtumankäsittelijä yksinkertaisesti komentaa liituria liitämään kullakin kellonlyömällä.- Keskeinen uudistus verrattuna edelliseen
ohjelmaan löytyy metodista
onKeyDown
: se ei varsinaisesti kasvata liiturin nopeutta vaan vain asettaa tiedon siitä, että "kaasu on pohjassa", kun ylänuolinäppäintä painetaan. - Vastaava
onKeyUp
käsittelee näppäimen irtipäästötapahtumia.
- Tutki
Glider
-luokkaa. Huomaa ainakin nämä:- Liiturin nopeus on kuvattu
Velocity
-oliolla. - Lisäksi liiturilla on kolme
Boolean
-tyyppistä ominaisuutta, jotka kertovat, onko kaasu pohjassa sekä onko "rattia" käännetty vasempaan tai oikeaan. - Liikkeestä huolehtii
glide
-metodi apumetodeineen. Se säätää nopeutta ohjaimien perusteella ja liikuttaa liituria säädetyn nopeuden mukaan. - Liiturissa ei ole jarruja mutta "kitka" hidastaa liituria hieman joka liikahduksen lopuksi, joten ilman kaasutusta liituri pysähtyy aikanaan itsekseen.
- Liiturin nopeus on kuvattu
- Varsinainen liiturin siirtäminen ja kitkan huomiointi ovat
valmiina. Toteuta nopeuden ja suunnan säätö; tavoite on
selitetty
glide
-metodin kuvauksessa.- Huomaat, että
glide
delegoi tämän osatehtävän yksityiselle apumetodilleadjustVelocity
. Voit tehdä tarvittavat muutokset sinne.
- Huomaat, että
- Voit jo tässä vaiheessa koeajaa
GliderApp
in. Liiturin pitäisi lähteä ylänuolta painaessa eteenpäin ja vähitellen hidastua itsestään. Se ei vielä käänny. - Täydennä
GliderApp
in tapahtumankäsittelijät niin, että ne välittävät tiedon sivunuolten painalluksistaGlider
-oliolle.
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.
Toinenkin liituri?
Jos haluat, voit kokeilla lisätä näkymään toisenkin liiturin, joka
liikkuu esimerkiksi W
-, A
-, ja D
-näppäimillä.
Jos tuloksena syntyi toimivaa mutta toisteista koodia, voit miettiä, miksi niin kävi. Kurssin edetessä löydämme lisää keinoja toiston kitkemiseen.
Lisänäppäimiä
Miten olisi helppo reagoida esimerkiksi Shift
-painallukseen hiirellä? Tai
selvittää, onko Shift
-, Ctrl
-, tai Alt
-erikoisnäppäin pohjassa,
kun toista näppäintä painetaan?
Luvun 3.1 lisätehtävässä käsittelijämetodin parametrina oli hiirenklikkausta kuvaava
MouseClicked
-olio eikä pelkkä klikkauksen sijainti. Tapahtumankäsittelijoitä
voi muutenkin määritellä niin, että käsittelijämetodi saa parametrikseen viittauksen
kyseistä tapahtumaa yleisesti kuvaavaan olioon. Tällaiselta tapahtumaa kuvaavalta oliolta
voi pyytää tiedon esimerkiksi siitä, onko tietty erikoisnäppäin painallettuna
tapahtumahetkellä. Tässä pari esimerkkiä:
override def onClick(mouseEvent: MouseClicked) = {
println(mouseEvent.isControlDown)
}
override def onKeyDown(keyPressEvent: KeyPressed) = {
println(keyPressEvent.isAltDown)
}
Voit kokeilla lisätä tällaiset metodit johonkin aiemmista ohjelmista. Voit myös
etsiä muita vastaavia tapahtumankäsittelijöitä View
-luokan dokumentaatiosta. Ehkä kehität myös jonkin sovelluksen, jossa
erikoisnäppäimillä on vaikutus ohjelman toimintaan?
Lisälukemista satunnaisuudesta
Satunnaisuuden sovelluksia
Ylempänä jo mainittiinkin johdantoartikkeli Introduction to Randomness and Random Numbers.
Vaikkapa nettipokerissa.
Isot simulaatiot, jollaisia käytetään esimerkiksi sään ennustamiseen, voivat toimia huonosti, jos tuotettujen satunnaislukujen jakauma on vähänkin pielessä.
Tietyissä yhteyksissä heikko satunnaisuus aiheuttaa tietoturvaongelmia. Jos satunnaislukugeneraattori on ennustettavissa, sitä voidaan hyödyntää hyökkäyksissä.
Lisätietoja löytyy esimerkiksi englanninkielisen Wikipedian artikkelista Applications of Randomness.
Yhteenvetoa
- Satunnaisten lukujen arpominen ei ole ongelmatonta.
- Muun muassa Scala-peruskirjastossa on välineitä näennäisen satunnaisuuden tuottamiseen.
- Luokan sisäiseen käyttöön voi laatia yksityisiä apumetodeita.
- Lukuun liittyviä termejä sanastosivulla: if; näennäissatunnaisluku, satunnaislukujen siemen; yksityinen.
Palaute
Huomaathan, että tämä on henkilökohtainen osio! Vaikka olisit tehnyt lukuun liittyvät tehtävät parin kanssa, täytä palautelomake itse.
Tekijät
Tämän oppimateriaalin kehitystyössä on käytetty apuna tuhansilta opiskelijoilta kerättyä palautetta. Kiitos!
Materiaalin luvut tehtävineen ja viikkokoosteineen on laatinut Juha Sorva.
Liitesivut (sanasto, Scala-kooste, usein kysytyt kysymykset jne.) on kirjoittanut Juha Sorva sikäli kuin sivulla ei ole toisin mainittu.
Tehtävien automaattisen arvioinnin ovat toteuttaneet: (aakkosjärjestyksessä) Riku Autio, Nikolas Drosdek, Joonatan Honkamaa, Jaakko Kantojärvi, Niklas Kröger, Teemu Lehtinen, Strasdosky Otewa, Timi Seppälä, Teemu Sirkiä ja Aleksi Vartiainen.
Lukujen alkuja koristavat kuvat ja muut vastaavat kuvituskuvat on piirtänyt Christina Lassheikki.
Yksityiskohtaiset animaatiot Scala-ohjelmien suorituksen vaiheista suunnittelivat Juha Sorva ja Teemu Sirkiä. Teemu Sirkiä ja Riku Autio toteuttivat ne apunaan Teemun aiemmin rakentamat työkalut Jsvee- ja Kelmu.
Muut diagrammit ja materiaaliin upotetut vuorovaikutteiset esitykset laati Juha Sorva.
O1Library-ohjelmakirjaston ovat kehittäneet Aleksi Lukkarinen ja Juha Sorva. Useat sen keskeisistä osista tukeutuvat Aleksin SMCL-kirjastoon.
Tapa, jolla käytämme O1Libraryn työkaluja (kuten Pic
) yksinkertaiseen graafiseen
ohjelmointiin, on saanut vaikutteita tekijöiden Flatt, Felleisen, Findler ja Krishnamurthi
oppikirjasta How to Design Programs sekä Stephen Blochin oppikirjasta Picturing Programs.
Oppimisalusta A+ luotiin alun perin Aallon LeTech-tutkimusryhmässä pitkälti opiskelijavoimin. Nykyään tätä avoimen lähdekoodin projektia kehittää Tietotekniikan laitoksen opetusteknologiatiimi ja tarjoaa palveluna laitoksen IT-tuki. Pääkehittäjänä on tällä hetkellä Markku Riekkinen, jonka lisäksi A+:aa ovat kehittäneet kymmenet Aallon opiskelijat ja muut.
A+ Courses -lisäosa, joka tukee A+:aa ja O1-kurssia IntelliJ-ohjelmointiympäristössä, on toinen avoin projekti. Sen ovat luoneet Nikolai Denissov, Olli Kiljunen ja Nikolas Drosdek yhteistyössä Juha Sorvan, Otto Seppälän, Arto Hellaksen ja muiden kanssa.
Kurssin tämänhetkinen henkilökunta löytyy luvusta 1.1.
Joidenkin lukujen lopuissa on lukukohtaisia lisäyksiä tähän tekijäluetteloon.
Random
-oliot ovat "satunnaislukugeneraattoreita". Niitä kuvaava luokka löytyy pakkauksestascala.util
. (Tämä Scala API:n pakkaus sisältää sekalaisia työkaluja. Sen nimi tulee sanasta utilities.)