wiki:s2011/demot/demo8
Last modified 6 years ago Last modified on 2011-11-01 18:19:07

Demot » Demo 8, 31.10.2011

Demojen palauttaminen

Demot palautetaan viimeistään maanantaina klo 13:00 mennessä. Kirjaudu ensin Korppiin ja sitten kurssin NettiDemoWWW:hen https://www.mit.jyu.fi/demowww/ohj1/. Voit palauttaa osan tai kaikki tehtäväsi etukäteenkin ja täydentää vastauksia määräaikaan mennessä. Jos sinulla on samassa .cs-tiedostossa usean tehtävän vastaus, niin voit laittaa tehtävän kohdalle esim. 3-4, tai voit palauttaa saman tiedoston useammalla eri rivillä.

V1

Tee Ville-tehtävät: 6.5, 9.7 + kaksi sellaista joita et ole aiemmin ymmärtänyt kunnolla (jos kaikki ymmärretty, ei tätä ylim kahta tarvitse tehdä). Mitä 9.7:ssa on väärin C#:ia ajatellen? Muista: Villen käyttöohje ja Ville-tehtävien palauttamisohjeet.

TDD1

Jos tarkistat vähintään kahden funktion toiminnan automaattisella testillä (ComTest), saat merkitä yhden lisäpisteen. Palauta DemoWWW:ssä tekstitiedosto TDD.txt (jonka siis arvostelet yhden pisteen arvoiseksi), missä kerrot minkä tehtävän ja minkä funktion/funktioiden toiminnan testasit. Voit antaa samassa tiedostossa palautetta ja kehitysehdotuksia Comtestin käytöstä. Mikäli ComTest ei toimi yliopiston mikroluokissa, tarkista että ComTest haetaan oikeasta paikasta: Valitse Visual Studiossa Tools -> ComTest -> Options. Esiin tulee ComTest Plugin Options. Tarkista, että Path to ComTest.jar executable kentässä on N:\bin\ComTest.jar ja ole yhdistänyt koneesi N-verkkolevyyn.

Listojen luominen testejä varten onnistuu esim. luomalla ensin taulukko ja sen avulla muodostamalla lista:

///   Vector[] t = { new Vector(1,2),new Vector(3,4),
///                  new Vector(5,2),new Vector(5,5) };
///   List<Vector> luvut = new List<Vector>(t);
tai
///   List<Vector> luvut = new List<Vector>{ 
//                   new Vector(1,2),new Vector(3,4),
///                  new Vector(5,2),new Vector(5,5) };

Pohjatiedostot varsinaisille tehtäville

Ota Jypelistä uusin versio.

Ota Demo 7:n ohjeilla (TortoiseSVN-ohje) pohjatiedostot Demo 7:stä. Sitten ota Demo 7 mallivastauksista ohjeen mukaan tarvittavat tiedostot ja tee ajamiseksi tarvittavat muutokset. Tee muutokset mainitussa järjestyksessä projekti kerrallaan. Eli kokeilet toiminnan aina kun kunkin projektin muutokset on tehty.

  • AngryLego: Laita AngryLego StartUp projektiksi
    • avaa AngryLego.cs.
    • ota mallivastauksen AngryLego.cs
    • kopioi sisältö projektissa olevan tilalle
    • lisää Content-sisältöön AngryLegoContent puuttuvat äänet ja kuvat (paina Contentin päällä hiiren oikeaa ja Add/Existing? Item ja ota ja valitse kaikki AngryLegoContent hakemiston kuvat ja äänet, paitsi maila2.png jos se vielä on).
    • kokeile ajaa ohjelmaa
  • Taulukot: Laita Taulukot StartUp-projektiksi
    • Avaa Taulukot.cs-tiedosto
    • ota mallivastauksen Taulukot.cs
    • kopioi sisältö projektissa olevan tilalle
    • lisää vielä aluksi tyhjä pääohjelma Taulukot-luokan sisälle
      public static void Main(string[] args)
      {
      }
      
    • kokeile että projekti kääntyy (tyhjällä pääohjelmalla se ei tulosta mitään)
  • Kuvaaja: Laita Kuvaaja StartUp projektiksi
    • avaa Kuvaaja.cs
    • ota Kuvaaja.cs
    • kopioi sisältö projektissa olevan tilalle
    • lisää projektin viitteeksi Taulukot-projekti (Kuvaaja-projektin References päällä hiiren oikeaa ja "Add Reference" ja sitten Projects ja Taulukot.)
    • kokeile että toimii

Tehtävä 1

M: 13. Ehtolauseet. Tee funktio Karkausvuosi(int vuosi), joka palauttaa tosi jos vuosi on karkausvuosi. Karkausvuosia ovat neljällä jaolliset vuodet, mutta ei täydet vuosisadat paitsi neljällä jaolliset vuosisadat (esim. 1900 ei ollut karkausvuosi, 1900 on 19. vuosisata ja 19 ei ole jaollinen neljällä, mutta 20 on ja siksi 2000 on karkausvuosi). Mieti kunnon testiohjelma / ComTest-testit.

Tehtävä 2

M: 13. Ehtolauseet, 13.8 13.8 switch-rakenne, 16. Toistorakenteet, 15. Taulukot. Kirjoita 3 erilaista funktiota Vuodenaika(int kuukausi), joka palauttaa merkkijonona sen vuodenajan, joka parametrina vietynä kuukautena on. Yksi käyttää käyttää if-lausetta, toinen switch-lausetta ja kolmas taulukkoa.

Tehtävä 3

Refaktorointi. Aluksi AngryLegossa oli laskurinäyttöjen luominen muodossa:

private void LuoPistenaytto()
{
    pisteet.MinValue = -500;
    pisteNaytto.IntFormatString = "Points: {0:00000}";
    pisteNaytto.Position = new Vector(Screen.Right - pisteNaytto.Width/2-20, 
                                      Screen.Top - pisteNaytto.Height/2);
    pisteNaytto.BindTo(pisteet);
    pisteNaytto.Color = Color.Yellow;
    pisteNaytto.BorderColor = Color.Black;
    pisteNaytto.PreferredSize = new Vector(150,pisteNaytto.Height);
    Add(pisteNaytto);

    tasoNaytto.IntFormatString = "Level: {0:0}";
    tasoNaytto.BindTo(tasoNr);
    tasoNaytto.Position = new Vector(Screen.Right - pisteNaytto.Width/2-20, 
                Screen.Top - pisteNaytto.Height / 2 - pisteNaytto.Height);
    tasoNaytto.Color = Color.Yellow;
    tasoNaytto.BorderColor = Color.Black;
    tasoNaytto.PreferredSize = new Vector(150,pisteNaytto.Height);
    Add(tasoNaytto);

    vihollisNaytto.IntFormatString = "Enemy: {0:00}";
    vihollisNaytto.BindTo(vihollisia);
    vihollisNaytto.Position = new Vector(Screen.Right-pisteNaytto.Width/2-20, 
                Screen.Top - pisteNaytto.Height / 2 - 2*pisteNaytto.Height);
    vihollisNaytto.Color = Color.Yellow;
    vihollisNaytto.BorderColor = Color.Black;
    vihollisNaytto.PreferredSize = new Vector(150,pisteNaytto.Height);
    Add(vihollisNaytto);
}

Tässä hyvin samanlaiset koodinosat toistuvat. Tällöin kannattaa katsoa mikä samanlaisista osista on erilaista ja miten voisi aliohjelmalle viedä parametrina erilaiset osat ja tehdä samanlaista aliohjelma. Muutosten jälkeen esimerkkikoodi voisi olla:

private void LuoNaytot()
{
    pisteet.MinValue = -500;
    pisteNaytto = LuoNaytto("Points: {0:00000}",pisteet,0);
    LuoNaytto("Level: {0:0}",tasoNr,1);
    LuoNaytto("Enemy: {0:00}", vihollisia, 2);
}

private Label LuoNaytto(string format, IntMeter mittari, int n)
{
    Label naytto = new Label(format);
    naytto.Width = 150;
    naytto.PreferredSize = new Vector(150, naytto.Height);
    naytto.SizeMode = TextSizeMode.None;
    naytto.Position = new Vector(Screen.Right - naytto.Width / 2 - 20, 
                      Screen.Top - naytto.Height / 2 - n * naytto.Height);
    naytto.IntFormatString = format;
    naytto.BindTo(mittari);
    naytto.Color = Color.Yellow;
    naytto.BorderColor = Color.Black;
    Add(naytto);
    return naytto;
}

Vastaavasti tuhoavien pallojen luonnissa on nyt koodi:

private PhysicsObject LuoPallo()
{
    PhysicsObject pallo = new PhysicsObject(tileWidth, tileWidth, 
                                            Shape.Circle);
    pallo.Image = pallonKuva;
    Add(pallo);
    pallo.Tag = "pallo";
    pallo.Destroyed += delegate { Savuta(pallo, false, 1.0); };
    pallot.Add(pallo);
    AddCollisionHandler(pallo, "rakenne", PalloOsuiRakenteeseen);
    return pallo;
}


private PhysicsObject LuoPallo2()
{
    PhysicsObject pallo = new PhysicsObject(tileWidth * 0.6, tileWidth, 
                                            Shape.Circle);
    pallo.Image = pallonKuva2;
    Add(pallo);
    pallo.Tag = "pallo2";
    pallo.Destroyed += delegate { Liekita(pallo, false, 2.0); };
    pallot.Add(pallo);
    AddCollisionHandler(pallo, "rakenne", Pallo2OsuiRakenteeseen);
    return pallo;
}

Näissäkin on paljon yhteistä. Osan yhteisen osan tyypit eivät vielä ole tuttuja, mutta tekemällä uusi delegaatti saadaan toisen pallon luonti muotoon:

public delegate void Tehoste(PhysicsObject obj,bool paine,double kerroin);

private PhysicsObject LuoPallo()
{
   return LuoTuhoPallo("pallo", pallonKuva, 1.0,1.0,
                       Savuta, PalloOsuiRakenteeseen);
}

Missä

private PhysicsObject LuoTuhoPallo(string tag, Image kuva, double sx, 
   double kerroin, Tehoste tehoste, NewCollisionHandler tormays)
{
    PhysicsObject pallo = new PhysicsObject(tileWidth * sx, tileWidth, 
                                                        Shape.Circle);
    pallo.Image = kuva;
    Add(pallo);
    pallo.Tag = tag;
    pallo.Destroyed += delegate { tehoste(pallo, false, kerroin); };
    pallot.Add(pallo);
    AddCollisionHandler(pallo, "rakenne", tormays);
    return pallo;
}

Kirjoita LuoPallo2 -metodi myös yhdellä rivillä käyttäen mallina tuota LuoPallo-metodia. Tarkista että ohjelma edelleen toimii samalla tavalla.

Tehtävä 4

Refaktorointi. Kuten edellisessä tehtävässä, myös rakenteiden luonnissa on toistoa (tässä ei tarvitse mitään delegaatteja tms "hankalaa"):

private PhysicsObject LuoSeina()
{
    SarkyvaRakenne seina = new SarkyvaRakenne(tileWidth, tileHeight);
    seina.Tag = "rakenne";
    seina.Kuvat = tiilenKuvat;
    return seina;
}


private PhysicsObject LuoKatto()
{
    SarkyvaRakenne katto = new SarkyvaRakenne(tileWidth * 1.5, tileHeight);
    katto.Tag = "rakenne";
    katto.Kuvat = katonKuvat;
    return katto;
}

Tee metodi LuoSarkyvaRakenne sopivilla parametreilla niin, että saat vaihdettua sekä LuoSeina että LuoKatto -metodit yhden rivin metodeiksi.

Tehtävä 5

M: 22.2 Listat Vaihda taulukko listaksi. Eli Kuvaaja.cs:ssä vaihda

private Vector[] pisteet;

tilalle

private List<Vector> pisteet;

ja tee kaikki muut tarvittavat muutokset jotta ohjelma toimii täsmälleen kuten aikaisemminkin.

Tehtävä 6

M: 22.2 Listat Muuta Kuvaaja.cs:ää siten, että se alkaa tyhjällä koordinaatistolla ja aluksi kysytään käyttäjältä merkkijono, jossa olisi tarkoitus olla vuoden kuukausien keskilämpötiloja. Merkkijonosta pilkotaan demo 7:n vastauksella reaalilukutaulukko. Sitten piirretään kuva (lisätään palloja kuvaan), siten että lukua vastaavat x-koordinaatit ovat 10,20,30 jne. Eli jos käyttäjä antaa merkkijonon

-10 -12 5 7 14 18

niin piirretään vastaavasti pallukat paikkoihin

(10,-10)
(20,-12)
(30,5)
(40,7)
(50,14)
(60,18)

pallukoiden värit ovat niin, että yli 12 olevat pisteet ovat punaisella ja alle 0:n olevat pisteet sinisellä. Muut mustalla.

Aluksi muuta alueen rajat:

        private const double x1 = -1;
        private const double x2 = 70;
        private const double y1 = -15;
        private const double y2 = 25;

sitten poista pääohjelmasta:

        pisteet = ArvoPisteet(20, x1, y1, x2, y2);
        LuoPisteet(this, pisteet, pallonKoko);

ja lisää pääohjelman (Begin) loppuun

 KysyKoordinaatti();

Muuta sopivasti metodin KysyKoordinaatti kysymystekstiä. Sitten muuta metodi KoordinaattiAnnettu muotoon:

        private void KoordinaattiAnnettu(InputWindow ikkuna)
        {
            string vastaus = ikkuna.InputBox.Text;
            double x = 10;
            double[] d = Demo7.Taulukot.ErotaLuvut(vastaus);
            pisteet = new List<Vector>();
            foreach (double luku in d)
            {
                pisteet.Add(new Vector(x,luku));
                x += 10;
            }
            LuoPisteet(this, pisteet, 0.3,0.0,12.0);
            kysymassa = false;
        }

Varsinaiseksi tehtäväksi jää tehdä tuo aliohjelma

 public static void LuoPisteet(PhysicsGame game, ??? pisteet, 
                              double r, double ala,double yla)

jossa ala ja yla ovat rajat sille, mitä piirretään milläkin värillä.

B1

Muuta AngryLego-peliä niin, että putoava pää huutaa mennessään ja Symbian soittelee pudotessaan kännykän ääniä. Äänet saavat kuulua pitempäänkin, mutta tekemällä niistä noin 1-2 sekuntia pitkiä, ne eivät soi turhan kauaa. Pohjahakemistossa on valmiita ääniä jos et itse halua tehdä ääniä.

B2

Muuta Kuvaaja.cs:ssä olevaa Axis-luokkaa niin, että se piirtää 4 pikkuviivaa (=jakaa viiteen osaan) jokaisen isomman välin sekä x-akselilla että y-akselilla.

B3

M: 15. Taulukot, 16. Toistorakenteet. Tee funktioaliohjelma Moodi(luvut), joka etsii taulukon yleisimmän luvun. Jos eniten esiintyviä on yhtä monta, niin silloin ensimmäisenä näistä lukujoukoista tulkitaan yleisimmäksi. Ennen ohjelmointia, mieti ensin kuinka itse ratkaisit tämän ongelman (eli mieti algoritmi). Et tarvitse aputaulukkoja välttämättä, vaan tehtävän voi ratkaista muutamalla apumuuttujalla. Moodi on yksi keskiluvuista. Toinen on keskiarvo - tee sitäkin varten funktioaliohjelma. Kolmas keskiluvuista on mediaani, eli aineiston keskimmäinen alkio. Tätä ei vielä tarvitse tehdä. Mitä mediaanin laskemiseksi pitäisi ensin tehdä? Katso vaikka Wikipediasta keskiluku.

G1-2

Muuta AngryLego-peliä niin, että lego-vauvat hyppivät muutaman pikselin verran levottomina ylös/alas. Vinkki: tee vihollisista oma luokka ja tee sen Update-metodiin tarvittavat muutokset.