C# ohjelmointi

Alkupuhe

Nykypäivänä tietokone on jokaisen ihmisen pakolline työväline työstä tai harrastuksesta huolimatta, ja tietokoneella jokaisen on osattava käyttää ohjelmia että voi tehdä mitään. Vaikka moni ihminen osaakin käyttää tietokoneita ja ohjelmia, he eivät tiedä yhtään mitä ohjelmat tekevät ja miten ne toimivat. Koska tietokone on jokaisen pakollinen työkalu nykypäivänä, ohjelmoinnin osaamisesta on hyötyä kaikille sillä se auttaa ymmärtämään mihin kaikkeen ohjelmat pystyvät, ja miten ne oikeasti toimivat.

Pelejä ei voi tehdä ilman ohjelmoinnin taitoja, mutta ennen kuin siirrymme kunnolla videopelien tekemiseen, opetamme ohjelmoinnin perusteet luomalla pieniä, yksinkertaisia ohjelmia joilla saamme kaikki ohjelmoinnin peruskäsitteet käytyä läpi.

Ohjelmointikielenä käytämme kieltä nimeltä C# (Cee-Sharp), joka on helpoimpia ohjelmointikieliä jolla pystyy tekemään ohjelmia, ja jota käytetään myös pelien tekemiseen.

Sanastoa

IDE = Integrated Development Environment. Tämä on se ohjelma, jonka sisällä koodia kirjoitetaan ja käännetään. (esim. Visual Studio)

C# ohjelmat

Ohjelma on pelkästään monta riviä koodia, jotka tietokone tulkitsee käskyiksi toimia. Tietokone lukee ohjelman koodia ja suorittaa sitä aina rivi kerrallaan. Ohjelmointikieli tarkoittaa sitä miten tietokone ohjelmaa lukee ja suorittaa. Ohjelmointikielet on optimoitu erillaisiin tarkoituksiin, eikä kaikilla kielillä voikkaan tehdä kaikkea. C# kieltä käytetään yleensä erittäin paljon juuri pelien tekemisessä.

C#-ohjelma koostuu joukosta lauseista (statement), jotka kirjoitetaan tekstitiedostoon. Lauseet ovat komentoja joita tietokone suorittaa ja päättyvät puolipisteeseen (;). Lauseiden avulla voidaan luoda muuttujia (variable), joihin tallennetaan erilaista dataa kuten numeroita ja sanoja. Muuttujan käyttö vaatii sen esittelyä (declaration) ja alustusta (initialization). Muuttujan esittely tarkoittaa sen tietotyypin (datatyyppi, data type) ja nimen määräämistä.

Ohjelmoija on siis henkilö joka luo komentoja ja antaa näin tietokoneelle käskyjä, ja saa sen toimimaan haluamallaan tavalla. Koska ohjelmat ovat pelkkää tekstiä, voisimme luoda ja muokata niitä millä tahansa tekstin muokkaus ohjelmalla. On kuitenkin paljon helpompaa käyttää ohjelmaa joka on luotu ohjelmointiin. Yksi parhaimmista ohjelmointi ohjelmista on Visual Studio, mutta se on suhteellisen  raskas tietokoneelle käyttää, ellei ole hyvää konetta. Visual Studiosta on olemassa myös kevyempi versio, nimeltään Visual Studio Code. Myös NotePad++ on suosittu, sekä MonoDevelop. Kun alamme käyttää Unitya eli pelienteko ohjelmaa, käytämme tällöin koodaamiseen juuri joko Visua Studiota ja Visual Studio Codea, mutta nyt kursseilla käytämme nettisivua nimeltään https://dotnetfiddle.net/ joka on täysin selaimessa toimiva C# koodaus ohjelma.

Alla näet vähän miltä dotnetfiddle alunperin näyttää. Muutetaan sen asetuksia hieman jotta meidän on helpompi käyttää sitä.

Vasemmalla näemme asetukset. Language saa pysyä samana, sillä haluamme juuri käyttää C#, mutta muutetaan sen alla olevaa kohtaa Project Type. Tällä hetkellä se on Console, mutta muutetaan sen tilalle Script. Nyt moni kuvassa olevan vaihtoehdon tulisi kadota, sekä keskellä näkyvän koodin ulkoasu hieman muuttua. Tämä on hyvä siihen että aloittelemme vasta ohjelmointia. Palaamme alkuperäisiin asetuksiin myöhemmin ohjeissa, mutta pysytään nyt näissä.

Vasemmalla alimpana on myös Auto Run-kohta joka on päällä, mutta laitetaan se pois päältä. Jos tämä on päällä, koodi suoritetaan aina kun sitä muokkaamme, mutta on helpompaa antaa meidän päättää aina milloin koodi suoritetaan.

Nyt sivun tulisi näyttää tältä:

Käydään sitten läpi mitä sivulla näemme. Vasemmalla on asetukset kuten aijemmin jo totesimme ja muokkasimme niitä. Keskellä sivua näkyy jo valmiiksi tehtyä koodia. Tämä on sivun koodieditori. Tähän me luomme ja muokkaamme omaa koodia jotta saamme sen toimimaan kuten haluamme.

Ylhäällä näkyy erillaisia vaihtoehtoja. Näitä painamalla voimme luoda uusia ja tallentaa kooda, mutta nämä toimivat vain jos olemme kirjautuneet sisään. Run- painike on tärkeä, koska siitä painamalla suoritamme ohjelmamme. Aina kun haluamme testata toimiiko koodi kuten haluamme, painamme tästä. Muilla näppäimillä ei ole niinkään väliä.

Alhaalla näemme niinsanotusti sivun "konsolin". Jos tulostamme ohjelmassa jotain, niin se näkyy täällä. Ohjelma tulostaakin jo valmiiksi legendaarisen lausahduksen "Hello World" konsoliin.

Koska aloitamme aivan puhtaalta pöydältä, voimme poistaa koodieditorista kaiken koodin paitsi ylimmän rivin, joka on "using System". using System kertoo mitä kirjastoa ohjelma käyttää. System kirjasto sisältää yleisimmät ohjelman toiminnallisuudet, mitä tällä alkeiskurssilla tarvitsemme.

Muuttujat

Muuttujat ovat ohjelmassa väliaikaisesti tallennettuja tietoja. Muuttujat tulee aluksi määritellä, ja antaa sille jokin oletusarvo. Kun ohjelma käynnistetään, antaa se muuttujalle kyseisen oletusarvon. Muuttujien arvoja on mahdollista muokata ohjelman ollessa käynnissä, mutta tieto ei säily ohjelman sammutettua. Seuraavan kerran kun ohjelma taas käynnistyy, saa muuttuja taas oletusarvonsa.

Tärkeimpiä muuttujia ovat:

int, joka on kokonaislukumuuttuja, ja hyväksyy minkä tahansa kokonaisluvun.

double, joka on reaali luku muuttuja ja joka hyväksyy myös desimaali lukuja.

float, joka on reaali luku muuttuja ja joka hyväksyy myös desimaali lukuja, kunhan sen perään laitetaan ‘f’ kirjain. Unity-pelimoottori käyttää paljon float-arvoja.

char, johon voi tallentaa minkä tahansa merkin.

string, joka on merkkijono muuttuja, ja johon voi tallentaa sanoja ja lauseita.

bool, joka on totuusarvo muuttuja, joka on joko true eli totta, tai false eli ei totta.

Unity-pelimoottorissa, eli ohjelmassa jota käytämme lopulta pelien tekemiseen, muuttujia on paljon useampia, mutta mitä ne ovat ja miten niitä käytetään käydään läpi unity-harjoituksissa toisella kerralla.

Kaikki muuttujat määritellään tietyn kaavan mukaan. Ensimmäisenä määritellään muuttujan tyyppi, eli onko se esim int vai string. Sitten annamme muuttujalle nimen. Muuttujan nimi voi olla mikä tahansa kunhan siinä ei ole ääkkösiä tai erikoismerkkejä. Jatkossa muuttujaan viitataan aina sille annetulla nimellä. Sitten laitetaan ‘=’ merkki, ja annetaan sille oletusarvo minkä se saa aina ohjelman käynnistäessä. Jokainen rivi loppuu puolipilkkuun ‘;’. Tämä kertoo ohjelmalle etteivät muut rivit liity tähän lauseeseen mitenkään.

Esimerkki 1:

int numero=4;

double desimaali=0.4;

float luku=0.4f;

string lause="Lause voi kirjoitaa tänne";

char kirjain=’c’;

bool totuus=true;

Kommentointi

Muuttujia ja tiedostoja nimetessä on tärkeää nimetä ne hyvin ja asiaan liittyvästi. Näin sinun sekä muiden ihmisten on helpompi ymmärtää koodia, ja koodista tulee muutenki helppolukuisempaa. Ohjelmia tehdessä on tärkeää myös muistaa kommentoida koodia samasta syystä. Joskus saattaa tulla hetkiä jolloin et pitkään aikaan työstä ohjelmaa, tai joudut tutkimaan mitä jonkun toisen koodi tekee tai toisin päin. Tällöin kommentteihin kirjoittaminen mitä kukin ohjelman osa tekee auttaa muistamaan miten ohjelma toimii. Tämä auttaa myös jos koodissa on jokin ongelma mikä pitää korjata.

Ohjelmaa voi kommentoida kahdella tavalla: voit kommentoida yhdelle riville käyttämällä // ennen kommentoitavaa asiaa. Ohjelma jättää kaiken kommentoinnin huomiotta, joten se ei vaikuta ohjelman toimintaan mitenkää jos ohjelmassa on kommentteja. Useammalle riville voit kommentoida käyttämällä /* ennen kommentoitavaa asiaa, ja */ kommentoitavan asian jälkeen sen merkiksi että kommentti loppuu siihen

Esimerkki 1:

//Tämä on esimerkki. Ohjelma ei tunnista tätä riviä koodissa

/* tämä on esimerkki

ohjelma ei tunnista näitä rivejä koodissa*/

Tämä on esimerkki. Ohjelma antaa virheilmoituksen tästä koska se ei ole kummankaan kommentointi tavan sisällä.

Ohjelman tulisi tulostaa sanat Hello World konsoliin näytön alareunaan. Console.WriteLine on komento jonka annamme ohjelmalle joka käskee sitä tulostamaan konsoliin haluamamme sanat. Tehtävässä nämä sanat ovat Hello World, mutta kirjoitit sinne mitä tahansa, niin se toimii silti, kunhan se on lainausmerkkien ympäröimä. Voit kirjoittaa myös sanoja suoraa Console.Write:n sulkujen sisälle, kunhan kirjoitat ne taas lainausmerkkien sisällä. Kokeile kaikkea mitä haluat.

Muuttujia on mahdollista asettaa toisiinsa. Tämä toimii yksinkertaisesti luomalla ensimmäinen muuttuja ja asettamalla sille arvo, luomalla toinen muuttuja ja asettamalla sen arvoksi ensimmäinen muuttuja.

Esimerkki 2:

int ensimmainen=23;

int toinen = ensimmainen;

ensimmainen=13;

Console.WriteLine(toinen);

Console.WriteLine(ensimmainen);

Esimerkissä teemme juuri niinkuin aijemmin luki. Me myös muutamme ensimmainen-muuttujan arvoa sen jälkeen kun se on asetettu toinen-muuttujaan. Jos testaamme esimerkkiä, niin huomaamme että niiden arvot ovat tulostettaessa eri. Tämä johtuu siitä, että kun asetamme muuttujan arvoksi toisen muuttujan, se kopioi kyseisen muuttujan arvon itseensä, ei itse muuttujaa. Tämän takia meidän ei tarvitse huolehtia että muuttamalla yhtä muuttujaa jokainen muuttuja ohjelmassa muuttuu samalla.

Operaattori 

Muuttujiin voidaan myös asettaa laskuja. Nämä laskut saavat sisältää muita muuttujia sekä normaaleja lukuja. Laskut voidaan tehdä aritmeettisilla operaattoreila, joita ovat:

+, jolla voit plussata lukuja yhteen. + merkkiä käytetään myös yhdistäessä tekstejä toisiinsa.

-, jolla voit miinustaa lukuja toisistaan.

*, jolla voit kertoa luvut toisillaan.

/, jolla voit jakaa luvut toisillaan

%, jolla saat jakojäännöksen, eli jakolaskusta yli jääneet luvut. Ohjelma siis kokeilee toisena annettua lukua ensimmäiseen niin monta kertaa kuin se menee siihen tasan, ja kun se ei enää mahdu siihen, antaa se yli jääneet luvut. Esim 23%4 antaa arvon 3, sillä 4 mahtuu 23 viisi kertaa, jolloin se on 20, ja yli jäävä luku on 3. Tätä käytetään yleensä tarkistamaan kuuluuko jokin luku tiettyyn kertotauluun, tai onko luku esim parillinen vai pariton.

Esimerkki 1:

string ensimmainen="Hello";

string toinen=ensimmainen+" World!";

int plussa=2+1;

int miinus=plussa-1;

int kerto=3*1;

int jako=kerto/1;

int prosentti=21%2;

Console.WriteLine(toinen);

Console.WriteLine(plussa);

Console.WriteLine(miinus);

Console.WriteLine(kerto);

Console.WriteLine(jako);

Console.WriteLine(prosentti);

Tulostus tulisi näyttää seuraavalta:

Hello World!

3

2

3

3

1

Ohjelmoinnissa muuttujia halutaan usein muuttaa jotenkin ja asettaa sen takaisin samaan muuttujaan. Tämä käy helpoiten arvonmuunto-operaattoreita. Näitä operaattoreita ovat:

‘+=’ plussaa muuttujaan annetun luvun

‘-=’ miinustaa muuttujasta annetun luvun

‘*=’ kertoo muuttujan annetulla luvulla

‘/=’ jakaa muuttujan annetulla luvulla

‘%=’ asettaa muuttujaan muuttujan jakojäännöksen

‘++’ kasvattaa muuttujaa yhdellä

‘--’ vähentää muuttujaa yhdellä

Miten arvonmuunto-operaattorit toimivat käytännössä on, se ottaa muuttujassa olevan luvun, tekee sille halutun asian ja asettaa sen takaisin muuttujaan.

Esimerkki 2:

int muuttuja1=4;

int muuttuja2=4;

muuttuja1+=3;

muuttuja2=muuttuja2+3;

Console.WriteLine(muuttuja1);

Console.WriteLine(muuttuja2);

Esimerkin molemmat tulostukset ovat 7, sillä laskut toimivat täysin samoin.

Voimme suorittaa laskuja muuttujiin, mutta voimme myös tulostaa ne suoraa. Tämä käy laittamalla laskut Console.WriteLinen sulkujen sisään, jolloin se tulostaa laskun tuloksen, ei itse laskua. Voimme myös helposti yhdistellä muuttujia lauseiden kanssa, saaden näin tulostettua käyttäjälle asiat oikealla tavalla. Meidän on vain yhdistettävä haluamamme asiat plus-merkeillä.

Esimerkki 3:

int arvo=5;

string nimi="arvo";

Console.WriteLine(nimi+ "-muuttujan arvo on "+arvo+". Tämä kerrottuna kymmenellä on "+(arvo*10));

Tyyppimuunnokset

Muuttujia on mahdollista muuttaa myös yhdestä toiseen joko suoraa vain asettamalla sen, tai se pitää ensin erikseen muuttaa haluttuun muotoon.

Voimme esimerkiksi asettaa int-muuttujan suoraa float-muuttujaan koska float pystyy käsitellä kokonaislukuja, mutta tämä ei toimi toisin päin, koska int-muuttuja ei pysty käyttämään desimaali lukuja. Float muuttujan asettaminen int- muuttujaan on kuitenkin mahdollista. Tämä onnistuu muuttamalla float muuttuja int- muuttujaksi laittamalla ‘(int)’ float muuttujan alkuun. Tällöin ohjelma muuttaa float muuttujan int muuttujaksi. Koska float muuttuja voi kuitenki olla desimaali luku, pyöristetään float muuttuja alaspäin lähimpään kokonaislukuun muutoksessa.

Esimerkki 1:

int numero1=4;

float leijuva1=numero1;

float leijuva2=5.9f;

int numero2=(int)leijuva2;

Console.WriteLine(numero1);

Console.WriteLine(leijuva1);

Console.WriteLine(leijuva2);

Console.WriteLine(numero2);

Tulostus on:

4

4

5.9

5

Koska int muuttujan voi laittaa suoraa float-muuttujaan, se ei muutu. Mutta koska float-muuttuja on mahdollista olla desimaali, pitää se erikseen muuttaa intiksi, jolloin se pyöristyy alaspäin lähimpään kokonaislukuun.

Kaikki numeraaliset muuttujat saadaan suoraa string-muuttujaksi, mutta taas, toisin päin tämä ei toimi koska string muuttuja sisältää paljon muutakin kuin vain numeroita. string-muuttujan muuttaminen on kuitenkin mahdollista muuttaa esim. int-muuttujaksi käyttämällä lauseketta: int.parse(string) jossa string on haluttu lause. Tällöin ohjelma muuttaa string-muuttujan int-muuttujaksi jos tämä on mahdollista. Mikäli merkkijonossa ei numeroa kuitenkaan ole tai se sisältää jotain muuta kuin numeroita, aiheuttaa tämä errorin ohjelmassa. Tämä toimii kaikkiin numeraalisiin arvoihin vaihtamalla int.parse()-lausekkeesta int toiseksi numeraaliseksi muuttujaksi.

Esimerkki 2:

string lause1="42";

string lause2="4.2";

int numero=int.Parse(lause1);

float leijuva=float.Parse(lause2);

Console.WriteLine(numero);

Console.WriteLine(leijuva);

Syötteen käsittely

Kaikki tähän asti olleissa esimerkeissä on ohjelman kaikki arvot saat suoraa ohjelmasta. Tämä ei kuitenkaan mene aivan pelistä. Seuraavaksi lisäämmekin käyttäjän antaman syötteen ohjelmaan ja käytämme sitä. Näin teemme ohjelmasta interaktiivisen, eli sen käyttäjä tai pelaaja voi vaikuttaa jotenkin mitä ohjelmassa tapahtuu.

Käyttäjän syötteen lisääminen tapahtuu käyttämällä lausetta Console.ReadLine(); . Tämä laittaa ohjelman odottamaan käyttäjältä syötettä. Kun käyttäjä on antanut syötteen, on meidän otettava annettu asia talteen. Tämä onnistuu luomalla string muuttuja, ja asettamalla sen arvoksi Console.ReadLine();

Esimerkki 1:

Console.WriteLine("Anna oma nimesi");

string nimi=Console.ReadLine();

Console.WriteLine("no mutta hei " + nimi);

Esimerkin ohjelma pyytää käyttäjää antamaan oman nimensä, ja odottaa että käyttäjä antaa nimensä, ottaa sen talteen ja sen jälkeen tervehtii käyttäjää tämän antamalla nimellä.

Console.ReadLine()-komentoa voi käyttää kuten mitä tahansa muuta string-muuttujaa, eli se on mahdollista myös muuttaa int-muuttujaksi mikäli käyttäjä antaa numeron.

Esimerkki 2:

Console.WriteLine("Anna ensimmäinen numero");

int eka=int.Parse(Console.ReadLine());

Console.WriteLine("Anna toinen numero");

int toka=int.Parse(Console.ReadLine());

Console.WriteLine(eka+" kerrottuna " +toka+" on "+eka*toka);

Esimerkissä muunnamme käyttäjän antamat vastaukset suoraa int-muuttujaksi, jonka jälkeen tulostamme ne kerrottuna toisiinsa. Tämä ei ole kuitenkaan paras tapa tehdä tämä, sillä jos käyttäjä ei annakkaan mitään numeroa, aiheuttaa tämä errorin ohjelmassa. Miten tämä korjataan näytetään seuraavassa kohdassa.

Vertailu if

If-lauseke löytyy jokaisesta ohjelmointikielestä, ja sillä vertaillaan onko jokin arvo totta. Yksinkertaisimmillaan tämä onnistuu käyttämällä bool-muuttujaa.

Kuten muistatte, bool-muuttujassa on mahdollista olla vain arvot True, eli totta, sekä False, eli valetta. If-lauseke tarkistaa on bool-muuttuja totta, ja mikäli on, jatkaa ohjelmassa eteenpäin. Mikäli bool ei ole totta, pystyy se jättämään osan ohjelmasta väliin ja jatkamaan myöhemmästä kohtaa.

Esimerkki 1:

bool arvo=true;

if(arvo){

        Console.WriteLine("Tämä arvo on tosi!");

}

Esimerkki luo bool-muuttujan ja antaa sen arvoksi totta, jonka jälkeen if lause tarkistaa onko arvo totta. Mikäli on, se tulostaa Tämä arvo on tosi!. Jos muutamme arvo-muuttujan arvon olemaan ei tosi eli false, niin se ei tulosta mitään, sillä se ei pääse käsiksi aaltosulkeiden sisälle.

Esimerkistä näkyy myös if-lauseen rakenne. if-lause alkaa kirjoittamalla if, ja laittamalla sulkeiden sisään totuusarvo jota olemme tarkistamassa, eli tällä kertaa arvo-muuttuja. heti if-lauseen jälkeen tulee aaltosulkeet, jotka merkitsevät erillistä ohjelman osaa. Koska aaltosulkeiden edessä on if-lauseke, ei ohjelma pääse aaltosulkeiden sisälle ilman että if-lauseelle annettu arvo on totta.

bool-muuttujan arvoissa, sekä if-lausekkeen sisällä voidaan käyttää vertailuoperaattoreita. Vertailuoperaattoreilla voidaan verrata kahta arvoa toisiinsa, ja mikäli lauseke on totta, palauttaa se bool arvon true, ja mikäli ei niin palauttaa se false. Näitä operaattoreita ovat

==’ tarkistaa ovatko arvot yhtä suuria

!=’ tarkistaa etteivät arvot ole yhtä suuria

‘>’ tarkistaa onko ensimmäisenä annettu luku suurempi kuin toisena

<’ tarkistaa onko ensimmäisenä annettu luku pienempi kuin toisena

‘>=’ tarkistaa onko ensimmäisenä annettu luku suurempi tai yhtäsuuri kuin toisena annettu

luku

‘<=’ tarkistaa onko ensimmäisenä annettu luku pienempi tai yhtäsuuri kuin toisena annettu luku

vertailuoperaattoreita voidaan käyttää asettamaan bool-muuttujalle arvo, tai suoraa if-lausekkeessa.

Esimerkki 2:

int luku=4;

bool arvo=(luku==4);

if(luku>3){

        if(arvo){

                Console.WriteLine("Kaikki on totta!");

        }

}

Esimerkissä esitellään muutaman vertailuoperaattorin toimintaa. Aluksi määritellään int-muuttuja luku ja annetaan sen arvoksi 4. Sitten määritellään bool arvo, ja vertaillaan vertailuoperaattorilla onko luku yhtäsuuri kuin 4. Koska on, arvo-muuttujan arvoksi tulee true. if-lauseke puolestaan tarkistaa on int-muuttuja luku suurempi kuin 3. Koska luku on 4, on tämä totta ja ohjelma voi jatkaa aaltosulkeiden sisään. Täällä se tarkistaa onko bool-muuttuja arvo totta. Koska on, jatkaa se myös toistenkin aaltosulkeiden sisään ja tulostaa "Kaikki on totta!".

Joissakin tapauksissa, kuten ylemmässä esimerkissä, haluamme tarkistaa onko useampi väite totta. Tämä onnistuu käyttämällä loogisia operaattoreita, joita ovat:

‘&&’ tarkistaa ovatko kaksi annettua väitettä totta

‘||’ tarkistaa onko edes jompi kumpi annetuista väitteistä totta

‘!’ tarkistaa, onko annettu väite valetta. Mikäli on, niin silloin se on totta, ja jos väite onkin totta, niin se palauttaa valetta. Toisin sanoen, se tarkistaa väitteet ristiin jolloin kaikki mikä on valetta onkin totta ja toisin päin.

Esimerkki 3:

int luku=4;

bool arvo=(luku==3);

if(luku>3&&!arvo){

        Console.WriteLine("Kaikki on totta!");

}

Esimerkki on samannäköinen mutta monimutkaisempi mitä aijempi esimerkki oli. Luodaan taas int luku ja annetaan sille arvo. Luodaan bool arvo ja katsotaan onko luku yhtä suuri kuin 3. Koska luku ei ole 3, saa muuttuja arvoksi false. Tämän jälkeen if lauseke tarkistaa onko luku suurempi kuin 3, ja että arvo-muuttujan arvo ei ole totta. Koska luku on 4 eli suurempi kuin 3, ja arvo-muuttuja on false, jatkaa se aaltosulkeiden sisään tulostukseen

 Näitä kaikkia operaattoreita hyväksi käyttämällä voimme tarkistaa kaikenlaista.

Ohjelmoinnissa meille tulee kuitenkin tilanteita kun haluamme että jotain tapahtuu kun jokin arvo on totta, mutta jotain muuta kun se onkin valetta. Tämä onnistuu else lausekkeella, jota käytetään if lausekkeen kanssa. Kun if lauseke tarkistaa onko jokin arvo totta. Jos se ei ole, niin ohjelma ei pääse aaltosulkeiden sisään, vaan silloin se pääsee else:n aaltosulkeiden sisään

Esimerkki 4:

bool arvo=false;

if(arvo){

        Console.WriteLine("arvo on totta");

}else{

        Console.WriteLine("arvo ei ole totta");

}

Esimerkissä ohjelma pystyy tulostamaan vai jomman kumman arvoista. Jos arvo-muuttujan arvo on true eli totta, tulostaa ohjelma että arvo on totta, muuten se tulostaa että arvo on valetta. Joissakin tilanteissa tämäkään ei ole tarpeeksi, vaan ohjelman on saatava tietää tarkemmin mitä tehdä. Tällöin voimme käyttää else if lauseketta. else if-lauseke toimii aivan samoin kuin if-lausekekkin, mutta se tarkistetaan vain jos ensimmiäinen if-lauseke on väärin. else if-lausekkeita voi olla niin monta kuin haluaa, kunhan se alkaa ensin yhdellä if-lausekkeella. else-lauseke suoritetaan else if-lausekkeen jälkeen, jos mikään niistä ei ollut tosi.

Esimerkki 5:

int numero=4;

if(numero==3){

        Console.WriteLine("numero on 3");

}else if(numero>3)

        Console.WriteLine("numero on suurempi kuin 3");

}else{

        Console.WriteLine("numero on pienempi kuin 3");

}

Esimerkissä määritellään int-muuttuja numero, ja sen arvoksi 4. if lauseke tarkistaa onko numero, ja jos ei ole, se tarkistaa onko se suurempi kuin 3. Esimerkissä on, jolloin se tulostaa että numero on suurempi kuin 3. Mikäli numero arvon muuttaa pienemmäksi kuin 3, pääsee ohjelma else lausekkeseen, jolloin se ilmoittaa numeron olevan pienempi kuin 3.

Vertailu switch

if-lauseke on kätevä ja yksinkertainen monien erillaisten asioiden tarkistamiseen. Mutta jos joskus ohjelmoinnissa haluamme tarkistaa vain yhden muuttujan eri arvoja, on kätevämpää käyttää switch-lauseketta.

switch on rakenteeltaan hyvin erilainen kuin if, mutta toimii samalla tavalla. switch lauseke suorittaa seuraavan laista rakennetta:

Esimerkki 1:

string vertailulauseke="vakio1"

string vakio2="vakio2";

switch(vertailulauseke)

  {

    case "vakio1":

      //Lauseet1

      break;

    case vakio2:

      //Lauseet2

      break;

    [default:

      //default-lauseet

      break;

    ]

  }

switch lauseke aloitetaan sanalla switch ja antamalla sille verrattava muuttuja. Esimerkissä muuttujan nimi on vertailulauseke. Tämän jälkeen switch siirtyy aaltosulkeisiinsa, ja alkaa verrata sille annetun muuttujan arvoa switchiin määrritellyihin case:ihin. switch tarkistaa onko case sanan perään annettu arvo sama kuin switchille annettu arvo. mikäli on, se siirtyy casen kaksoispisteiden jälkeisille riveille suorittamaan koodia. Jos case taas ei ole sama, siirtyy se suoraa seuraavaan case:en. Mikäli mikään case ei ole sama kuin switchille annettu arvo, voidaan switchille määritellä default-lauseke, joka siis toimii samoin kuin if lauseen else. Jokaisesta Casesta löytyy myös break; komento. Kyseinen komento lopettaa switchin toiminnan, ettei se enää jatka oikean casen löytämistä. Mikäli break; komennon ottaa pois, jatkaa switch oikean casen etsimistä vaikka se jo kerran löysi. Ominaisuutta kannattaa käyttää hyväksi joissakin tilanteissa.

Switch lausekkeessa voi myös määrä useamman case:n samoille koodeille. Tämä tapahtuu vain laittamalla molemmat case:t peräkkäin ennen koodia

Esimerkki 2:

string vertailulauseke="vakio1"

switch(vertailulauseke)

  {

    case "vakio1":

    case "vakio2":

      //molempien lauseet

      break;

    [default:

      //default-lauseet

      break;

   ]

}

Huom! Vaikka switch on olemassa, sitä ei silti tarvitse käyttää. Switch on monimutkainen, eikä millään tavoin parempi kuin if-lausekkeet. Joten käyttäkää aina mielummin if-lausekkeita kuin switchiä.


Random

Random on omanlaisensa muuttuja C# kielessä, mutta sitä käytettäessä se antaa aina satunnaisen numeron syöttämiesi numeroiden väliltä. Tehdessämme pelejä, on meidän usein käytettävä satunnaisia arvoja, jotta pelistä saadaan mielenkiintoinen. Unityssa on oma Random-systeeminsä, joten tämä esimerkki toimii C# tehtävissä.

Esimerkki 1:

using System;

//Luomme uuden random-generaattorin nimeltä “r”

Random r = new Random();

//Tulostamme random-generaattorin avulla arvon väliltä //0-100

Console.WriteLine(r.Next(100));

//Tulostamme random-generaattorin avulla arvon väliltä //10-100

Console.WriteLine(r.Next(10, 100));

Esimerkissä luomme uuden random muuttujan, jonka jälkeen tulostamme siitä Next-arvon. Next-arvo antaa juuri uuden satunnaisen int-arvon antamiemme numeroiden välillä. Jos annamme Nextin sulkeiden sisään vain yhden numeron, tulostaa se lukujen 0 ja 100 väliltä, 0 ollessa pienin mahdollinen luku 99 suurin. Jos taas annamme sulkeisiin kaksi eri lukua sulkeilla erotettuna, ensimmäinen luku on pienin mahdollinen, ja toinen luku miinus yksi on suurin mahdollinen.

Esimerkkitulostus 1:

33

42

Voimme asettaa muuttujiakin Nextin sulkeisiin, tai esimerkiksi antaman syötteen.


Esimerkki 2:

using System;

//Luomme uuden random-generaattorin nimeltä “r”

Random r = new Random();

//Luomme muuttujan “luku1”, joka on tyyppiä int ja saa arvokseen //12

int luku1 = 12;

//Tulostamme alla olevan tekstin konsoliin ja pyydämme arvoa

Console.WriteLine("Anna luku, joka on suurempi kuin 12");

//Luodaan uusi muuttuja “luku2”, joka on tyyppiä int ja saa
//arvokseen käyttäjän syöttämän luvun

int luku2 = int.Parse(Console.ReadLine());

//Tulostamme konsoliin luvun, joka valitaan satunnaisesti luvun 12

//ja käyttäjän syöttämän luvun väliltä

Console.WriteLine(r.Next(luku1, luku2));

Esimerkissä tulostetaan satunnaisesti luku 12 sekä käyttäjän antaman luvun väliltä. Mikäli käyttäjä syöttää pienemmän luvun kuin 12, antaa ohjelma meille virheilmoituksen.

Kuten aijemmin jo mainitsin, Unityssä emme käytä tätä, vaan sielä meillä on oma Random-systeemimme jonka tulemme käymään läpi.

Esimerkkitulostus 2:

Anna luku, joka on suurempi kuin 12

>22

20

Toisto while

while-lauseke tapahtuu niin kauan kuin sille annettu ehto on totta. Sille annetaan totuusarvot aivan samalla tavoin kuin if-lauseellekkin, mutta niin kauan kun kyseiset arvot ovat totta, se suorittaa jotain toimintoa. Tästä syystä on oltava tarkkana että while-lausekkeelle annetut arvot muuttuvat while-lausekkeen aaltosulkeiden sisällä, ettei se jää looppiin, eli ohjelma jää suorittamaan samaa koodinpätkää ilman mitään ulospääsyä. Tällöin ohjelma usein kaatuu, ja se joudutaan sammuttamaan väkisin jolloin on vaarana menettää osa tallentamatonta koodia, joten ole varovainen.

Esimerkki 1:

using System;

//Luomme muuttujan “luku”, se on tyyppiä int (kokonaisluku) ja
//arvo 3

int luku = 3;

//while(luku>0) ← sulkujen sisällä oleva vertaus on ehto alla

//olevalle while lauseelle

//Niin kauan, kuin “luku” on suurempi kuin nolla, tulostamme

//muuttujan “luku” ja kolme pistettä. Tulostamisen jälkeen

//muuttujaa “luku” pienennetään arvolla 1

while(luku>0)

{

        Console.WriteLine(luku + "...");

        luku--; //Tässä siis vähennämme muuttujaa “luku” yhdellä

}

//Tulostamme näytölle tekstin “START!” ja luomme string-tyyppisen

//muuttujan “lause”, jolle ei anneta mitään arvoa

Console.WriteLine("START!");

string lause = "";

//Niin kauan kuin muuttuja “lause” ei sisällä seitsemää

//a-kirjainta, lisäämme lauseeseen yhden a-kirjaimen ja

//tulostamme sen

while(!lause.Contains("aaaaaaa"))

{

lause += "a";

        Console.WriteLine(lause);

}


Esimerkkitulostus 1:

3...

2...

1...

START!

a

aa

aaa

aaaa

aaaaa

aaaaaa

aaaaaaa

While voi tarkistaa mitä tahansa, kunhan se antaa arvoksi true tai false.

While on hyvä käyttää jos jotain asioita joita joudutaan toistamaan monta kertaa, tai kunnes jotain tapahtuu. While on mahdollista käyttää myös käyttämällä pelkkää true arvoa, jolloin ohjelma suorittaa koodin kunnes saavuttaa break komennon. Kun break-komento saavutetaan, kaikki sen jälkeen tulevat komennot jätetään tekemättä.

while(true) -käyttö voi olla vaarallista, koska siinä on mahdollisuus, että ohjelma jää ikuiseen silmukkaan. Jos on kyse raskaammasta ohjelmasta, se voi kaataa kehitysympäristön (IDE) ja kaikki tallentamattomat muutokset häviävät.


Esimerkki 2:

using System;

//Tässä luodaan muuttuja “luku” joka on tyyppiä int ja saa

//arvokseen 3

int luku = 3;

//While ei nyt tarkista mitään ehtoa, vaan se on koko ajan totta

//Nyt kun while on totta, sen sisällä olevaa koodia suoritetaan

//niin kauan, kunnes se keskeytetään break-komennolla

while(true)

{

//Jos luku on 0, lopetetaan while break-komennon avulla

//ja sen sisällä olevaa koodia ei enää suoriteta

if(luku == 0)

{

        break;

}

//Tulostetaan luvun arvo ja sen perään kolme pistettä

        Console.WriteLine(luku + "...");

//Muuttujan “luku” arvoa vähennetään yhdellä

        luku--;

}

//Tulostetaan sana “START!”

Console.WriteLine("START!");

Esimerkkitulostus 2:

3...

2...

1...

START!

Esimerkki toimii samalla tavalla kuin aijempikin, mutta siinä on käytetään break; komentoa sen sijaan että tarkistettaisiin while:ssa arvo.

while-lausekkeessa ehto tarkistetaan aina alussa. Tästä syystä, mikäli arvo ei ole totta heti alussa, ei whilen sisältöä tehdä kertaakaan. Mikäli haluamme esimerkiksi tehdä whilen sisällön aina vähintään kerran, voidaan käyttää do-while komentoa. do-while toimii täysin samoin kuin while, mutta sen rakenne on hieman erilainen, koska tarkistaa whilen totuusarvon vasta whilen lopussa.

Esimerkki 3:

using System;

//Luodaan muuttuja “numero”, joka on tyyppiä int ja saa arvokseen

//nollan

int numero = 0;

//Whilen sisällä oleva koodi suoritetaan vain silloin, kun

//”numero” muuttujan arvo on alle kymmenen ja suurempi kuin nolla

//Alla olevan while:n sisällä olevaa koodia ei suoriteta, koska

//numero ei ole suurempi kuin nolla. Eli koodissa hypätään tämän
//while:n ohi ja suoritetaan do-while:n sisällä oleva koodi.

while(numero < 10 && numero > 0)

{

//Tulostetaan muuttujan “numero” arvo ja välilyönti

Console.Write(numero + " ");

//Lisätään “numero” muuttujan arvoon yksi

numero++;

}

//do-while komennossa suoritetaan aina ensin do:n sisällä oleva

//koodi ja sen jälkeen vasta tarkistetaan, onko while:n sisällä

//oleva ehto totta.

do

{

//Tulostamme muuttujan “numero” sisällön ja välilyönnin

Console.Write(numero + " ");

//Muuttujan “numero” arvoa korotetaan numerolla yksi

numero++;

}

//do:n koodi suoritetaan uudelleen, jos muuttujan “numero” arvo

//on pienempi kuin kymmenen ja suurempi kuin nolla

while(numero < 10 && numero > 0);

//Koska suoritimme ensin do:n sisällä olevan koodin, muuttujamme

//arvoksi tuli 1, joten while:n ehto on nyt tosi ja suoritamme

//do:n sisällä olevaa koodia niin kauan, kunnes while:n ehto ei

//ei ole enää tosi.


Esimerkkitulostus 3:

0 1 2 3 4 5 6 7 8 9

Esimerkissä näkyy hyvin whilen ja do-whilen erot. Koska while tarkistaan lausekkeen alussa annetut true-arvot, ei se pääse missään kohtaa suorittamaan whilen sisältöä. Koska do-while tarkistaa annetut true-arvot vasta lausekkeen lopussa, ehtii se suorittaa sisällön jo kerran, ja tehdä sen sen takia useampaan kertaan koska numero-muuttujan arvo muuttuu sen sisällä.

Toisto for

Vaikka while-lauseke on kätevä suorittamaan samaa asiaa monta kertaa putkeen, on se vaarallinen koska se joutuu helposti looppiin. Tämän takia löytyy myös toinen lauseke joka suorittaa saman toiminnon, nimeltään for.

for-lausekkeen rakenne on hieman monimutkaisempi, mutta tämä juuri tekee siitä turvallisemman käyttää. for lausekkeen alussa luodaan jokin muuttuja, yleensä int mutta se voi olla mikä tahansa, ja annetaan sille nimi. Tämän jälkeen for-lausekkeelle annetaan ehto jonka mukaan se suorittaa koodia, yleensä liittyen sille luotuun numeraaliseen muuttujaan. Tämän jälkeen jos halutaan, voidaan laittaa miten numero muuttujaa muutetaan joka kerta kun ohjelma on käynyt for-lausekkeen läpi.


Esimerkki 1:

using System;

//Luodaan muuttuja “e”, jonka tyyppi on int ja arvo on 0

int e = 0;

//Tulostamme tekstin konsoliin

Console.WriteLine("Tässä on while-loopin tulosteet:");

//while-loopille annetaan ehto: Jos muuttuja “e” on pienempi

//kuin 10, suoritetaan while-loopin sisällä oleva koodi

while(e < 10)

{

//Tulostamme muuttujan “e” arvon konsoliin

        Console.WriteLine(e);

//Korotamme muuttujan “e” arvon yhdellä

        e++;

}

//Tulostamme rivinvaihdon

Console.WriteLine();

//Tulostamme tekstin konsoliin

Console.WriteLine("Tässä on for-loopin tulosteet:");

//for-lauseessa sulkujen sisällä luodaan muuttuja “i” ja annetaan

//sen arvoksi 0. Sitten kirjoitamme ehdon: jos muuttuja “i” on

//pienempi kuin kymmenen, suurennamme sitä luvulla yksi ja

//suoritamme for:n sisällä olevan koodin

for(int i=0; i<10; i++)

{

//Tulostamme muuttujan “i” arvon konsoliin

        Console.WriteLine(i);

}


Esimerkkitulostus 3:

Tässä on while-loopin tulosteet:

0

1

2

3

4

5

6

7

8

9

Tässä on for-loopin tulosteet:

0

1

2

3

4

5

6

7

8

9

Esimerkissä näytetään miten while ja for toimivat samalla tavalla. Aluksi luodaan int tyyppinen muuttuja e ja sen arvoksi annetaan nolla. Sitten aloitetaan while, jonka sisällä olevaa koodia suoritetaan niin kauan, kunnes muuttuja e on 10. Whilen sisällä tulostetaan e, ja suurennetaan e-muuttujan arvoa yhdellä.

For-lausekkeessa kaikki i-muuttujaan tehdyt muutokset tehdään yhdessä rivissä. Tämä on turvallisempaa koska näin voidaan helposti tarkistaa, että tarkistettava muuttuja muuttuu koko ajan, eikä tämän takia joudu looppiin.


Peliesimerkki

using System;

//Luodaan muuttujat, joita tullaan käyttämään pelissä. Kaikki ovat tyyppiä int.

int p1HP = 100, p2HP = 100, era = 1;

//Luodaan random-generaattori ja annetaan sen nimeksi r

Random r = new Random();

//Pyydetään konsolissa käyttäjää painamaan Enteriä

Console.WriteLine("Paina Enter aloittaaksesi taistelun");

Console.ReadLine();

//Taistelu jatkuu niin kauan, kun toisen pelaajan HP on suurempi kuin 0

while (p1HP > 0 && p2HP > 0)

{

//Tulostetaan, monesko erä alkaa

        Console.WriteLine(era + ". erä alkaa!");

        

//Random-generaattori antaa satunnaisen arvon väliltä 10-40, joka vähennetään

//pelaajan 2 hp:stä

        p2HP = p2HP - r.Next(10, 40);

        

//Tulostetaan konsoliin, se kuinka paljon pelaaja 2:lle jäi HP:a

        Console.WriteLine("Pelaaja 1 löi Pelaajaa 2. Pelaajalle 2 jäi " + p2HP + " HP");

        Console.WriteLine("Paina Enter jatkaaksesi");

        Console.ReadLine();

        

//Tässä tehdään sama kuin ylemmän lyönnin laskemisessa

        p1HP = p1HP - r.Next(10, 40);

        

        Console.WriteLine("Pelaaja 2 löi Pelaajaa 1. Pelaajalle 1 jäi " + p1HP + " HP");

        Console.WriteLine("Paina Enter jatkaaksesi");

        Console.ReadLine();

        

//Korotetaan era-muuttujaa ykkösellä

        era++;

}

//Kun jommankumman pelaajan HP on vähemmän kuin nolla, tulostetaan konsoliin kumpi voitti

if (p1HP <= 0)

{

        Console.WriteLine("Pelaaja 2 VOITTI!");

        Console.ReadLine();

}

else if (p2HP <= 0)

{

        Console.WriteLine("Pelaaja 1 VOITTI!");

        Console.ReadLine();

}

Array

Muuttujia on erilaisia, ja tärkeimmät niistä esiteltiinkin aivan alussa. Ohjelmoidessa tulee kuitenkin  hyvin usein tapauksia, jolloin joutuu luomaan paljon samanlaisia muuttujia samanlaiseen käyttöön, tai esimerkiksi luodakseen listan samanlaisia muuttujia. Tähän voidaan silloin käyttää Array:ta, joka tarkoittaakin listaa asioita. Näiden luominen onnistuu lisäämällä ‘[]’ muuttujan loppuun.

Kun luodaan array:ta, arvojen asettaminenkin toimii hieman eri tavalla kuin normaalissa muuttujassa. Kun luodaan Array, jotta se luodaan oikein, on siihen luotava oikea array asettamalla sen arvoksi ‘new muuttujatype[arrayn suuruus]{arrayn 0. arvo,arrayn 1. arvo… arrayn suuruus-1. arvo}; . Tällöin Arrayhyn luodaan "arrayn suuruus" verran muuttujia arrayhyn, ja asetetaan jokaiselle arvo erikseen aaltosulkeiden sisään, erottamalla arvot pilkulla. Voimme myös jättää arvot asettamatta, mutta silloin meidän on asetettava ne myöhemmin että niistä olisi jotain hyötyä. Tällöin on pakko antaa arraylle suuruus. Tai voimme jättää suuruuden pois, ja lisätä aaltosulkeisiin vain arvot, josta array saa itselleen suuruuden.

Kun olemme luoneet arrayn, ja asettaneet sille arvot, pääsemme näihin arvoihin käsiksi käyttämällä kulmikkaita sulkeita, ja kirjoittamalla siihen monennenko arvon haluamme. On kuitenkin huomioitava, arrayn ensimmäinen arvo on aina 0 kohdassa, ja arrayn viimeisen arvon saa käyttämällä arraysta saatavaa length arvo, ja miinustamalla siitä yksi. Muuten nämä arvot toimivat aivan kuten normaalit muuttujatkin. Voit tulostaa niitä, käyttää if lauseissa yms. kaikkea mitä olemme jo muuttujista opetellut.

Esimerkki 1:

using System;

//Luomme taulukon “arvoja”, jonka tyyppi on int ja sen alkioihin

//tallennetaan arvot 1, 2, 3, 4 ja 5

int[] arvoja = new int[]{1, 2, 3, 4, 5};

//Tulostamme taulukossa “arvoja” alkion 0 arvon, joka tässä //tapauksessa on 1

Console.WriteLine(arvoja[0]);

//Tulostamme taulukon viimeisen arvon, joka tässä tapauksessa on

//5

Console.WriteLine(arvoja[arvoja.Length-1]);

Esimerkki antaa tulosteeksi 1 ja 5, koska 1 on arrayn ensimmäinen arvo, ja 5 on viimeinen.

Syy miksi opetamme arrayt vasta nyt on, koska arrayt on kaikkein yksinkertaisimmat käyttää for-lausekkeen kanssa. Kun käytetään arrayta, niin halutaan tarkistaa kaikki arvot kerralla, ja vertaille niitä jotenkin. Tämä käy helpoiten käyttämällä for-lauseketta.

Esimerkki 2:

string[] arvoja=new string[]{"näin","helposti","tämä","käy"};

for(int i=0; i<arvoja.Length; i++){

        Console.Write(arvoja[i]+" ");

}

Console.WriteLine();

int[] numeroita=new int[6];

for(int i=0; i<numeroita.Length; i++){

        numeroita[i]=i;

Console.Write(numeroita[i]);

}

Esimerkissä luomme string arrayn joka sisältää neljä sanaa, ja tulostamme for-lausekkeen avulla kaikki nämä sanat helposti. Luomme myös int arrayn ja asetamme sille vain pituuden, jonka jälkeen for:ssa asetamme muuttujille arvot ja tulostamme ne.

Multidimensional array

multidimensional array tarkoittaa monen ulottuvuuden listaa. Tavallisella arraylla voimme luoda yhden rivin verran muuttujia, mutta multidimensional arraylla voimme luoda monta listaa asioita.

Luomme multidimensional arrayn hieman samalla tavoin kuin tavallisen arraynkin, eli aluksi tyypin, ja sitten [] sen perään, mutta tällä kertaa laitamme pilkun sulkeiden väliin. Tämä tarkoittaa että haluamme kahden ulottuvuuden arrayn. Kun asetamme arvoja, jos asetamme arraylle pituuden, laitamme sille kaksi pituutta jotka erotellaan pilkulla, ja nämä tarkoittava eri arrayn pituuksia. Jos taas asetamme aaltosulkeilla arvoja, laitamme ensin yhden aaltosulkeet, jonka sisään asetamme useita muita aaltosulkeita. näitä toisia aaltosulkeita tulee niin monta kun laitoit ensimmäisen arrayn pituudeksi. näiden sisään tulee niin monta haluamaasi muuttujaa kuin olet toiseen arrayhyn pituudeksi laittanut.

Esimerkki 1:

int[,] multi=new int[2,4]{{5,1,6,5},{3,8,5,6}};

for(int i=0; i<multi.GetLength(0); i++){

for(int o=0; o<multi.GetLength(1); o++){

Console.WriteLine(multi[i,o]);

}

}

Console.WriteLine(multi.Length);

Esimerkissä luomme multidimensional arrayn, jonka ensimmäisen arrayn pituus on 2, ja toisen 4. Sitten asetamme nämä arvot. Ensimmäisten aaltosulkeiden väliin tulee yhtä monta aaltosuljetta kuin ensimmäisen arrayn pituus on, ja toisten aaltosulkeiden väliin tulee toisten arrayn pituuden verran arvoja. Tämän jälkeen luomme aluksi forin joka toistuu ensimmäisen arrayn verran, ja heti perään toisen forin joka toistuu toisen arrayn verran. Näin voimme käydä kaikki arvot läpi mitä multidimensional arrayssa on.

Esimerkin lopussa on tulostettu myös multidimensional arrayn pituuden. Kuten huomaat, tämä pituus on koko multidimensional arrayn pituinen, eli toisin sanoen tässä tapauksessa se palauttaa arvon 8. Eli emme voi oikein käyttää sitä for lausekkeessa. Sen sijaan käytämmekin GetLength() lauseketta. Tämän avulla saamme kaikki haluamamme pituudet arraysta asettamalla vain pituuden sijaintinumeron sulkeisiin. Koska meillä on 2 dimensionaalia, niin GetLength(0) palauttaa arvon 2, ja GetLength(1) palauttaa arvon 4.

Multidimensional arrayssa voi olla niin monta ulottuvuutta kuin halutaan. Tällöin vain laitettava multidimensional arrayn luomisvaiheessa enemmän pilkkuja sulkeisiin, ja lisättävä enemmän arvoja. Multidimensional arrayt käyvät kuitenkin hyvin äkkiä hyvin monimutkaiseksi, minkä takia ei kannatakkaan käyttää kuin maksimissaan 3 ulottuvuutta.

Toisto foreach

foreach-lauseke käy läpi kaikki arvot mitkä sille annetaan, yleensä array muodossa. Ei ole väliä onko sille annettu tavallinen array vai multidimensional, foreach käy kaikki sen arvot yksi kerrallaan läpi. Miten foreach rakennetaan on, sen sulkeissa luodaan uusi muuttuja, joka on samantyyppinen kuin kaikki muuttujat sille annetussa listassa. Mikäli listassa on jokin muu arvo, skippaa foreach tämän arvon antamatta siitä virheilmoitusta. Foreach toistaa itseään niin monta kertaa kuin listassa on sopivia muuttujia, ja joka kerta vaihtaa muuttujan arvoa listan muuttujan arvoksi. Mikäli muutamme foreach muuttujan arvoa, asettaa se uuden arvon myös listaan oikeaan kohtaan.

Esimerkki 1:

int mones=0;

int[]lista=new int[]{3,5,7,3,1,3,5,3,4};

foreach(int numero in lista){

        if(numero==3){

                mones++;

}

}

Console.WriteLine(mones);

mones=0;

int[,,] numeroita=new int[,,]{{{3,5,7,3,1,3,5,3,4},{3,5,7,3,1,3,5,3,4},{3,5,7,3,1,3,5,3,4}},{{3,5,7,3,1,3,5,3,4},{3,5,7,3,1,3,5,3,4},{3,5,7,3,1,3,5,3,4}},{{3,5,7,3,1,3,5,3,4},{3,5,7,3,1,3,5,3,4},{3,5,7,3,1,3,5,3,4}}};

foreach(int numero in numeroita){

        if(numero==3){

                mones++;

}

}

Luomme aluksi intin joka on 0, sekä listan joka sisältää vain joitakin lukuja. Tämän jälkeen luomme foreachin, joka aluksi luo intin nimeltä numero, ja asettaa sen arvoksi joka kerta numeron sille annetusta listasta. Tämän jälkeen if-lauseke tarkistaa onko kyseinen numero 3, ja jos on, lisää mones-muuttujaa yhdellä. Tämän jälkeen tulostamme mones-muuttujan ja saamme selville että lista sisälsi neljä numero kolmosta. Tämä sama käydään läpi myös multidimensional arraylla, ja saadaan vastaukseksi että se sisältää 36 numero kolmosta.

Methodit

Nyt päästään vihdoin kiinni hieman syvempiin koodauksen asioihin, eli methodeihin. Tämä myös tarkoittaa, että jos muistatte, tämän tekstin ensimmäisissä kohdissa muutimme vasemmalta asetuksista "Console-kohdan Scriptiksi. Nyt on aika muuttaa se takaisin Consoleksi ja katsoa mitä tämä oikein tarkoittaa

Ohjelman rakenne

 Kun olemme muuttaneet takaisin Console-kohtaan, tulisi ohjelman näyttää tältä:

Esimerkki 1:

using System;        

                        

public class Program

{

        public static void Main()

        {

                Console.WriteLine("Hello World");

        }

}

Kuten tiedämme, using System kertoo mitä kirjastoa ohjelma käyttää. System kirjasto sisältää yleisimmät ohjelman toiminnallisuudet.

Class kertoo että ohjelmamme on olio, ja sen nimi on Program. Olion nimi voi olla mikä tahansa, kunhan se ei sisällä ääkkösiä. Voimme tehdä yhteen ohjelmaan monta eri oliota, jotka viittaavat toisiinsa. Public kertoo että luokka on julkinen, ja muut luokat voivatkin käyttää sitä näin. Tästä kerrotaan kuitenkin tarkemmin myöhemmin olio-kohdassa.

void kertoo että ohjelmamme sisältää methodin Main. Yhdessä oliossa voi olla enemmän kuin yksi methodi. C#-koodi tunnistaa nimen Main, ja suorittaa sen automaattisesti heti ohjelman alussa. Methodit voivat olla minkä tahansa nimisiä, mutta että koodi toimisi oikein, niin tämä ei voi olla muun niminen.

Kun kirjoitetaan ohjelmaa, se kirjoitetaan methodin aaltosulkeiden väliin. Tänne tulee kaikki mitä haluamme ohjelman suorittavan. Toisin sanoen, kaikki tekemämme ohjelmat toimii täysin samalla tavalla kuin tähänkin asti, mutta meidän on vain laitettava ne Main() methodin aaltosulkeiden väliin. Jos haluatte niin voitte kokeilla tätä.

Methodit ovat ohjelman osia, joka on määritelty erikseen koodin, ja joihin pääsee käsiksi milloin ikinä haluaa. Tähän asti olemme perjaatteesa koko ajan käyttäneet yhtä methodia, nimeltä main, johon olemme kirjoittaneet kaikki koodit tähän asti. Nyt koska osaamme jo käyttää monta ohjelmoinnin osa-aluetta, voimme ruveta käyttämään niitä hyödyksi myös methodeissa.

Methodeihin voimme siis kirjoittaa asioita joita joudumme esimerkiksi käyttämään monessa eri paikassa, mutta emme halua että ohjelmassa esiintyy samat 5 riviä koko ajan uudestaan ja uudestaan. Tällöin voimme asettaa kyseiset 5 riviä methodiin, ja vain verrata kyseiseen methodiin tehdäksemme kyseiset asiat. Luomme tavallisen methodin asettamalla classin sisään "void methodinnimi(){}" ja kirjoittamalla aaltosulkeiden sisään tehtävät asiat.

Esimerkki 2:

using System;                                

public class Program

{

        public static void Main()

        {

                while(true){

                        Console.ReadLine()

esimerkki();

                }

        }

        static void esimerkki(){

                Console.WriteLine("Nyt kyllä annoit syötteen…");

}

}

Esimerkissä loimme methodin nimeltä esimerkki, ja aina kun kutsumme methodia, se tulostaa Nyt kyllä annoit syötteen…. Ohjelma kutsuu methodia aina kun käyttäjä antaa syötteen konsoliin. Koska tekemämme ohjelma on pääohjelma, meidän pitää jokaisen methodin eteen lisätä sanat static. Tämä selitetään paremmin myöhemmin objektit kohdassa.

Methodeilla on helppo säästää tilaa ja laittaa useasti samalla kertaa käytetyt koodirivit sinne. Jos kuitenkin määrittelemme muuttujia Main methodissa, emme pääse niihin käsiksi muissa methodeissa. Tämä ei kuitenkaan ole ongelma. Voimme määritellä metodiin sulkeisiin, että kun methodia kutsutaan, sille pitää antaa yksi tietyn tyyppinen muuttuja, jota methodi voi käyttää koodissaan.

Esimerkki 3:

using System;

                                        

public class Program

{

        public static void Main()

        {

                while(true){

                        string sana=Console.ReadLine();

                        tarkista(sana);

                        if(sana.Equals("exit")){

                                break;

                        }

                }

        }

        static void tarkista(String sana){

                int numero;

                if(int.TryParse(sana, out numero)){

                        Console.WriteLine("Annoit pelkän numeron");

                }else{

                        Console.WriteLine("Et antanut pelkkää numeroa...");

                }

        }

}

Koodissa on hyvä esimerkki methodi siitä, jos halutaan pelaajan syöttävän pelkän numerosarjan ohjelmaan. Ohjelma ottaa käyttäjän syötteen, ja tarkistaa methodissa mikäli syöte on muunnettavissa numeroksi. Mikäli on, se tulostaa että käyttäjä antoin numeron.

Nyt osaamme jo luoda methodeja, sekä antaa niille niiden tarvitsemia asioita. Nyt mitä tarvitsemme, on saada jotenki tietoa takaisin pääohjelmaan. Tämä onnistuu helposti. Tähän asti olemme luoneet methodeja käyttämällä sanaa void ennen methodin nimeä, mikä tarkoittaa että methodi on oma ohjelman osansa. Mutta, jos laitamme void sanan tilalle minkä tahansa muuttujan tyypin, saa methodi tehtäväkseen palauttaa pääohjelmaan sen tyyppisen muuttujan arvo. Tällöin methodin on aina palautettava halutun tyypin arvo takaisin.

Esimerkki 4:

using System;

                                        

public class Program

{

        public static void Main()

        {

                Console.WriteLine("Anna numero");

                while(true){

                        string sana=Console.ReadLine();

                        int numero=tarkista(sana);

                        if(numero!=-1){

                                break;

                        }

                }

                Console.WriteLine("Haluatko jatkaa? y/n");

                while(true){

                        if(haluatko(Console.ReadLine())){

                                break;

                        }

                }

                Console.WriteLine("hyvä hyvä, karkasit loopista.");

        }

        static int tarkista(String sana){

                int numero;

                if(int.TryParse(sana, out numero)){

                        return numero;

                }else{

                        Console.WriteLine("Et antanut pelkkää numeroa...");

                        return -1;

                }

        }

        static bool haluatko(string sana){

                if(sana.Equals("n")){

                        return true;

                }else{

                        return false;

                }

        }

}

Mitä ohjelmamme tekee, on se aluksi pyytää käyttäjältä numeroa. Kun käyttäjä antaa syötteen, ohjelma lähettää sen menemään tarkista methodiin, joka aluksi tarkistaa onko syöte numero. Jos on, se palauttaa syötteestä saadun numeron, jos ei, se palauttaa -1. Methodista saatu vastaus tallennetaan omaan muuttujaansa, ja tarkistetaan onko se hyväksyttävä numero. jos on, ohjelma jatkaa seuraavaan esimerkkiin. Ohjelma pyytää käyttäjältä haluaako tämä jatkaa. Kun käyttäjä antaa syötteen, se lähetetään haluatko methodiin, jossa ohjelma tarkistaa onko sana n. Jos on, ohjelma lähettää true-arvon takaisin, jolloin ohjelma pääsee if-lauseen sisään, ja karkaa loopista. Jos käyttäjä antaa jotain muuta, methodi palauttaa false ja ohjelma pysyy loopissa.

Methodit voivat olla saman nimisiä, mutta silloin niille annetut muuttujien arvot on oltava eri muotoisia. Meillä voi siis olla kaksi saman nimistä muuttujaa, joista toinen ei halua ohjelmalta mitään tietoa, ja toinen pyytää int muuttujaa, mutta molemmat eivät voi pyytää int muuttujaa, tai olla pyytämättä mitään. Saman nimiset methodit ovat hyödyllisiä siksi, koska niiden avulla voidaan luoda samankaltaisia methodeja ilman että annetaan kaikki tiedot. Oletetaan että käyttäjä on kirjautumassa peliin. Jos käyttäjä antaa käyttäjänimen, nimi asetetaan muuttujaan ja sitä käytetään pelissä. Mikäli käyttäjä taas jättää käyttäjänimen tyhjäksi, voidaan hänelle asettaa default nimi. Näin saamme saman asian tehtyä kahdella eri tavalla, siten että methodille annetaan string muuttuja jossa on käyttäjänimi, ja siten, että methodille ei anneta mitään, että se luo randomisti käyttäjänimen pelaajalle.

Esimerkki 5:

using System;

                                        

public class Program

{

        public static void Main()

        {

                kertoja(4);

                kertoja(5,5);

                kertoja(3,2,3);

        }

        static void kertoja(int numero1){

                tulostaja(numero1);

        }

        static void kertoja(int numero1,int numero2){

                tulostaja(numero1*numero2);

        }

        static void kertoja(int numero1,int numero2,int numero3){

                tulostaja(numero1*numero2*numero3);

        }

        static void tulostaja(int numero){

                for(int i=1; i<=numero; i++){

                        Console.WriteLine(i+" Apple, A-A-A");

                }

                Console.WriteLine();

        }

}

Esimerkissä luomme kolme samannimistä methodia, jotka kaikki ottavat eri määrän numeroita. Methodit ottavat saamansa numerot, jonka jälkeen ne kertovat ne toisillaan ja lähettävät tulostaja methodin, joka tulostaa niin monta kertaa kuin kerrottu loppuluku oli.

Methodit ovatkin erittäin kätevä työväline asioiden tarkistamiseen, ja pitämään koodi siistinä ja luettavana.

Olio

Nyt pääsemmekin c#-ohjelmoinnin ytimeen, eli olioihin. c# on olio-ohjelmointikieli, ja nimitys tulee siitä että se käyttää hyödykseen olioita. Oliot ovat ikäänkuin ohjelmoijan itse luomia muuttujia, jotka sisältävät kaikkia haluamiamme muuttujia. Ohjelma sisältääkin jo yhden olion, nimeltä Program. Se ei kuitenkaan käyttäydy kuin olio, koska se sisältää Main-methodin, minkä takia pystymme tekemään siellä ohjelmointia. Luomme olion helposti aluksi kirjoittamalla class olionnimii. Tämän jälkeen tulee aaltosulkeet, ja olemme luoneet uuden olion. Voimme luoda classiin uusia muuttujia, jos haluamme, sekä erilaisia methodeja. Jotta pääsemme olioon käsiksi ohjelmassa, meidän on luotava se ohjelmassa samalla tavoin kuin mikä tahansa muukin muuttuja.

Esimerkki 1:

using System;

                                        

public class Program

{

        public static void Main()

        {

                ajoneuvo auto=new ajoneuvo("auto",4,5);

                ajoneuvo mopo=new ajoneuvo("mopo",2,2);

                ajoneuvo mopoauto=new ajoneuvo("mopoauto",4,2);

                auto.tulosta();

                mopo.tulosta();

                mopoauto.tulosta();

        }

}

public class ajoneuvo

{

        string nimi;

        int renkaat;

        int matkustajat;

        public ajoneuvo(string nimia, int renkaita, int matkustajia){

                nimi=nimia;

                renkaat=renkaita;

                matkustajat=matkustajia;

        }

        public void tulosta(){

                Console.WriteLine(nimi+"ssa renkaita on yhteensä "+renkaat+", ja matkustajia mahtuu "+matkustajat);

        }

}

Esimerkissä onkin paljon uutta. Aluksi loimme objektin nimeltä ajoneuvo, ja annoimme sille muuttujat nimi, renkaat ja matkustajat. Tämän jälkeen meillä on luomismethodi, jonka nimi pohjautuu aina siitä mikä objektin nimi on. Koska meidän objektin nimi on ajoneuvo, on luomismethodin nimi myös ajoneuvo. luomismethodi käydään läpi aina kun objekti luodaan pääohjelmassa, ja se vaikuttaa vain luotuun objektiin. Ohjelmassa myös annamme luomismethodille arvoja, jotka methodi sitten asettaa oikeille kohdille.

Tämän jälkeen suoritamme kaikista luoduista objekteista läpi tulosta methodin, joka on määritelty objektissa tulostamaan kaikki ajoneuvon tiedot konsoliin. Jos testasitte esimerkkiä, näette että konsoliin on tosiaan tulostettu kaikkien ajoneuvojen tiedot, jotka koodissa niihin määrittelimme. Koska objektit tulostavat vain omat tietonsa, eivätkä ne koskekkaan toistensa tietoihin ellei niin erikseen määritellä




Tämä materiaali on tuotettu Euroopan maaseudun kehittämisen maatalousrahaston tuella