The referenced paragraph does not exist.

Demo 7

Palauta viimeistään ma klo 11:59.

Osaamistavoitteet

Tämän demokerran päätteeksi

  • osaat jo soveltaa taulukoita, funktioita ja silmukoita paremmin

Ajankäyttösi tällä viikolla

Työtuntien kirjaamisesta saa 0.5 demopistettä.

Demokerran päätteeksi kirjoita arvio tällä viikolla käyttämästäsi työmäärästä. Laske työmäärään mukaan kaikki tällä viikolla käyttämäsi aika: lähiopetukseen osallistuminen, oppimateriaalin lukeminen, demotehtävien tekeminen, luentovideon katsominen, demojen purkutilaisuuteen osallistuminen (maanantaina) ja niin edelleen. Voit päivittää lukua viikon edetessä, se voi helpottaa arvion tekemistä. Huom! Siis tähän ei laiteta kurssin alusta kaikkia tunteja yhteensä, vaan vain tämän viikon tunnit.

# d7tunnit


Huomautus tehtävien pisteytyksistä

PP

PP2-tehtävät (näistä saa pisteitä vain käymällä PP-ryhmässä). Aikataulu Sisussa.

Tehtävä 1*

M: 16. Silmukat. Tee funktio LaskeKirjaimet, joka laskee merkkijonossa olevien annetun kirjaimen esiintymien lukumäärän. Testaa pääohjelmalla (tai ComTestillä), jossa on kutsuja tyyliin (keksi lisää testejä):

int sMaara = LaskeKirjaimet("kissa", 's');
int kMaara = LaskeKirjaimet("kissa", 'k');

Funktion pitää osata ottaa huomioon myös isot kirjaimet. Esimerkiksi merkkijonosta "Ritari" pitää löytyä r-kirjaimia kaksi kappaletta.

Vinkki: Char-merkin muuttaminen pienaakkoseksi onnistuu käyttämällä Char.ToLower()-metodia. Ks. dokumentaatio.

Tehtävässä saa kääntyvän ohjelman ajamisesta 0.3 p., testien läpäisemisestä 0.6 p. (testit on kirjoitettu valmiiksi) ja dokumentaation katsomisesta 0.1 p.

# d3teht6a

Tehtävä 2*

M: 16. Toistorakenteet, 12. Muokattavat merkkijonot

Tee tämä tehtävä Riderissa. Valmis ja toimiva ohjelma palautetaan kuitenkin TIMiin normaalisti.

Tee konsolisovellus ja sinne funktio LuoKolmio, joka palauttaa suorakulmaisen kolmion niin kutsutulla ASCII-grafiikalla. LuoKolmio-funktio ottaa parametreina char-merkin sekä yhden luvun, joka on kolmion leveys ja korkeus. Funktio palauttaa string-olion. Ota pohjaksi tämä pääohjelma:

public static void Main()
{
  string kolmio = LuoKolmio('@', 8);
  Console.WriteLine(kolmio);
}

Sen pitäisi tulostaa tällainen kolmio:

@
@@
@@@
@@@@
@@@@@
@@@@@@
@@@@@@@
@@@@@@@@

Ohje: Merkkijono rakennetaan StringBuilder-olioon. Kunkin rivin päätteeksi lisätään rivinvaihto seuraavasti (tässä sb on StringBuilder-muuttujan nimi):

sb.Append('\n');

Funktio palauttaa lopuksi StringBuilder-olion "tavallisena" merkkijonona sanomalla

return sb.ToString();

Palauta laatikkoon koko ohjelmasi, ei siis pelkkää funktiota.

Vinkki 1, jos ei lähde aukeamaan.

Vinkki 2, jos ei vieläkään aukea (avaa tämä vasta sitten kun olet itse miettinyt).

Arviointi:

  • kääntyvä ohjelma 0.1 p.
  • itse kirjoitetut testit ja testien läpäiseminen 0.3 p.
  • oikea tulostus 0.6 p.

Testaamisesta: Funktio palauttaa merkkijonon, joten odotettu paluuarvo tulee laittaa lainausmerkkien sisään. Korvaa rivinvaihdot merkeillä \n.

Onko testaamisesta ja rivinvaihtohässäkän ( n -merkki) käytöstä jossakin esimerkkiä? Riderissa en nyt jotenkin osaa ajaa testejä...

Tulos on merkkijono joten sen ympärillä pitää olla lainausmerkit. -AJL

28 Feb 23 (edited 28 Feb 23)
# d7t1

Hei, sain tämän IDEssa toimimaan ihan oikein, käytin Rideria vaikka lukeekin että tee visual studiossa. Siitäkö syystä ei nyt toimi TIMissä normaalisti?

Palauta laatikkoon koko ohjelmasi, ei siis pelkkää funktiota. Korjasin myös Visual Studio -> Rider. -AJL

27 Feb 23 (edited 27 Feb 23)

Testit ei mee läpi, mutta tulee silti täydet pisteet. Onkohan tää ok?

Kiitos huomautuksesta. Korjasin automaattipisteytystä ja täydensin tehtävän kuvausta arvioinnin osalta. -AJL

01 Mar 23 (edited 02 Mar 23)

Kolmio tulostuu oikein, mutta ei saa kuin 0,4 pistettä?

Korjasin tarkastinta. Toimisiko se nyt oikein? -AJL

02 Mar 23 (edited 02 Mar 23)

Tarkastin ei taida toimia vielä, sillä minä sain myös 0.4p vaikka ajo ja testit onnistuivat.

Kuviossa ei saa olla ylimääräisiä välilyöntejä. -AJL

02 Mar 23 (edited 03 Mar 23)

Miten tällaista testataan ComTestilla?

Paluuarvo on merkkijono joka laitetaan lainausmerkkien sisään. -AJL

04 Mar 23 (edited 04 Mar 23)

Tehtävä 3

Lue ensin: 17.1. String.Split()

Tee funktio SanojenPituusKeskiarvo. Funktio ottaa parametrina merkkijonon, ja palauttaa sanojen pituuksien keskiarvon. Sanat erotellaan välilyöntien, pisteiden ja pilkkujen kohdalta. Esimerkiksi syötteellä

Kolme miestä istuu saunassa.

funktio palauttaisi 6, sillä sanoja on neljä kappaletta, ja sanojen pituudet ovat 5 + 6 + 5 + 8 = 24.

Vastaavasti syötteellä

Kolme miestä, myös Pertti, istuskeleepi lauteilla.

tulos olisi 7, sillä sanoja on kuusi, ja pituudet ovat 5 + 6 + 4 + 6 + 12 + 9 = 42.

Funktio ei saa tulostaa mitään.

Tässä tehtävässä luokka ja pääohjelma ovat valmiina, mutta pääohjelma on piilotettu, joten et näe pääohjelmaa.

Vinkki 1: Käytä String.Split-metodia (ks. dokumentaatio). Voit antaa Split-metodille useita erotinmerkkejä pilkuilla erotettuna.

Vinkki 2: Split-metodi voi synnyttää taulukkoon tyhjiä alkoita, kuten esimerkiksi yllä olevassa tapauksessa käy. Tyhjiä alkioita ei saa laskea keskiarvoon mukaan.

# pituuksienKa

Tehtävä 4-5 (2 p.)

M: 15. Taulukot, 16. Silmukat.

Seuraava ohjelma luo 20 palloa satunnaisiin paikkoihin ympäri kenttää. Pallot tallennetaan pallot-taulukkoon. Tee Fysiikkapeli ja aja tämä ohjelma Riderissa.

public class Lahinpallo : PhysicsGame
{
    public override void Begin()
    {
        SetWindowSize(800, 600);
        Level.Size = new Vector(800, 600);
        PhysicsObject[] pallot = TeeSatunnaisetPallot(20, 30.0);

        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
    }

    /// <summary>
    /// Tekee palloja satunnaisiin paikkoihin
    /// </summary>
    /// <param name="montako">Montako palloa tehdään</param>
    /// <param name="koko">Pallon koko</param>
    /// <returns>Pallot</returns>
    private PhysicsObject[] TeeSatunnaisetPallot(int montako, double koko)
    {
        PhysicsObject[] pallot = new PhysicsObject[montako];
        for (int i = 0; i < montako; i++)
        {
            PhysicsObject p = new PhysicsObject(koko, koko, Shape.Circle);
            pallot[i] = p;
            p.Position = RandomGen.NextVector(Level.BoundingRect);
            Add(p);
        }
        return pallot;
    }
}

Tee Begin:iin vielä yksi fysiikkaolio-pallo haluamaasi paikkaan, vaikkapa kohtaan x=100, y=100.

Anna pallolle väriksi sininen, jotta se erottuu muista palloista.

Sen jälkeen tee funktio

public PhysicsObject LahinPallo(PhysicsObject[] pallot, Vector piste)
{
 // täydennä ...
}

joka etsii ja palauttaa annettua pistettä lähimmän pallon, siis PhysicsObject-olion.

Seuraavaksi, kutsu Begin:ssä LahinPallo-funktiota siten että annat argumentteina pallot-taulukon, ja juuri äsken tekemäsi sinisen pallon paikan (sininenPallo.Position).

Saat paluuarvona lähimmän pallon olioviitteen. Värjää lähin pallo punaiseksi. Funktiota voidaan käyttää seuraavasti. (Laita tämä Begin:iin.)

PhysicsObject lahinPallo = LahinPallo(pallot, sininenPallo.Position);
lahinPallo.Color = Color.Red;

Kun olet saanut tehtävän valmiiksi, niin aseta itsellesi 2 pistettä Set Custom Points -toiminnolla.

Vinkkejä: Demossa 6 etsittiin kokonaislukutaulukon lähintä lukua miidi-tehtävässä. Sen idea sopii täysin, nyt vaan pitää palauttaa lähin fysiikkaolio. Demo 6:ssa alkion tyyppinä oli int, nyt PhysicsObject. Etäisyyden voit helpoiten laskea Jypelin Vector-luokasta löytyvällä Vector.Distance-funktiolla tai käyttämällä samaa ideaa kuin demo 6:n tehtävässä 6, jossa laskettiin kahden pisteen etäisyys toisistaan. Muista, että fysiikkaolion paikan saat fysiikkaolion Position-ominaisuuden avulla.

# d7teht4

Tehtävä 6

Tässä tehtävässä voit hyödyntää tekemiäsi tehtäviä 4-5.

  1. Lisää peliin pieni sininen pallo. Tee aliohjelma, joka siirtää pienen sinisen pallon siihen kohtaan, mihin klikkasit hiirellä. Hiiren paikan ruudulla saat tätä ohjetta käyttäen.

  2. Jatka tehtävää niin että lähimmän pallon kohdalle ilmestyy punainen pallo. Sama toistuu kun hiirellä klikataan uudestaan jonnekin muualle, niin sinisen kuin punaisen pallon paikka päivittyy.

Katso video

Ohje tehtävän tekemiseen:

Tee hiiren vasemman painikkeen kuuntelijaksi delegaatti, jossa hoidetaan sekä pallon siirtely että lähimmän pallon päivittäminen.

Mouse.Listen(MouseButton.Left, ButtonState.Pressed, delegate ()
{
   // Siirrä sinistä palloa
   // Päivitä lähin pallo
}, "");

Selitys: Delegaatti on nimetön aliohjelma, jota tässä kutsutaan hiiren napin painamisen yhteydessä. Delegaatilla on käytössään kaikki paikalliset muuttujat, joten tämä kuuntelija tulee tehdä samaan aliohjelmaan sinisen pallon kanssa (Beginiin).

# d7teht5

V1

Tee Ville-tehtävät: 5.9 - 5.13 sekä 9.8.

Muista: Villen käyttöohje.

Palauta tehtävä kirjoittamalla alla olevaan tekstilaatikkoon mitä opit ja mitä mieltä olit tämän kerran Ville-tehtävistä ja auttoivatko Ville-tehtävät sinua yhtään. Muutama rivi riittää.

# VilleV1

TDD1

Jos tarkistat vähintään kahden funktion toiminnan automaattisella testillä (ComTest), saat merkitä yhden lisäpisteen. Kirjoita alle olevaan vastauslaatikkoon minkä tehtävän ja minkä funktion/funktioiden toiminnan testasit. Voit antaa samalla vastauksen kautta palautetta ja kehitysehdotuksia Comtestin käytöstä.

Valitettavasti tehtäviä 1-5 on hieman hankala testata automaattisesti (periaatteessa lähintä palloa voisi tutkailla). Tehtävät 6 ja B2 kuitenkin sopivat tähän hyvin. B1 soveltuu myös, mutta on hieman hankalampi testata (2-ulotteisen taulukon testaaminen).

# demo7tdd

B1

Tee konsoliohjelma, joka tulostaa ASCII-grafiikka-"puun" (ASCII-grafiikalla tarkoitetaan kirjoitusmerkeillä tuotettua "taidetta"). Puun alaosassa on yhden merkin korkuinen ja kolme merkkiä leveä jalka/runko, jonka päällä kolmio siten, että alin "kerros" on N merkkiä (N=pariton), seuraava N-2, sitten N-4 jne, jolloin ylimpään kerrokseen jää yksi merkki. Alla esimerkki tulostuksesta.

Voit joko (a) pääohjelmassa pyytää käyttäjää syöttämään puun leveys (eli kolmion alimman rivin merkkien lukumäärä), merkki jolla kolmio täytetään, sekä merkki jolla jalka täytetään, tai (b) käyttää seuraavaa valmista pääohjelmaa:

public static void Main()
{
  string puu = LuoPuu(9, '@', '|');
  Console.WriteLine(puu);
}

Ohjelman tuloste näyttäisi tällöin seuraavanlaiselta:

    @
   @@@
  @@@@@
 @@@@@@@
@@@@@@@@@
   |||

Vinkki: StringBuilder.Append-metodille voit antaa toisena parametrina toistojen määrän.

Vinkki: Puun kolmion osan rakentamisessa kannattaa lähteä seuraavasta ajatuksesta.

  1. Lisää aluksi sopiva määrä välilyöntejä. Tähän voit käyttää StringBuilder-olion Append-metodia.
  2. Sitten lisää sopiva määrä puun merkkejä. Tähänkin voit käyttää Append-metodia.

Kaksinkertaista for-silmukkaa ei tarvitse välttämättä tehdä tässä tehtävässä. Hyödynnä parametrina saamaasi leveys-muuttujaa ja silmukan i-muuttujaa.

Vinkki: Yhden merkin voit lukea käyttäjältä näin:

char merkki = Console.ReadKey().KeyChar;
# d7kuusi

B2-3 (2 p.)

Lisää B1 tehtävän puuhun satunnaisia koristeita sinne tänne. Aseta pisteesi Set Custom Points -toiminnolla.

Miten levea puu > 15
Mistä puu on tehty > $
Mistä jalka on tehty > /
       o
      $$$
     $o$o$
    $o$$o$o
   o$$$o$$$o
  o$$$o$$$$oo
 $$o$$o$$$$$$$
$$$$$$$$$$$$$$$
      ///

Vinkki: Kannattaa ehkä tehdä apufunktio kolmion yksittäisen rivin rakentamiseen, jossa arvotaan minkä verran koristeita riviin tulee. Palautuksena String jonka sitten liität StringBuilder-olioon pääohjelmassa.

# d8tehtb3

Tässä ei varmaan haittaa se, että ohjelma ei käänny käyttäjältä kysyttävien syötteiden takia? Voin toki kommentoida ne pois ja vain kutsua Mainissa funktiota suoraan asettamillani arvoilla. Testatakaan en osaa string-muuttujia + random-elementtiä, mutta kyselenpä ohjauksessa sitten :)

Ei haittaa vaikka ohjelma ei TIMissä käänny. Satunnaisuutta on kieltämättä hankala testata. -AJL

02 Mar 23 (edited 03 Mar 23)

B4

M: 15.5 Moniulotteiset taulukot, 16. Silmukat. Tee funktio, joka summaa yhteen kaksi matriisia vastinalkioittain. Funktio siis joutuu ensin luomaan oikeankokoisen tulosmatriisin. Mitä on syytä olettaa parametrimatriiseilta? Dokumentoi kommentteihin oletuksesi. Sitten funktio laskee tulosmatriisiin komponenteittain summan. Esimerkiksi:

public static void Main(String[] args) 
{
  double[,] mat1 = {{1,2,3}, {2,2,2}, {4,2,3}};
  double[,] mat2 = {{9,2,8}, {1,2,5}, {3,19,-3}};
  double[,] mat3 = Summaa(mat1, mat2);
  Console.WriteLine(Demo6.Matriisit.Jonoksi(mat3, " ", "{0,5:0.00}"));
}

tulostaisi

10.00  4.00 11.00
 3.00  4.00  7.00
 7.00 21.00  0.00

Demo 6 malliratkaisuissa on valmis funktio matriisin muuttamisesta merkkijonoksi, mutta toki voit tehdä itsekin oman tulostusaliohjelman.

Ajamisesta saa 0.2 pistettä, oikeasta tulosteesta 0.6 ja dokumentaation generoinnista 0.2 pistettä.

# d7b1

G1

M: 15.5 Moniulotteiset taulukot. Nyt GameOfLife on säännöillä b3s23 (born 3, stay 2 ja 3) eli synnytään 3:lla naapurilla ja pysytään 2:lla tai 3:lla naapurilla. Muuta SeuraavaSukupolvi-aliohjelma sellaiseksi, että sille voidaan viedä jonkinlaisena taulukkona säännöt ja silmukoiden sisään ei tule enää yhtään if-lausetta (Huom! myös ?-lause on if-lause, samoin switch :-)

# d7g1

G2

Tee pieni (tasohyppely tms.) peli, jossa on

  • liikuteltava pelaaja, jolla voi "ampua" jotain, ja joilla voi osua vihollisiin
  • vihollisia/seiniä/esteitä tai jotain, jolla on elämäpisteitä eli eivät häviä yhdestä. Vinkki: perintä.
  • olioilla on tekstuurit

Huom! Et voi ajaa TIMissä peliäsi, koska pelin ulkopuolisia tiedostoja (tekstuurit, ym.) ei voi viedä TIMiin. Saat pisteet pelin ajamisesta, mutta TIM tulee valittamaan sinulle puuttuvista tiedostoista.

Ajamisesta saa 0.8 pistettä ja dokumentaation generoinnista 0.2 pistettä.

# d7g2

These are the current permissions for this document; please modify if needed. You can always modify these permissions from the manage page.