Ohjelmointi 2 -- kesä 2006 -- Demo 4/11

Demonumero:4/11
Palautus:tiistaina 30.5.2006 klo 18 mennessä.
Laskennallinen tehtävämäärä:
 9 kpl.
Pisteitä saa korkeintaan:
 11 kpl.

(esim. 12 tehtyä kohtaa -> 11 pistettä Korppiin)

Aletaan pikkuhiljaa vaatia kaikilta lähdekoodeilta (demot ja harkka) suositusten mukaista asemointia! Tällä kertaa on mm. tehtäviä, joiden avulla voi harjoitella asiaa ja kerätä samalla pisteitä.

Muistanette, että kurssilla saa käyttää apuohjelmistoa, joka löytyy osoitteesta http://www.mit.jyu.fi/vesal/kurssit/ohj2/ali/ -- sivulla on myös ohjeet. Lisäksi saa käyttää kaikkea, mitä löytää Javan API-dokumentaatiosta (kuitenkin, jos homma näyttää hoituvan tyyliin yhdellä rivillä, olisi kohtuullista esittää vaihtoehtoinen ratkaisu, jossa käytetään "vähemmän edistyneitä" metodeja). Jos tehtävässä kysytään algoritmia, ei saisi oikeastaan olettaa alustasta mitään.

1-2:

(Java-kielen syntaksin ymmärtäminen ja selkeä koodi)

Kesäope sai tehtäväksi kirjoittaa ohjelman, joka tulostaa kokonaisluvut ykkösestä neloseen. Tällaisen se sai aikaan:

public class Sotkettu{public static int A (int 
a,int b) {return  (a>=b)?a:b;}  public  static 
void main(String[]A){{int a,b,c,d; a=1; b=2*a;  
c=b; c +=a; d = A(b,a)*c; if (a<b)  if  (b>a)d 
=((c-1)==A(a,b))?d:a;else d--;d--;--d;;;;;{};;
System.out.println(a  +  ", " + b + ", " + c + 
", " + d);}}}  ///mitä suotta sisentelemään///

Saiko ope aikaan tehtävänantoa vastaavan ohjelman? Entäpä järkevän? Tehtäviä:

  • Kopioi koodi omaan työkaluusi, sisennä rivit rakenteen mukaisesti ja laita välilyönnit oikeisiin (eli ymmärrettävyyden kannalta parhaisiin) paikkoihin. Jaa ainakin jokainen sijoituslause omalle rivilleen.
  • Laita joka rivin perään kommentti, jossa selität, mitä siinä oleva Java-koodi tekee. (Ehdoton perusasia! En ihmettele, jos välikokeessa olisi jotain vastaavaa)
3:

(Koodauskäytännöt - Java Code Conventions)

Tutustu Sunin suositukseen Java-lähdekoodin muodosta: Code Conventions. Muokkaa tehtävän 1-2 koodi vastaamaan mahdollisimman paljon suositusta. (Jätä koko toiminnallisuus silti ennalleen). Mm. nimeä metodi A ja pääohjelman parametri A merkitystensä mukaisesti. Poista lisäksi koodista ne merkit {, } ja ;, joita ei tarvita, ja korjaa sisennys vastaavasti.

4:

(Javadoc ja dokumentointi)

Tutustu javadoc - kommenttien standardimuotoon. Ks. esim Code Conventions -dokumentin esimerkkikoodit tai Sunin Javadoc-kirjoitusohjeet. Kirjoita edellisten tehtävien ohjelmalle kattavat, oikeaoppiset javadoc-kommentit, joissa käytät kenttiä @author, @version ja metodin kommentissa @param, @return

Ja tästedes kaikkiin ohjelmakooditehtäviin onkin tultava javadoc -kommentit... Koodien tulee olla suosituskäytäntöjen mukaan kirjoitettuja. ja ainakin tekijän nimi/nimet javadoc-tyyppisesti.

5:

(Päivän pöytätesti; lisää sotkua)

Tutki pöytätestin avulla mitä ovat muuttujien arvot seuraavassa ohjelmassa kunkin lauseen suorittamisen jälkeen. Mitä ohjelma tulostaa?

/**
 * Mitä ohjelma tulostaa?? 
 * @author  Vesa Lappalainen
 * @version 1.0, 19.01.2003
 */
public class Alisotk2 {

  private static int i(StringBuffer s) {
    return Integer.parseInt(s.toString());
  }
  private static void set(StringBuffer s,int i) {
    s.delete(0, s.length()).append(""+i);
  }

/* 01 */ private static StringBuffer b; private static int c;
/* 02 */
/* 03 */ private static void s_1(StringBuffer a, int b)
/* 04 */ {
/* 05 */   int d;
/* 06 */   d  = i(a);
/* 07 */   c  = b + 3;
/* 08 */   b  = d - 1;
/* 09 */   set(a,c - 5);
/* 10 */ }
/* 11 */
/* 12 */ private static void a_2(int a, StringBuffer b)
/* 13 */ {
/* 14 */   c  = a + i(b);
/* 15 */   { int c; c = i(b);
/* 16 */   a = 8 * c; }
/* 17 */   set(b,175);
/* 18 */ }
/* 19 */
/* 20 */ public static void main(String[] args) {
/* 21 */   StringBuffer a = new StringBuffer("4"); int d=9;
/* 22 */   System.out.println("" + a + " " + b + " " + c + " " + d);
/* 23 */   b=new StringBuffer("3"); c=2; d=1;
/* 24 */   s_1(b,c);
/* 25 */   a_2(d,a);
/* 26 */   s_1(a,3+d);
/* 27 */   System.out.println("" + a + " " + b + " " + c + " " + d);
/* 28 */ }
}

Ohjeita: Ryhmittele pöytätestissä eri paikoissa (luokka, metodit, lohkot, keko) elävät muuttujat eri supersarakkeisiin. Tähti * sarakkeessa merkkaa viitemuuttujaa ja & merkkaa viitemuuttujan arvoa eli osoituskohdetta. Suorituksen alku on annettu seuraavassa:

+----------+--------+-------+------------+-----------+-------+
|          | luokan | main  | s_1        | a_2       | keko  | 
+----------+----+---+---+---+---+----+---+---+---+---+---+---+
|          | *  |   |*  |   |*  |    |   |   |*  |   |   |   |
|   lause  |  b | c | a | d | a |  b | d | a | b | c |N1 |N2 |
+----------+----+---+---+---+---+----+---+---+---+---+---+---+
|  /*01*/  |null| 0 | - | - | - | -  | - | - | - | - | - | - |
|  /*21*/  |    |   |&N1| - | - | -  | 9 | - | - | - | 4 | - |
...
6-7:

(Luokat ja oliot)

Kirjoita luokka Henkilo, jossa on sukunimi, etunimi ja syntymävuosi. Kirjoita metodi kysy, joka kysyy henkilön tiedot. Kirjoita metodi tulosta, joka tulostaa henkilön tiedot (ks. monisteen luku 9.2). Kirjoita myös testipääohjelma.

8-9:

(Harjoitustyön vaihe 3)

Toteuta omalle harjoitustyöllesi käyttöliittymäluokka, jossa on vähintään päävalikko sekä metodiesittely jokaisen alavalikon/toiminnallisuuden toteuttamista varten (jotka toistaiseksi tulostavat sen "ei toimi vielä").

Muista tärkein: Sinun pitää itse ymmärtää joka ikinen koodissasi oleva rivi kaikkine sanoineen ja merkkeineen - mikä minkäkin asian merkitys ohjelman toiminnalle on.

Malliharjoitustyön vaihetta 3 kannattaa vilkuilla; netistä (http://www.mit.jyu.fi/~vesal/kurssit/ohj2/kerho/) tai mikroluokissa levyltä (n:\kurssit\ohj2\kerho).

G1-4:

Tässä on ollut aiemmin joku tylsä merkkijonojuttu, mutta tällä kertaa tehdään peli. Mulla itsellä meni tähän pari tuntia liian kauan, joten taidan julkaista jotain vinkkejä pohjille.

Eli: Toteuta klassinen peli "Connect four" ("fyra-i-rad", "neljä rivissä"). Jotta opitaan samalla vähän "laajennettavuutta", tee pelistä yleispätevä niin, ettei ole rajoitettu pelikentän kokoa eikä pelaajamäärää.

Pelin alkuperäinen idea on seuraava: On läpinäkyvä lokerikko, jossa on seitsemän saraketta, joihin jokaiseen mahtuu päällekkäin korkeintaan kuusi nappulaa. Aluksi lokerikko on tyhjä. Kaksi pelaajaa pudottaa vuorollaan nappulansa aina johonkin lokeroon. Silloin se putoaa aina siinä lokerossa aiemmin olleiden nappuloiden päälle. Se voittaa, jolla ensimmäisenä on neljä omaa nappulaa rivissä joko vaakasuoraan, pystysuoraan, tai vinosti.

Peliä voi pelailla ainakin seuraavissa paikoissa netissä (ja varmaan miljoonassa muussakin:)

(Jossain on todennäköisesti valmis toteutus Javalla, mutta sitä ei saa käyttää...)

Tässä on mun version käyttöliittymä, tekstipohjainen niinkuin meidän kurssilla tuppaa olemaan... Lokerikon sisältö näytetään aina jokaisen pudotuksen jälkeen:

|0  |1  |2  |3  |4  |5  |6  |
+---+---+---+---+---+---+---|
|   |   |   |   |   |   |   |
|   |   |   |   |   |   |   |
|   |   |   |   |   |   |   |
|   |   |   |   |   |   |   |
|   |   |   |   |   |   |   |
|   |   |   |   |   |   |   |
+---+---+---+---+---+---+---|
(Vastaa -1 lopettaaksesi kesken.)  Mihin sarakkeeseen pudottaa pelaaja 1 (*) >4


|0  |1  |2  |3  |4  |5  |6  |
+---+---+---+---+---+---+---|
|   |   |   |   |   |   |   |
|   |   |   |   |   |   |   |
|   |   |   |   |   |   |   |
|   |   |   |   |   |   |   |
|   |   |   |   |   |   |   |
|   |   |   |   | * |   |   |
+---+---+---+---+---+---+---|           
(Vastaa -1 lopettaaksesi kesken.)  Mihin sarakkeeseen pudottaa pelaaja 2 (O) >4


|0  |1  |2  |3  |4  |5  |6  |
+---+---+---+---+---+---+---|
|   |   |   |   |   |   |   |
|   |   |   |   |   |   |   |
|   |   |   |   |   |   |   |
|   |   |   |   |   |   |   |
|   |   |   |   | O |   |   |
|   |   |   |   | * |   |   |
+---+---+---+---+---+---+---+
(Vastaa -1 lopettaaksesi kesken.)  Mihin sarakkeeseen pudottaa pelaaja 1 (*) >3


|0  |1  |2  |3  |4  |5  |6  |
+---+---+---+---+---+---+---|
|   |   |   |   |   |   |   |
|   |   |   |   |   |   |   |
|   |   |   |   |   |   |   |
|   |   |   |   |   |   |   |
|   |   |   |   | O |   |   |
|   |   |   | * | * |   |   |
+---+---+---+---+---+---+---|
(Vastaa -1 lopettaaksesi kesken.)  Mihin sarakkeeseen pudottaa pelaaja 2 (O) >

Ja niin se peli jatkuu, kunnes päättyy:

|0  |1  |2  |3  |4  |5  |6  |
+---+---+---+---+---+---+---|
|   |   |   |   |   |   |   |
| * |   |   |   |   |   |   |
| O | * | O | * |   |   |   |
| O | * | O | O | * |   |   |
| * | O | * | * | O |   |   |
| O | * | O | * | * |   | O |
+---+---+---+---+---+---+---|
(Vastaa -1 lopettaaksesi kesken.)  Mihin sarakkeeseen pudottaa pelaaja 2 (O) >1


|0  |1  |2  |3  |4  |5  |6  |
+---+---+---+---+---+---+---|
|   |   |   |   |   |   |   |
| * | O |   |   |   |   |   |
| O | * | O | * |   |   |   |
| O | * | O | O | * |   |   |
| * | O | * | * | O |   |   |
| O | * | O | * | * |   | O |
+---+---+---+---+---+---+---|
Pelaaja 2 voitti. ONNEKSI OLKOON!

(Eli tossa pelaaja kakkonen sai noita 0 -nappuloitaan neljä riviin vinottain)

Nyt halutaan sellainen ohjelma, että pelissä voi olla eri määrä sarakkeita ja rivejä ja että voittoehdon voi määrätä olemaan mikä tahansa määrä nappuloita rivissä. Eli vaikkapa noin:

|0  |1  |2  |3  |
+---+---+---+---|
|   |   |   |   |
|   |   | O |   |
| O | * | * | * |
+---+---+---+---|
Pelaaja 1 voitti. ONNEKSI OLKOON!

Vihjeitä:

Tää on jo sen verran monipuolinen ohjelma, että jopa järkeviäkin toteutustapoja on kovin paljon. Kerronpa tässä mitä ominaisuuksia minun versioon päätyi. Pakko ei ole noudattaa näitä, ja varsinkin paremmin saa aina tehdä:

  • Mulla on luokka Pelialue, jonka konstruktorille annetaan rivien ja sarakkeiden määrä sekä tieto siitä, montako nappulaa pitää olla peräkkäin, että voittaa. Konstruktori tekee oliolle privaatin taulukon (int[][]), joka on sopivan kokoinen.
  • Taulukossa on kokonaislukuja: 0=ei nappulaa, 1=ykköspelaajan nappula, 2=kakkospelaajan ...
  • Itse peli on mulla on eri luokassa, vaikka näin pienessä ohjelmassa ehkä toimisi myös Pelialue -luokan main-metodi...
  • Pelipääohjelma luo yhden Pelialue-luokan olion, jota se käyttää.
  • Pelialueessa on metodi pudota(int sarake, int pelaaja)
  • pudota() palauttaa true, jos pudotus onnistui, ja false, jos yritetty sarake on jo täynnä. Pääohjelma tarkistaa onnistuiko pudotus.
  • pudota() kutsuu apumetodia tarkistaVoittaja(int rivi, int sarake), joka tutkii taulukosta, että jatkuuko annetusta koordinaatista alkaen riittävästi saman pelaajan nappuloita johonkin suuntaan niin että kyseinen pelaaja voittaa.
  • Pääohjelma tarkistaa aina pudotuksen jälkeen pelialueen getVoittaja() -metodin avulla, että onko peli päättynyt. Siellä on sitten speksaistu että 0 = peli jatkuu vielä, -1 = jokainen lokero on tullut täyteen, eli tuli tasapeli, 1 = ykköspelaaja voitti, 2 = kakkospelaaja voitti, 3 = kolmospelaaja voitti (perusversiossa on vain kaksi pelaajaa, mutta mikään tuossa ohjelmassa ei estäisi laajentamasta moninpelimahdollisuutta...)
  • Malliohjelmaan tuli noin 150 riviä (ennen kuin siinä on kunnon kommentit). Vähemmällä pärjää varmasti eikä enemmän ole mahdottomuus.
  • Malliohjelma ei kovin pahasti kaatuile, mutta ei myöskään sisällä kaikkia mahdollisia (käyttäjän)järkevyystarkistuksia.

Ei ku tekemään, jos hotsittaa, ja kysykää, jos on kysyttävää. Mitä tuon tekemällä voi oppia: Ainakin tulee harjoiteltua taulukoiden ja silmukoiden käyttöä, ja eiköhän tuossa joudu muutaman kerran tavalla tai toisella etsimään piilottelevia virheitäkin. Ohjelmointiäksiisiä siis.

Kunhan ehdin tarkastamaan näitä demoja, ja jäätte ehkä pistotarkastuksessa valokeilaan... niin tästä ropisee pisteitä pois, jos saan ohjelman kaatumaan jollain tavoin tai jos se ei toteuta joltain osin fyra-i-rad'in varsin simppeleitä sääntöjä. Pisteet saa takaisin, jos löytää mun malliohjelmasta vähintään yhtä monta vastaavaa virhettä. (Täydellistä ei tee koskaan kukaan, koska sellainen ei tule valmiiksi deadlineen mennessä.)