Demo 7

Palauta viimeistään ma 29.2. klo 11:59, läpikäynti ma 29.2. klo 12-14.

Tällä kertaa tehtävät 1-5 tehdään käytännössä yhteen. Eli aloita ykkösestä ja etene vitoseen. Tehtävän nro 6 (ja bonukset ym.) voit toki tehdä sitten erillään näistä.

Oppimistavoitteet

Tämän demokerran päätteeksi

  • osaat jo soveltaa taulukoita, funktioita ja silmukoita paremmin

PP, perjantai 26.2.

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

Tehtävä 1

M: 15. Taulukot. Tee uusi Jypeli-peli (Fysiikkapeli), ja kopioi Begin-aliohjelmaan alla oleva koodi.

PhysicsObject[] pallot = new PhysicsObject[] {
  LuoPallo(10, 0, 0, Color.White), 
  LuoPallo(10, 20, 20, Color.White),
  LuoPallo(10, 40, 40, Color.White), 
  LuoPallo(10, 60, 60, Color.White),
  LuoPallo(10, 80, 80, Color.White)
};

Huom: Yllä tehtävänannossa annettu mallikoodi tarkoittaa samaa kuin tässä alla. Siinä luodaan pallot-niminen PhysicsObject-taulukko, johon sijoitean LuoPallo-funktion palauttamia PhysicsObjecteja.

PhysicsObject[] pallot = new PhysicsObject[5];
pallot[0] = LuoPallo(10, 0, 0, Color.White);
pallot[1] = LuoPallo(10, 20, 20, Color.White);
pallot[2] = LuoPallo(10, 40, 40, Color.White);
pallot[3] = LuoPallo(10, 60, 60, Color.White);
pallot[4] = LuoPallo(10, 80, 80, Color.White);

Toteuta funktio LuoPallo, joka luo ja palauttaa pallo-fysiikkaolion. Tee funktiossa myös pallon lisäys pelikentälle Add-lauseella. Parametreina säde ja paikka sekä väri -- siis yhteensä neljä parametria. Huomaa, että LuoPallo ei ole static-funktio tässä tapauksessa (koska emme vie tietoa pelistä, johon pallot lisätään -- toisin sanoen, funktio ei voi toimia pelkästään parametreina saatujen tietojen avulla vaan se tarvitsee tiedon pelioliosta, johon pallot lisätään.)

Toteuta funktio LuoPallo, joka luo ja palauttaa pallo-fysiikkaolion. Tee LuoPallo-funktiossa myös pallon lisäys pelikentälle Add-lauseella. Kyseisen funktion parametreina ovat säde ja paikka sekä väri -- siis yhteensä neljä parametria. Huomaa, että LuoPallo ei ole static-funktio tässä tapauksessa (koska emme vie tietoa pelistä, johon pallot lisätään -- toisin sanoen, funktio ei voi toimia pelkästään parametreina saatujen tietojen avulla vaan se tarvitsee tiedon pelioliosta, johon pallot lisätään.)

VINKKI: Funktion pitää siis palauttaa PhysicsObject-tyyppinen olio. Tällöin funktion toteutuksesta täytyy löytyä return-lause, jonka perässä palautetaan PhysicsObject-tyyppinen arvo, esimerkiksi pallo :-).

# d7teht1

EI TOIMI! Kahden ohjaajan mukaan koodissa ei ole mitään vikaa, mutta kun ajaa, niin tulee tällaista: Unhandled Exception: System.ArgumentOutOfRangeException: must be greater then zero Parameter name: maxLength

24 Feb 16

Toimiipas! Luotko kenties pallon antamalla PhysicObjectille paikkakoordinaatin parametrina. Muuallahan siellä ei nollia ole. Sille annetaan leveys, korkeus ja muoto parametrina. Eli ei PhysicsObject pallo = new PhysicObject(x, y, Shape Circle)

24 Feb 16

Tehtävä 2

(Tässä tehtävässä jatketaan tehtävää 1.)

a) Tee Begin-aliohjelmaan, ekan tehtävän koodin perään, silmukka, jolla laitat pallot-taulukossa olevat pallot satunnaisesti ympäri kenttää. Huom! Et saa olettaa, että taulukossa on viisi palloa, eli koodisi pitää toimia muunkin kokoiselle taulukolle.

Vinkki: Koska pallot ovat taulukossa, voimme ottaa taulukon paikassa i olevan pallon apumuuttujaan pallo. Koordinaattien arpominen taulukon paikassa i olevalle pallolle tapahtuu seuraavasti.

PhysicsObject pallo = pallot[i];
pallo.X = RandomGen.NextDouble(Level.Left, Level.Right);
pallo.Y = RandomGen.NextDouble(Level.Bottom, Level.Top);
# d7teht2a

b) Tee aliohjelma SekoitaPaikat, jolle annetaan viisi parametria:

  1. PhysicsObject-taulukko, joka sisältää siirrettävät fysiikkaoliot
  2. x-koordinaatin minimi (double)
  3. y-koordinaatin minimi (double)
  4. x-koordinaatin maksimi (double)
  5. y-koordinaatin maksimi (double)

(Valinnainen: Voit tehdä kohdat 2-3 sekä 4-5 myös vektoreina, jolloin 3 parametria riittää.)

Ota nyt pallot sekoittava silmukka pois Begin:stä ja sen sijaan laita Begin:iin SekoitaPaikat-aliohjelmakutsu. Sekoita nyt tehtävässä 1 tekemäsi pallotaulukko ja katso että joka kerta pallot tulevat eri paikkaan.

# d7teht2

Tehtävä 3

(Tässä tehtävässä jatketaan tehtävää 2.)

Tee funktio TeeSatunnaisetPallot, jolle annat parametrina luvun, kuinka monta palloa arvotaan. Tähän perustuen funktio luo taulukollisen palloja satunnaisesti ympäri pelikenttää, ja palauttaa tuon taulukon, eli paluuarvon tyyppi on PhysicsObject[]. Käytä funktioita, joita teit tehtävissä 1-2.

LISÄOHJE / VINKKI

Eli lopputulemana sinulla pitäisi olla idealtaan seuraava koodi

Begin-aliohjelma
{
  PhysicsObject[] pallot = TeeSatunnaisetPallot(10); // tämä funktiokutsu 
                                                     // palauttaisi 10 pituisen
                                                     // taulukon
} 

TeeSatunnaisetPallot-funktio
{
  1. Tee Pallot silmukassa hyödyntäen LuoPallo-funktiota
  2. Sekoita pallot käyttämällä SekoitaPaikat-aliohjelmaa
}

LuoPallo-funktio
{
  tehty tehtävässä 1
}

SekoitaPaikat-aliohjelma
{
  tehty tehtävässä 2
}
# d7teht3

Tehtävä 4

(Tässä tehtävässä jatketaan tehtäviä 1-3. Voit tehdä tämän samaan kooditiedostoon edellisten tehtävien kanssa.)

M: 15. Taulukot, 16. Silmukat.

Tee funktio

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

joka etsii ja palauttaa annettua pistettä lähimmän taulukon alkion PhysicsObject-taulukosta.

Tee ensin fysiikkaolio-taulukko jossa on palloja taulukossa kuten tehtävässä 1, eli ei satunnaisesti ympäri kenttää vaan "kiinteästi" paikassa (0, 0), (20, 20), jne. (Laita tämä Begin:iin.)

PhysicsObject[] pallot = ... // Palloja tehtävän 1 mukaisesti

Sitten luodaan yksi vektori. (Laita tämä Begin:iin.)

Vector piste = new Vector(0, 50);

Sitten molemmat parametrina LahinPallo-funktiolle ja palautuksena tulee sen lähimmän pallon olioviite. Funktiota voidaan käyttää seuraavasti. (Laita tämä Begin:iin.)

PhysicsObject lahinPallo = LahinPallo(pallot, piste);

Katso debuggerin avulla, mikä on lähimmän pallon sijainti. Huomaa, että tehtävässä oletetaan pallojen olevan samankokoisia.

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 laskea joko Demo 6 Etaisyys-funktiolla tai jopa helpommin Jypelin Vector-luokasta löytyvällä funktiolla kahden vektorin (=pisteen) välisen etäisyyden laskemiseksi (etsi dokumentaatiosta ko. funktio). Muista, että fysiikkaolion paikan saat fysiikkaolion Position-ominaisuuden avulla.

# d7teht4

Tehtävä 5

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

  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. Tehtäviä 1-4 (ja 5 a) hyväksi käyttäen tee Jypeli-peli, missä arvotaan ruudulle 15 kappaletta palloja. Kun hiirellä klikkaa ruudulle, ilmestyy siihen kohtaan sininen pallo. Samalla 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

# d7teht5

Timi ei osaa lukea Window.Widthiä eikä sen Heightiä :(

26 Feb 16

Selvitellään, mutta voi olla että tälle kurssille tuo ominaisuus ei TIM-Jypeliin ehdi :-( /AJL

27 Feb 16

Tehtävä 6

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');
# d3teht6a

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

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

Demo6.Matriisit.Jonoksi -käyttö ei ole pakollista, voit tehdä itsekin oman tulostusaliohjelman.)

# d7b1

B2

M: 17. Merkkijonojen pilkkominen ja muokkaaminen Merkkijonojen pilkkominen: Tee funktio ErotaLuvut(String jono), jonka ansiosta seuraava pääohjelma

public static void Main(String[] args) 
{
    double[] luvut = ErotaLuvut("2.23 3 4 5 k      9 ;5");
    Console.WriteLine(String.Join(" ", luvut));
}

tulostaisi

 2.23  3  4  5  0  9  5

k == 0 ???
Eikö tarkoituksena ole löytää merkkijonosta pelkät luvut?

25 Feb 16

VL: on, mutta tässä tehtävässä "vääriin" kohtiin tulee oletus 0. ELi joku "palanen" ei muutu numeroksi, sen tilalle laitetaan 0.

27 Feb 16 (edited 27 Feb 16)

Vinkki: Käytä String.Split-funktiota ja Taulukot.cs:ssä olevaa ErotaDouble-funktiota yksittäisen merkkijonon muuttamisessa reaaliluvuksi. Kopioi tämä aliohjelma (sisältöineen) mukaan koodiin. ErotaDouble toimii vaikka jonoksi annetaan vääränlaisiakin syötteitä ja sille voi valita mitä tällöin palautetaan. Ks. ErotaDouble funktion ComTestit.

# d7b2

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 vihuihin
  • vihuja/seiniä/esteitä tai jotain, jolla on elämäpisteitä eli eivät häviä yhdestä. Vinkki: perintä.
  • olioilla tekstuurit

Huom! Et voi ajaa TIMissä peliäsi, koska pelin ulkopuolisia tiedostoja (tekstuurit, ym.) ei voi vielä TIMiin. Saat pisteet pelin ajamisesta, mutta TIM tulee valittamaan sinulle puuttuvista tiedostoista Microsoft.Xna.Framework.Content.ContentLoadException poikkeuksien muodossa.

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.