And the WINNER iiiiis….

lokakuu 24, 2007

Voitokkaan roboturnauksen jälkeen on helppo hymyillä! Javasotureiden edustusrobotti kun meni ja otti kilpakumppaneihinsa nähden ylivertaisena himoitun voiton odotetusta ja haasteellisesta turnauksesta! Ensimmäisessä osaottelussa Soturi jäi tosin jumittamaan kahden ruudun välille, mutta tämä kaikki oli osa taktiikkamme, sillä näin vastustajillemme syntyi illuusio siitä, että robottimme ei ole varteenotettava voittajaehdokas. (Eräs toinenkin ryhmä taisi käyttää tätä hämäysstrategiaa, he vaan eivät osanneet lopettaa sen käyttöä ajoissa ;) ). Annettuamme ensin hieman etumatkaa kilpakumppaneillemme, käskimme Soturin ryhtyä tositoimiin ja äännekkään kannustuksen säestyksellä robottimme selvitti labyrintin kuin labyrintin ja usein myös nopeimpana ja tehokkaimpana! Kyllä siinä jokaisen tosi Javasoturin sydän oli pakahtua ylpeydestä, kun tulostaululla komeili voittoon riittänyt pistemäärä 25! Tasapisteisiin päätyneet Stud- ja Vompattirobotit taistelivat vielä keskinäisestä paremmuudestaan ja kakkossijasta, kun Hepalonrobotti sai tyytyä ansaituun pistemääräänsä 4 ja sijaan neljä.

Soturi saavutti lopullisen rakenteensa useammassa yhteiskoodaus ja -tuumaushetkissä, sekä Antin viimeistely- ja käsittelysessioissa. Viimeistä hiontatilaisuutta vietettiin tiistaina Paniikissa ennen keskiviikon turnausta. Silloin tarkistettiin robotin toimivuus ja viilattiin viimeiset koodin pätkät kuntoon. Soturirobotti palautettiin ajallaan ja tyytyväiset javakollegat poistuivat kukin mihinkin suuntaan odottamaan tulevaa jännitysnäytelmää.

Ensimmäinen yhdessä koodattu projekti oli mielenkiintoinen. Etenkin lähtö oli hankala: miten saada kymmenen ihmistä koodaamaan yhtä koodia, kun kaikki eivät edes mahdu yhden näytön eteen?! Alkukankeuden jälkeen rytmi alkoi löytyä ja huomasimme, että yhdessä koodaamisen parasta antia on se, että pystyy miettimään ja purkamaan ongelmia keskustelemalla. Helpointa oli silti, että itse koodia kirjoitti kerrallaan korkeintaan muutama ihminen. Kokemus oli opettavainen ja antoi varmasti jokaiselle jotakin!


Purkusessio 6: Ongelmia

lokakuu 23, 2007

T-talon käytävien katu-uskottavin olo-tiimi kerääntyi vaihteeksi täysilukuisena yhteen keskustelemaan ongelmistaan tiistain kunniaksi. Puheenjohtajamme Maiju ”89” Tompuri nosti heti alkajaisiksi kissan pöydälle kyselemällä phuksiparkoja aikaisemminkin kauhistuttaneesta rekursiosta.

Matematiikassa rekursio määritellään keinona kertoa funktion arvo tietyssä pisteessä hyödyntämällä funktion arvoa edellisessä pisteessä. Rekursiota käytetäänkin erityisesti tietotekniikassa, jossa rekursiivisesti lasketut välitulokset tallennetaan useimmiten pinoon. Viimeisellä rekursiokierroksella pinosta kerätään vastaukset käänteisessä järjestyksessä.

Rekursiokäärme
Psykedeelinen rekusiomönkiäinen matkalla ajasta ikuisuuteen.

Purkusessiossa selvisi rekursion hyödyntämisestä Javassa seuraavaa: Tietyt matemaattiset toimitukset on helppo esittää lyhyesti rekursiokaavalla, kuten esimerkiksi kertoma:

private static long kertoma (int n) {
if (n==0) {
return 1;
}
else {
return n*kertoma(n-1)
}
}

Rekursiota käytettäessä tulee kuitenkin varmistaa, ettei synny ns. ikuista silmukkaa, jossa metodit kutsuvat toisiaan toistuvasti. Lopputuloksena oravanpyörästä seuraa usein StackOverFlow error, jossa pinomuisti kulutetaan loppuun ja ohjelman suoritus keskeytyy.

Tutkimuksen kohteena oli lisäksi hakemistorakenteen läpikäynti, kuten esimerkiksi kotihakemiston syövereissä seikkaileminen pseudokoodin avulla. Antti esitteli piirustustaitojaan esittelemällä systeemin, jossa ohjelma etsii haluttua tiedostoa kansioista leikkaamalla etsittävän alan aina puoliksi. Tässäkin siis hyödynnettiin eräällä tavalla rekursiota.


Tapaus 6: alustus

lokakuu 23, 2007

Viime keskiviikkona tutustuimme tapaukseen 6. Työotsakkeeksi muotoutui ytimekkäästi Ongelmia. Muutaman kevyen virikkeen jälkeen siirryimme tehtävien kimppuun. Tehtävät käsittelivät muun muassa rekursiota ja javaharjoituksista inspiroituja ongelmallisia tapauksia. Ongelmia esiintyi:

  • päätymätön rekursio
  • sisäkkäiset arkut
  • Carcassonnen kaupungit

Päädyimme siis seuraavanlaisiin oppimistavoitteisiin

  • rekursio yleisesti (hyödyntäminen)
  • hakemistorakenteen läpikäynti (esim. Kotihakemiston läpikäynti pseudokoodilla)
  • rekursion vahvuudet ja heikkoudet

SoturiRobotin ongelmien läpikäyntiä

lokakuu 21, 2007

Keskiviikkoisen osallistujamäärältään vajaaksi jääneen OLO-session jälkeen oli vuorossa robotin viilausta. Antti oli ahkerasti vääntänyt koodia ja koko tapaaminen alkoikin sen läpikäynnillä. Ongelmana oli robotin jumiutuminen erinäisissä kohdissa. Päätimme hylätä robotin alkuperäisen tavan asettaa kieltoja suunnille ja kehittää järkevämmän toimintatavan. Törmäsimme ongelmiin parhaan suunnan valinnassa (en mene tässä vielä yksityiskohtiin, onhan koko turnaus vielä käymättä ja erinäinen vakoilu on aina suuri uhka kilpailussa ;) ) ja ratkaisu oli kaikkea muuta kuin elegantti. Parin tunnin jälkeen koodaamisen tehokkuus oli pudonnut murto-osaan alkuperäisestä, robotti ei vieläkään toiminut halutulla tavalla ja osalla ryhmästä huohottivat Marathonin siirtämät DL:t niskaan, joten päätimme siirtää (siirtäminen on aina ratkaisu kaikkeen?) Soturin hiomista myöhempään ajankohtaan.


Purkusessio 5

lokakuu 20, 2007

Viikon 42 olo-sessio lähti hiukan hiljaisemmin käyntiin kuin aiemmat sessiot, ryhmämme jäsenmäärä oli nimittäin vähän normaalia pienempi. Olo oli tavallisuudesta poiketen keskiviikkona, eikä koko ryhmämme ollut täysin perillä uudesta aikataulusta. Pääsimme kuitenkin purkusessioon käsiksi, kun avaussesion sihteerinä toiminut Laura otti ohjat käsiinsä ja toimi purun puheenjohtajana poissaolevan Johanneksen sijaan.

Tapaus 5 avauksessa sovimme yhteisistä oppimistavoitteista, joita olivat tapauksen koodin korjaaminen sekä asetaNaapuri()-metodin keksiminen, erilaiset debug-tavat ja ystävämme rekursio. Jätimme suosiolla ensimmäisen oppimistavoitteen läpikäymättä, kaikki olivat ohjelmointitehtävää varten luoneet asetaaNaapuri()-metodin, ja virheitä olimme korjailleet avauksessa jo aivan kylliksi. Siirryimme siis suoraan päätä rekursioon ja debug-tapoihin.

Purkusession keskustelu oli joltain osin ehkä hieman laimeaa, mutta tärkeimmät asiat tulivat varmasti kaikille selväksi. Rekursio on tarkoittaa siis ongelmanratkaisuperiaatetta, jossa ongelma jaetaan pienempiin osaongelmiin, jolloin ratkaisusta tulee ymmärrettävämpi ja yksinkertasempi. Metodi voi kutsua itse itseään(suora rekursio) tai jonkun toisen kautta(epäsuora rekursio. Rekursion yksi vaaroista on päättymättömän rekursion aiheuttaminen, jolloin metodi kutsuu itseään yhä uudestaan ja uudestaan ja uudestaan….

Debug-tapoja keksimme useita, olimmehan varmaankin kaikki joutunet käyttämään niitä ohjelmoidessamme pelimaailmaa. Virheitä voi siis vähentää ja paikantaa tekemällä ohjelmaa pienissä osissa. Lisäksi ohjelman metodeihin voi lisätä tulostuksen, jolloin ohjelmaa ajettaessa selviää, missä virhe oli. Koodin kommentointi auttaa ymmärtämistä, sekä myöhemmin on helppo muistella, mitä tuli koodatessa tehtyä ja ajateltua. Ongelmat on myös hyvä jakaa pieniin osiin, tehdä vaikka apumetodeja, joita sitten käyttää isompaan kokonaisuuteen. Lauran hyvä idea ongelmien välttämiseksi oli koodin kirjoittaminen ensin selvällä suomenkielellä. Sen jälkeen näistä itse kirjoitetusta “ohjeista” on helppo (tai helpompi) koodata itse java-kieltä.

Tapaus olikin nopeasti purettu, joten siirryimme suosiolla eteenpäin, tapaukseen 6 sekä hiukan myöhemmin koodaamaan soturirobottiamme, joka kauniista koodista huolimatta juuttui vielä silloin tällöin paikalleen tai jäi hyppimään kahden ruudun välille.


Satunnaista mutta järkevää, onnistuuko?

lokakuu 14, 2007

Toinen ohjelmointitehtävä käsitteli seikkailupelimaailman Carcassonne-tyyppisen rakenteen toteuttamista. Ensimmäisissä osatehtävissä koodailtiin maailman rakenteeksi maastoja, sektoreita ja karttaruutuja ja niille jos jonkinmoista pyöritystä ja kieputusta.

Uusina asioina tuli ainakin Enumertaatiot, joiden käytännöllisyys kuitenkin jäi vielä hieman hämärän peittoon. Muut uudet asiat olivat aika peruskauraa, mutta sitäkin enemmän pohtimista ja raakaa koodaamista vaati joidenkin rakenteiden toteuttaminen.

Neljä ensimmäistä osatehtävää sain hullun melkein 10-tuntisen koodauspäivän jälkeen suurinpiirtein valmiiksi jo maanantaina. Luulin jo saavani lähes koodausvapaan loppuviikon, mutta viimeinen eli viides osatehtävä osoittautui paljon paljon hankalammaksi kuin miltä se aluksi näytti. Tehtävänä oli luoda järkeviä mutta satunnaisia karttaruutuja generoiva metodi. Tästä tulikin ainakin minun osaltani hyvin monivaiheinen ja monta päivää kestänyt prosessi.

Aluksi koodasin nopeasti täysin satunnaisesti sektoreiden maastoja arpovan metodin päästäkseni testaamaan kurssin tarjoamaa graafista testiohjelmaa. Satunnaisten sektoreiden napsahdellessa nätisti yhteen tuntui hienolta nähdä ensimmäistä kertaa koodinsa tuotoksia graafisessa muodossa. Jokin oli kuitenkin pielessä, sillä hetken paloja lätkittyäni tajusin sinne tänne syntyvän tyhjiä kohtia joihin juuri arvottu pala olisi kyllä käynyt. Koodiani moneen kertaan luettuani ja vielä useammin testiohjelmaa suoritettuani jälkeen virhe kuitenkin paikallistui: yksi i oli vahingossa lipsahtanut l:ksi.

Satunnaisten karttaruutujen muodostamat maailmat eivät kuitenkaan olleet kovin järkeviä, joten oli aika heittää ensimmäinen koodi bittiavaruuteen ja aloittaa aivoriihi. Aloin koodaamaan pitkiä switch-rakenteita ja määrittelin erilaisia järkevien karttaruutujen rakenteita, joista sitten arvottaisiin satunnaisesti. Jossain vaiheessa monen ruudun pituiseksi venynyttä koodia tutkiessani päätin kuitenkin taas heivata koko roskan bittiavaruuteen ja aloittaa alusta.

Tällä kertaa tavoitteenani oli tehdä tehtävänannon mukaisesti homma mahdollisimman yksinkertaisesti ja lyhyesti. Homma osoittautui suhteellisen haastavaksi, mutta lopulta sain pitkän pohdinnan jälkeen aikaan lyhyen, ytimekkään ja vielä tehtävänannon mukaisesti toimivan metodin, johon olin jopa itse tyytyväinen.

Vaikka metodini tekikin järkeviä paloja, niin lisäharmia toi testiohjelmiston kautta ilmennyt ongelma: kun maailmassa on enää muutama tyhjä paikka karttaruuduille, tulisi niihin saada sellaisia ei-järkeviä paloja joita oma generaattorini ei pysty tuottamaan. Tämä aiheutti ohjelman jumiutumisen sen yrittäessä epätoivon vimmalla generoida paloja niin kauan että tyhjiin kohtiin sopiva tulisi eteen.

Ohjelman kaaduttua tarpeeksi monta kertaa alkoi ongelma ottaa päähän, ja lopulta päädyinkin kompromissiratkaisuun: Lisäsin metodiini kohdan, joka 0,05% todennäköisyydellä arpookin satunnaisista sektoreista koostuvan ruudun. Käytännössä siis kone generoi satunnaisen ruudun vasta siinä vaiheessa kun varsinaiset metodini tekemät palat eivät sovi minnekään. Näin sain lopulta kokonaisen maailman generoitua loppuun saakka, eivätkä ne pari viimeistä palaakaan ihan hulluja tunnu olevan. Ainoa ongelma on että sopivan satunnaisen palan generointi (0,05% todennäköisyyden takia) kestää hetken.

-

Huh, tulipas sitten avauduttua tuosta viimeisestä osatehtävästä. Mutta hyvä kun sai pitää oman purkusession, kun ei tänään olekaan Oloa :) Uusi java-tehtäväkin julkaistiin näköjään jo, mutta ehkä pitää pitää pari päivää väliä ennen kuin jaksaa taas siihen paneutua.


OLO Avaus 4

lokakuu 14, 2007

Ohhoh! Melkein jäi koko blogi elämänkiireiden takia unohduksiin! No, parempi myöhään kuin ei milloinkaan. Lisätäänpä tänne vielä vähän infoa viime viikon OLO-session avauksesta, kun sitä ei täällä vielä ole. Blogimme siis seuraa aikansa trendejä, eikä pidä kirjoituksia kronologisessa järjestyksessä pitäviä blogeja juuri minään. Kyllähän jokainen Guy Ritchien tai Quentin Tarantinon elokuvia katsonut tietää, että takaumat korottavat jännitysmomentin toiseen potenssiin. Tässä siis yksi sellainen.

Tehtäväksemme siunaantui, tulevia taistoja alustaen, pohtia toteuttamistapoja erilaisia labyrintteja läpikäyvälle robotille. Työotsakkeeksi oloilulle annoimme ‘Maailman mallintaminen ja siinä liikkuminen’. Virikemateriaalissa robotin kerrottiin jo osaavan metodit kaannyVasemmalle(), kaannyOikealle(), etene(), etenemismahdollisuuksia tutkivan voiEdeta(), sekä mahdollista määränpäähän pääsyä tutkivan olenMaalissa(). Lisäksi käytössä oli ruutu-tyyppisen olion palauttava metodi annaSijainti(). Robotti siis tunsi sijaintinsa, sekä edessään olevan suunnan. Suunta sai arvokseen jonkin neljästä pääilmansuunnasta.

Ensin pohdimme miten maailma, eli labyrintti, voidaan mallintaa. Päädyimme kaksiulotteiseen taulukkoon, johon ruutu-oliot sijoitetaan. Jokainen ruutu voitaisiin ymmärtää huoneena, jossa on neljä seinää. Kaikki ruudut olisivat toisiinsa nähden muuten samanlaisia, mutta huoneiden seinämillä olevien ovien, robotin kulkureittien määrä, vaihtelisi yhden ja neljän välillä.

Kun maailman perusolemus oli selkiytynyt, aloimme pohtia itse robotin toteutusta. Ensimmäisessä ja yksinkertaisimmassa esimerkkilabyrintissa ei ollut lainkaan haarautumia, eli robotin ei tarvinnut kuin osata kääntyä. Robotin ei siis tarvinnut kuin edetä, kunnes mutka tuli vastaan. Mutkassa robotin piti kääntyä, jatkaa etenemistä jos mahdollista, tai toistaa kääntyminen kunnes eteneminen onnistuu. Ryhmämme meinasi jumitua jo lähes poliittiset sävyt saaneeseen keskusteluun siitä, pitäisikö robotin kääntyä vasemalle vai oikealle. Käsittämättömään väittelyyn kyllästynyt assari vihelsi pelin onneksi poikki, ja robotti saatiin tekemään käännös oikeaan (vasempaan) suuntaan. Koska labyrintti ei sisältänyt risteyksiä, ei robotin tarvinnut osata tallentaa tietoa käymättömistä korpimaista, ja eteneminen voitiin toteuttaa ilman voiEdeta() metodin mahdollistamaa eri suuntien tarkastelua.

Seuraavassa labyrintissa robotin oli jo osattava palata umpikujista edelliseen risteykseen. Sen siis tuli tietää milloin ruudussa oli useampi etenemismahdollisuus, ja mitkä niistä se oli jo käyttänyt. Robotin siis piti pyöriä täys kierros ja tutkia etenemisvaihtoehdot voiEdeta() metodin avulla, ja vasta sitten aloittaa liikkuminen. Kolmas labyrintti sisälsi kehiä, joille huonosti suunniteltu robotti saattaisi jumiutua ikuisiksi ajoiksi. Robotti siis tarvitsisi tiedon siitä missä ruuduissa se jo oli käynyt,. Labyrintin tarkastelu jäi hieman pintapuoliseksi ja sen syvällisempi pohtiminen lisättiin oppimistavotteisiin.

Tässä kohtaa takauma loppuu ja jokainen katsoja päästää suustaan “aaaaaaa, nyt mä tajusin”.


SoturiRobotti valmistautuu taisteluun

lokakuu 14, 2007

Viime perjantain Robo-Extrassa aloitimme työstämään ryhmämme tuotosta 24.10. pidettävään Robottiturnaukseen. Esisuunnittelu oli jäänyt olosessioiden varaan, ja todettuamme 10 ihmisen koodaamisen yhdellä koneella hyvin hankalaksi, siirtyi osa ryhmästämme suunnittelemaan ja kirjoittamaan ylös robottimme liikkumislogiikan käyttäen ihan perinteistä kynä-paperi-metodia.

Saimme kuitenkin koodattua robotin peruslogiikan alulle, ja paneuduimme erityisesti erilaisten tallennusmenetelmien käyttöön robotin yhteydessä. Saimmepa aikaan yhden apuluokankin. Robottimme nimesimme ryhmämme mukaisesti SoturiRobotiksi. Sitten nälkä alkoikin jo kurnimaan, ja päätimme lopettaa siltä erää ja lähteä nauttimaan lounasta. Seuraava koodaustuokio sovittiin ensi keskiviikoksi.

Itselleni jäi hieman kaivamaan mieltä robotin keskeneräisyys ja päätinkin vielä tuoreesta muistista koodata lounaan jälkeen kesken jääneet kohdat loppuun. Muutama tunti siinä sitten hujahtikin Paniikissa muiden vääntäessä toista java-tehtävää, mutta lopputuloksena sain peruslogiikat ja tallennukset toimimaan – ja lisäsimpä robotille uuden tietorakenteenkin reitin tallennukseen. Taaksepäin palaamisen logiikkaa tulee kuitenkin vielä kehittää, nykyisellään robotti jää tietyissä tilanteissa palloilemaan edestakaisin.

Vielä pientä viilausta siis, ja robotti on voittamaton. Keskiviikkona jatketaan Soturimme parissa!


AvausOLOilu numero viisi

lokakuu 9, 2007

 

Tämän kertainen OLO lähti sutjakkaasti käyntiin, onhan OLOilu jo meille tuttua puuhaa. Tuskin edes huomasi, että jouduimme viemään session läpi tavallista hieman pienemmällä porukalla. Ahkerana puheenjohtajanamme toimi Johannes ja sihteerinä Laura. Virikkeinä eteemme saimme tekstin ohjelmoinnin haastavuudesta ja koodinpätkän, joka tuntui vilisevän loogisia virheitä. Innokkaimmat lähtivät korjaamaan virheitä jopa ennen kuin puheenjohtajamme oli virallisesti avannut aiheen. Mielikuvituksellisesti ja hilpeyttä herättävästi nimesimme työotsakkeeksi Virheettömättömyyden.

Päätimme aloittaa aiheen käsittelyn korjaamalla koodin virheitä. Ensimmäisten virheiden löytäminen olivat niinkin kokeneille koodareille kuin meille jo aivan lastenleikkiä ja koodi korjaantui niin omiin lappuihimme kuin taululle post-it -lappuihin kirjattuna. Selkeät virheet korjattuamme pääsimme viimeisen, meille eniten päänvaivaa ja keskustelua aiheuttaneen, asetaNaapuri()-metodin kimppuun. Koska täydellistä yhteisymmärrystä metodin ulkomuodosta ei saavutettu, kirjasimme sen miettimisen myös oppimistavoitteisiin. Tärkeintä kuitenkin oli, että jokainen ymmärsi periaatteen, jolla metodia pitäisi ryhtyä rakentamaan.

Lopuksi pohdimme vielä kuinka virheiden syntyä voisi estää, tai ainakin fiksusti jo koodausvaiheessa tarkistaa onko niitä syntynyt. Taululle ilmestyi taas mieltä avartavia lappusia, joiden sisältönä oli muun muassa välitulostuksiin ja koodin pilkkomiseen liittyviä asioita. Debug-tapojen pohtiminenkin jätettiin kotitehtäväksi ja esitettäväksi ensi kerran purkusessiossa. Kolmanneksi oppimistavoitteeksi valitsimme Mikon esimerkkien innoittamina rekursion.

Lupasimme lisäksi kaikki valmistautua perjantaita varten tutkimalla roboturnauksen sääntöjä ja ehkä jopa miettiä kuinka Maailman Paras robottimme selviäisi labyrintissä paremmin kuin muiden ryhmien robotit. Jäämme innolla odottamaan pian alavaa robotin koodausta! Kun assarit vielä session loppuun demonstroivat roboturnauksen toimintaa, oli paketissa taas kerran melkoisen mukava OLOsessio.


Olo-tapaus 4: purku

lokakuu 8, 2007

Tapauksessa 4 olimme saaneet pohdittavaksemme kuinka voimme ohjelmoida virtuaalisen robotin, joka löytää tiensä erilaisten labyrinttien läpi maaliin. OLO-session jälkeen jaoimme oppimistavoitteiksi luokan stack tutkimisen sekä ratkaisun meille esitettyyn kolmanteen labyrinttiin, josta kuva ohessa.

Stack

Useat meistä olivat tulkinneet tämän tavoitteen hiuskarvan ohi tarkoituksen ja opiskelleet pinomuistia engl. stack, vaikka tarkoitus olikin tutkia itse luokkaa stack. Saimme selville, että pinomuistissa muistin varaaminen ja vapauttaminen ovat automaattisia toimintoja. Esimerkiksi paikalliset muuttujat ja parametrit käyttävät pinomuistia. Pinomuistia käytettäessä ohjelman suoritus jaetaan ikään kuin lohkoihin ja jokaisen lohkon alussa varataan lohkon muuttujille niiden tarvitsema tila pinosta. Lohkon lopussa puolestaan vapautetaan tuo tila.

Sen sijaan itse luokka Stack on työkalu tällaisen muistin hallitsemiseen. Sen tarjoama metodi push asettaa muistipinoon jotain ja metodi pop ottaa sieltä pois. Pinomuistista voidaan ottaa ja lisätä vain pinon päälle/päältä eli pinon keskellä sijaitseviin osiin ei päästä suoraan käsiksi. Assarimme Mikko esitti tämän hyvin havainnollisesti post-lappujen pinona. Luokka stack tarjoaa myös muita metodeja pinon tutkimiseen ja muokkaamiseen.

Labyrintti 3

Ideamme oli, että tehdään while-silmukka, joka pyörii niin kauan kuin metodi olenMaalissa() ei päde. Silmukan sisällä yritetään kääntyä vasemmalle ja jos se onnistuu, lähdetään vasemmalle, jos ei, kokeillaan oikeaa, jos ei vieläkään napannut, yritetään mennä eteenpäin ja jos ollankin umpikujassa tai ollaan jo oltu kyseisessä ruudussa, niin palataan takaisinpäin.

Pohdimme paljon sitä, että olisi järkevää tallettaa tiedot kaikista ruuduista, joissa ollaan oltu ja kaikista ruuduista, joissa on ollut enemmän kuin yksi suuntavaihtoehto (paluun lisäksi) ja saimmekin aikaan ratkaisun, mutta sitä tarvittaisiin vasta neljännessä labyrintissa ja nyt tehtävämme oli tutkia vain kolmatta labyrinttia, joka ratkeaa, sillä että ennen eteenpäin menemistä yritetään kääntyä.

labyrint.PNG