Palautus lähestyi uhkaavasti. Jäljellä oleva aika laskettiin päivien sijaan minuuteissa. Viilasin, tallensin, kommitoin, loggasin, uppasin, jarrasin, mailasin ja tutisin: sadan tunnin työpanos lävähti palautuslootaan kuin tukkupakkaus kryptoniittia. Aika kului, vastausta ei kuulunut. Kohtalaisella laskupäällä aika palautukseen oli jo sekunteja. Sitten poksahti: huikaiseva viiden megan paketti ei ollut mahtunut TKK:n suppiloista. Huutelin paniikissa irkkiin, ja nohevasti tilanteen tasalla ollut assari (yksi kappale) pelasti iltani kiertäen moiset rajoitukset.

Ja niin se tapahtui. Projekti oli ohi.

Pidin esittelykierroksen sille arvottuna aikana ja Marko ja Suni antoivat pelistä mukavaa palautetta. Ainoa konkreettinen jäljellä oleva suorite on projektin loppuraportti, josta on tällä hetkellä reipas puolikas jäljellä. Vääntämään siis, ettei tule kiire.

PS. Tekoälystä sen verran, että ihan minimaxia siitä ei tullut. Kaikkien mahdollisten toimintojen tulokset läpikäyvästä maxiversiostakin tuli niin riipaisevan raskas isommissa kartoissa, ettei enemmässä monimutkaistamisessa juuri olisi järkeä. Se on hyvä näin.

Käyttöliittymä on hiomaton, mutta se toimii. Käynnistysruudussa on ohjeteksti ja pelaajien ja kentän valinta, pelin päätyttyä taas kerrotaan lyhyellä tekstillä kumpi voitti ja tarjotaan uusi peli -nappia. Periaatteessa koodi voisi olla nyt valmis, mutta tekoälyn raakileisuus häiritsee. Aion tänään katsoa josko voisin parissa tunnissa saada aikaan tekoälyn, joka edes yrittää – algoritmitavoitteena minimax. Seuraavaksi siirryn javadocien täydentämiseen ja toivon että ehdin saada valmista ennen tiistaita, jolloin viimeistään on pakko aloittaa loppuraportin tekeminen.

Tältä peli näyttää versiossa 121Tältä peli näyttää versiossa 121. Yksiköiden liikuttelussa on päheä hehkutusefekti, mutta se pitää nähdä livenä.

Peli on toimintakunnossa ja näyttääkin jonkinlaiselta, mutta käyttöliittymä siltä puuttuu. Lähden siis pulttaamaan jonkinlaista valitse pelaajat, valitse kartta -alkuvalikkoa ja pelinpäättymisilmoitusta. Sen jälkeen voisin hyvällä omallatunnolla julistaa projektin päättyneeksi, mutta itseni tietäen keksin varmaan kaikenlaista näperrettävää viime metreille asti. Pitää muistaa jättää aikaa loppuraportille.

Koin viime yönä valaistumisen ja ymmärsin, miten toteutan pelaajan interaktion pelin kanssa. Tähän asti olen pyöritellyt graafisia efektejä jotka toimivat yhdessä hiiren kanssa (yksikön vetäminen paikasta toiseen), mutta peliin tällä ei ole ollut mitään vaikutusta.

Pelimoottori pyörittää looppia, jossa pelin esitys renderöidään ruudulle. Lisätään siis jokaiseen pyöritykseen pelilogiikkapäivitys, jonka suorittaa itse peli. Pelin sisällä on pelikierroksia ja pelikierrosten sisällä pelivuoroja. Peli pitää huolta siitä, että kierroksia jatketaan niin kauan kuin päättymisehto ei ole täyttynyt ja käynnistää uuden kierroksen aina kun vanha on ohi. Kierros huolehtii siitä, että jokainen pelaaja saa oman vuoronsa ja vaihtaa seuraavaan pelaajaan kun nykyinen on valmis. Pelivuoron tehtävä on kysellä pelaajalta, josko sillä olisi antaa uusi komento toteutettavaksi. Kuulostaa simppeliltä, ja niin se onkin.

Varsinainen valaistuminen oli siinä, että jokainen taso – peli, kierros ja vuoro – laukoo omanlaisiaan tapahtumia. Taistelin nimittäin viimeiset pari päivää sen kanssa, kuinka saan tiedon kulloisistakin olennaisuuksista kuten vuorossa olevasta pelaajasta kiinnostuneille tahoille. Tässä siis vastaus. Käyttöliittymän puolella toimiva kuuntelija, jonka on tarkoitus muodostaa pelaajan häröilyistä pelissä suoritettavia komentoja, saa tiedon pelaajaoliosta ja voi siten kertoa sille, että seuraavalla kerralla kun kysytään kerrot sitten suorittavasi tämänlaisen komennon.

Puuh, se helpotti. Nyt voi taas puskea koodia kun on suunta tiedossa.

Studio Wars, revisio 58

Studio Wars, revisio 58

Sitten vain visualisointi kuntoon ja homma on puoliksi pulkassa.

Äärimmäisen tarkan ja tieteellisen projektiaikakirjanpitoni mukaan nyt on käynnissä projektin tunti numero 25. Luku on hieman suurempi kuin mitä odotin. Tätä varten on vietetty ainakin ympäristöni mielestä aivan liian suuri osa joulusta koneen ääressä ja vieläkin suurempi osa projektia muuten vain vatvoessa. Mutta mitä olen saanut aikaiseksi?

Ennen joulua viimeistelin pelimekaniikan suunnittelun. Lyhyt kuvaus (pidemmän jaksan ehkä kirjoittaa myöhemmin): Jokaisella yksiköllä on vaikutuskenttä, joka ulottuu yksiköstä ulospäin alan ja voimakkuuden riippuessa yksikön tasosta. Pelikentällä olevien yksiköiden vaikutukset summataan joukkueittain yhteen, ja saadaan joukkueiden kokonaisvaikutukset. Tämä näkyy pelissä eri värisinä ruutuina. Eri joukkueiden vaikutukset kumoavat toisiaan, ja jos yksikön kohdalla oleva vaikutuskenttä muuttuu eri joukkueen dominoimaksi, yksikkö joutuu pois pelistä. Tarkoitus on poistaa pelistä kaikki vastajoukkueen yksiköt.

Pelin idean selvittyä sen toteuttaminen helpottui tietysti oleellisesti. Tunnit ovat toistaiseksi uponneet pelimaailman rakenteiden ja kenttien käsittelyyn vaadittaviin toteutuksiin. Itse pelimekaniikka kuitenkin loistaa poissaolollaan – tuudittauduin jo taannoin siihen uskoon, että tarvittavien asioiden esiinloihtiminen helpottuu, kun käsillä on jonkinlainen visuaalinen esitys pelimaailmasta.

Piirtely Javalla ja erilaisten Swing-komponenttien koostaminen oikeasti toimiviksi kokonaisuuksiksi on valitettavasti se osuus, jota pidän kaikkein vaikeimpana koko touhussa. Olen googletellut pitkiä päiviä saadakseni tähän jotain oleellista helpotusta tai valaistumista, mutta tuloksetta. Seuraavaksi ei auta kuin kohdata peto silmästä silmään ja koodata se solmuun.

Ah, kun sentään hyvältä / kunnon koodi maistuu.

Iltaa kohden ryhdistyin ja rupesin takomaan näppäimistöä. Ei siitä mitään mestariteosta vielä tullut, mutta ajatuksia sinkoili sinne tänne ja sain pari interfacenraatoa ihan hyvälle mietintäasteelle.

Pari testiäkin kirjoitin. Käänsin vanhan harkoista tutun Ilmansuunta-luokan, jota tiesin tarvitsevani, projektissa noudattamaani englanninkieliseen formaattiin ja loin samalla testit. Huomasin, että JUnit on oikein mukava hamcrestin kanssa tarjoiltuna. Tässä esimerkkiä:

    @Test
    public void movingInAllDirectionsShouldLeadToOrigin()
    {
        Point p = new Point();
        for (Direction d : Direction.values()) {
            p.translate(d.getDX(), d.getDY());
        }
        assertThat(p, is(new Point()));
    }

Ah, niin itsestäänselvän näköistä.

Loin SVN-repon. Avasin Eclipsen. Loin projektin. Lisäsin Guicen ja JUnitin kirjastoihin.

Hakkasin päätä pöytään. Ajatus ei vain lentänyt. Silmiin sattui.

Kipeänä koodaaminen on ankeaa. Yritän motivoida itseäni Googlen opetusmateriaalilla, mutta saanenko tänäänkään mitään tehdyksi.

Graah.