wiki:k2015/demot/demo7
Last modified 21 months ago Last modified on 2016-01-31 02:03:11

Demot » Demo 7, 3.3.2015

Tarkista aina demosivu netistä mahdollisten muutosten varalta.

Demot poikkeuksellisesti tiistaina 3.3. klo 10. Paikkana "Oppimistila", AgD122.1. Dumpin tilan ohi ja oikealle. Vaksit ohjaavat tarvittaessa.

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 27.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)
};

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.)

Tehtävä 2

(Tässä tehtävässä jatketaan tehtävää 1. Voit tehdä tämän samaan kooditiedostoon edellisen tehtävän kanssa.)

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);

(a) Tee Begin-aliohjelmaan 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.

(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)

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

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

Tehtävä 3

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.

Tehtävä 4

(Voit tehdä tämän samaan kooditiedostoon tehtävien 1-3 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.

Tehtävä 5

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

(a) 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.

(b) Tehtäviä 1-4 (ja 5a) 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

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

V1

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

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ä funktioiden toiminnan testasit. Voit antaa samassa tiedostossa palautetta ja kehitysehdotuksia Comtestin käytöstä. Tehtävän "numeroksi" anna TDD1.

Valitettavasti tehtäviä 1-5 on hieman hankala testata automaattisesti (periaatteessa lähintä palloa voisi tutkailla). Tehtävät 6 ja B1 kuitenkin sopivat tähän hyvin.

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.)

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(Demo6.Matriisit.Jonoksi(luvut, " ", "{0,5:0.00}"));
}

tulostaisi

 2.23  3.00  4.00  5.00  0.00  9.00  5.00

Vinkki: Käytä String.Split-funktiota.

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 :-)

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