Kesän 2011 Ohjelmoinnin jatkokurssi muodostuu kolmesta tehtäväsarjasta, joissa jokaisessa on 16 tehtävää:
Perustehtävät (11 kpl) ovat suoraviivaisia tehtäviä kurssin tärkeimmistä asioista. Perustehtävät kannattaa tehdä aina kokonaan.
Lisätehtävät (4 kpl) ovat syventäviä tehtäviä, joissa kurssin asioita sovelletaan uudenlaisissa tilanteissa.
Pähkinä (1 kpl) on haastava tehtävä, jonka ratkaiseminen vaatii miettimistä ja oivaltamista.
Tehtävät palautetaan esittelemällä niitä ohjaajalle ohjelmointipajassa. Osan 3 tehtävien viimeinen palautuspäivä on tiistai 21.6., mutta tehtäviä voi mielellään palauttaa aiemminkin.
Tee tätä tehtäväsarjaa varten NetBeans-projekti
KoodaritJaPomot
.
Lue materiaalista luku 7 ja tee seuraavat tehtävät:
Tee rajapinta Tyontekija
, joka vaatii toteuttamaan metodin
laskeAlaiset
. Metodin tarkoituksena on palauttaa työntekijän
alaisten määrä yrityksessä.
Tee lisäksi luokka Koodari
, joka toteuttaa rajapinnan
Tyontekija
. Luokan sisältönä on koodarin nimi. Koodarin alaisten
määrä on aina nolla.
Seuraava pääohjelma testaa luokkaa:
public class Main { public static void main(String[] args) { Tyontekija aapeli = new Koodari("Aapeli"); System.out.println(aapeli.laskeAlaiset()); } }
Ohjelman tulostuksen tulisi olla seuraava:
0
Tee luokka Pomo
, joka toteuttaa rajapinnan
Tyontekija
. Lisää luokkaan myös metodi lisaaAlainen
,
joka lisää pomolle uuden alaisen. Tallenna alaiset
ArrayList
-rakenteeseen, joka sisältää
Tyontekija
-rajapinnan toteuttavia olioita.
Seuraava pääohjelma testaa luokkia:
public class Main { public static void main(String[] args) { Pomo petteri = new Pomo("Petteri"); petteri.lisaaAlainen(new Koodari("Aapeli")); petteri.lisaaAlainen(new Koodari("Maija")); petteri.lisaaAlainen(new Koodari("Uolevi")); System.out.println(petteri.laskeAlaiset()); } }
Ohjelman tulostuksen tulisi olla seuraava:
3
Vihje: Toteuta pomon alaisten laskeminen niin, että summaan lisätään pomon
alaisten määrä sekä silmukassa kunkin alaisen alaisten määrä. Voit luottaa
siihen, että jokaisella alaisella on metodi laskeAlaiset
.
Tee ohjelma, joka määrittelee seuraavan työntekijähierarkian:
Lisää ohjelmaan rivi, joka tulostaa Kaisan alaisten määrän, ja varmista, että tulokseksi tulee 7.
Tee tätä tehtäväsarjaa varten NetBeans-projekti
Vertailtavuus
.
DNA-ketju on merkkijono, joka muodostuu merkeistä A, C, G ja T. Esimerkiksi merkkijono ACTAGGCAT on DNA-ketju.
Tee luokka DNAKetju
, jonka sisältönä on DNA-ketju. Tee
luokalle konstuktori ja metodi toString
. Lisää konstruktoriin
tarkistus, että annettu merkkijono on kelvollinen DNA-ketju eli siinä on vain
merkkejä A, C, G ja T. Jos merkkijono ei ole kelvollinen, luokan sisällöksi
tulee pelkkä merkkijono X.
Seuraava pääohjelma testaa luokkaa:
public class Main { public static void main(String[] args) { DNAKetju testi = new DNAKetju("ACTAGGCAT"); System.out.println(testi); DNAKetju huono = new DNAKetju("AAPELI"); System.out.println(huono); } }
Ohjelman tulostuksen tulisi olla seuraava:
ACTAGGCAT X
Lisää DNAKetju
-luokkaan metodi compareTo
ja
ilmoita, että se toteuttaa rajapinnan Comparable
.
Toteuta vertailu siten, että ensisijainen vertailutapa on ketjun pituus ja
toissijainen vertailutapa on aakkosjärjestys.
Seuraava pääohjelma testaa luokkaa:
import java.util.*; public class Main { public static void main(String[] args) { ArrayList<DNAKetju> lista = new ArrayList<DNAKetju>(); lista.add(new DNAKetju("TAAC")); lista.add(new DNAKetju("AACACA")); lista.add(new DNAKetju("CTAG")); lista.add(new DNAKetju("CTTACTTTA")); Collections.sort(lista); System.out.println(lista); } }
Ohjelman tulostuksen tulisi olla seuraava:
[CTAG, TAAC, AACACA, CTTACTTTA]
Tee luokka Lukujoukko
, jonka sisältönä on joukko lukuja. Lisää
luokkaan metodi lisaaLuku
, joka lisää luvun joukkoon, jos sitä ei
ole siinä valmiiksi. Lisää myös metodi toString
, joka muodostaa
merkkijonoesityksen tallennetuista luvuista.
Seuraava pääohjelma testaa luokkaa:
public class Main { public static void main(String[] args) { Lukujoukko luvut = new Lukujoukko(); luvut.lisaaLuku(4); luvut.lisaaLuku(7); luvut.lisaaLuku(2); luvut.lisaaLuku(4); luvut.lisaaLuku(5); System.out.println(luvut); } }
Ohjelman tulostuksen tulisi olla seuraava:
[2, 4, 5, 7]
Huomaa, että luku 4 esiintyy joukossa vain kerran, vaikka se yritettiin laittaa sinne kahdesti.
Lisää luokkaan Lukujoukko
metodi lukujenMaara
,
joka palauttaa joukossa olevien lukujen määrän. Lisää sitten metodi
compareTo
ja ilmoita, että luokka toteuttaa rajapinnan
Comparable
. Järjestyksen ratkaisee joukon lukujen määrä.
Seuraava pääohjelma testaa luokan toimintaa:
import java.util.*; public class Main { public static void main(String[] args) { ArrayList<Lukujoukko> lista = new ArrayList<Lukujoukko>(); Lukujoukko eka = new Lukujoukko(); eka.lisaaLuku(1); eka.lisaaLuku(2); Lukujoukko toka = new Lukujoukko(); toka.lisaaLuku(3); toka.lisaaLuku(4); toka.lisaaLuku(5); Lukujoukko kolmas = new Lukujoukko(); kolmas.lisaaLuku(6); lista.add(eka); lista.add(toka); lista.add(kolmas); Collections.sort(lista); System.out.println(lista); } }
Ohjelman tulostuksen tulisi olla seuraava:
[[6], [1, 2], [3, 4, 5]]
Tee tätä tehtäväsarjaa varten NetBeans-projekti
Tuotevarasto
.
Lue materiaalista luku 8 ja tee seuraavat tehtävät:
Tee luokka Varasto
, jonka sisältönä on tuotteen määrä
varastossa. Lisää luokkaan metodit lisaaTuote
ja
poistaTuote
. Tee metodi poistaTuote
niin, että
tuotteen määrä ei voi mennä negatiiviseksi. Lisää myös luokkaan metodi
toString
, joka toimii esimerkin mukaisesti.
Seuraava pääohjelma testaa luokkaa:
public class Main { public static void main(String[] args) { Varasto omenat = new Varasto(); System.out.println(omenat); omenat.lisaaTuote(); omenat.lisaaTuote(); System.out.println(omenat); omenat.poistaTuote(); System.out.println(omenat); omenat.poistaTuote(); System.out.println(omenat); omenat.poistaTuote(); System.out.println(omenat); } }
Ohjelman tulostuksen tulisi olla seuraava:
0 kpl 2 kpl 1 kpl 0 kpl 0 kpl
Tee luokka Historia
, jonka tarkoituksena on pitää kirjaa
tuotteen määrästä varastossa eri ajanhetkinä. Seuraavassa tehtävässä luokka
kytketään luokkaan Varasto
, mutta toistaiseksi se on erillinen
luokka. Lisää luokkaan metodi lisaaMerkinta
sekä metodi
toString
.
Seuraava pääohjelma testaa luokkaa:
public class Main { public static void main(String[] args) { Historia maarat = new Historia(); maarat.lisaaMerkinta(5); maarat.lisaaMerkinta(7); System.out.println(maarat); maarat.lisaaMerkinta(4); System.out.println(maarat); } }
Ohjelman tulostuksen tulisi olla seuraava:
[5, 7] [5, 7, 4]
Tee luokka MuistavaVarasto
, joka perii luokan
Varasto
. Lisää luokan osaksi Historia
-olio ja tee
konstruktoreista sekä metodeista lisaaTuote
ja
poistaTuote
uudet versiot, jotka merkitsevät muistiin varaston
tilanteen. Tee myös uusi metodi haeHistoria
, joka palauttaa
muutoshistorian.
Seuraava pääohjelma testaa luokkaa:
public class Main { public static void main(String[] args) { MuistavaVarasto omenat = new MuistavaVarasto(); omenat.lisaaTuote(); omenat.lisaaTuote(); omenat.poistaTuote(); omenat.lisaaTuote(); omenat.lisaaTuote(); omenat.poistaTuote(); omenat.poistaTuote(); omenat.lisaaTuote(); omenat.lisaaTuote(); omenat.lisaaTuote(); omenat.poistaTuote(); System.out.println(omenat.haeHistoria()); } }
Ohjelman tulostuksen tulisi olla seuraava:
[0, 1, 2, 1, 2, 3, 2, 1, 2, 3, 4, 3]
Tee vielä luokkaan MuistavaVarasto
metodi
piirraTilasto
, joka piirtää pylväsdiagrammin varaston
muutoshistoriasta.
Seuraava pääohjelma testaa luokkaa:
public class Main { public static void main(String[] args) { MuistavaVarasto omenat = new MuistavaVarasto(); omenat.lisaaTuote(); omenat.lisaaTuote(); omenat.poistaTuote(); omenat.lisaaTuote(); omenat.lisaaTuote(); omenat.poistaTuote(); omenat.poistaTuote(); omenat.lisaaTuote(); omenat.lisaaTuote(); omenat.lisaaTuote(); omenat.poistaTuote(); omenat.piirraTilasto(); } }
Ohjelman tulostuksen tulisi olla seuraava:
# # ### # ### #### ###########
Lisätehtävät alkavat tästä:
Tee tätä ja seuraavaa tehtäväsarjaa varten NetBeans-projekti
Viisitoista
.
15-pelissä 4x4-ruudukko sisältää kokonaisluvut 1–15 ja yhden tyhjän ruudun. Tavoitteena on saada luvut seuraavaan järjestykseen:
1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 |
13 | 14 | 15 |
Jokaisella siirrolla voi siirtää tyhjän ruudun vieressä (vaakasuunnassa tai pystysuunnassa) olevan luvun tyhjään ruutuun. Mitä vähemmän siirtoja lukujen järjestämiseen tarvitsee, sen parempi.
Seuraava sivu selventää, miten pelin kuuluisi toimia:
Kaksiulotteinen taulukko on hyödyllinen tässä tehtäväsarjassa.
Tee luokka Viisitoista
, joka toteuttaa 15-pelin peruslogiikan.
Luokan sisältönä on 15-pelin tilanne, ja konstruktori lisää luvut järjestykseen
ruudukkoon. Luokassa on myös metodit, joilla voi siirtää tyhjää ruutua sekä
hakea tietyssä ruudussa olevan luvun.
Lue materiaalista luku 9 ja tee seuraavat tehtävät:
Tee luokka Kayttoliittyma
, joka toteuttaa 15-pelille graafisen
käyttöliittymän. Pelin toiminnallisuus on edelleen luokassa
Viisitoista
. Tässä vaiheessa riittää, että graafinen
käyttöliittymä pystyy piirtämään 15-pelin tilanteen hakemalla ruuduissa
olevat luvut luokasta Viisitoista
.
Peli voisi näyttää tässä vaiheessa seuraavalta:
Lisää peliin näppäimistönkäsittely, jotta pelaaja voi siirtää ruudukossa
olevia lukuja. Lisää luokkaan Viisitoista
myös metodi, jolla
ruudukon sisällön voi sekoittaa, ja anna pelaajalle mahdollisuus tähän.
Huom! Mikä tahansa satunnainen 15-pelin tilanne ei ole ratkaistavissa. Keksi keino, jolla sekoittaja tuottaa aina ratkaistavan tilanteen.
Lisää peliin laskuri, joka pitää kirjaa siirtojen määrästä. Pelin pitäisi myös tunnistaa, kun pelaaja saa luvut järjestykseen. Voit myös tarjota pelaajalle mahdollisuuden aloittaa pelin tietystä tilanteesta ja lisätä peliin muita ominaisuuksia haluamasi mukaan.
Tee ohjelma, joka ratkaisee annetun 15-pelin aloitustilanteen.
Ohjelman toiminnan tulisi näyttää tältä:
Anna aloitustilanne: 1 2 3 4 5 6 0 8 9 10 7 12 13 14 11 15 Ratkaisu (3 siirtoa): 1 2 3 4 5 6 8 9 10 7 12 13 14 11 15 1 2 3 4 5 6 7 8 9 10 12 13 14 11 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Voit suunnitella ohjelman toiminnan itse tai tutustua aihetta käsittelevään kirjallisuuteen (15-peli on englanniksi 15 puzzle). Lyhimmän 15-pelin ratkaisevan siirtosarjan voi etsiä IDA*-algoritmilla sopivan heuristiikan avulla.
Tee tätä tehtäväsarjaa varten NetBeans-projekti
ItsensaTulostaja
.
Seuraava ohjelma tulostaa toisen ohjelman koodin:
public class Tulostaja { public static void main(String[] args) { System.out.println("public class Tervehtija {"); System.out.println(" public static void main(String[] args) {"); System.out.println(" System.out.println(\"Heipparallaa!\");"); System.out.println(" }"); System.out.println("}"); } }
Ohjelman tulostus on seuraava:
public class Tervehtija { public static void main(String[] args) { System.out.println("Heipparallaa!"); } }
Tee ohjelma, joka tulostaa oman koodinsa (eli ohjelman koodi ja tulostus ovat samat).
Huom! Ohjelman ei ole tarkoitus lukea koodia tiedostosta. Myöskään mitkään Java-kielen erikoisominaisuudet eivät ole tarpeen.