Oefeningen H10
Meetlat
Doel: Zet een lengte om naar verschillende eenheden met behulp van properties.
Specificaties:
Klassenaam:
MeetlatProperty (Input):
BeginLengte(type:double): Write-only property om de lengte in meter in te stellen.Opslag: Sla deze waarde intern op in een private variabele (bv.
_lengte).
Properties (Output - ReadOnly): De volgende properties geven de lengte terug, omgerekend naar de gevraagde eenheid:
LengteInM
double
Geeft _lengte terug.
LengteInCm
double
_lengte * 100
LengteInKm
double
_lengte / 1000
LengteInVoet
double
_lengte * 3.2808
Voorbeeldgebruik:
Meetlat mijnLat = new Meetlat();
mijnLat.BeginLengte = 2; // We stellen in op 2 meter
Console.WriteLine($"{mijnLat.LengteInM} meter is {mijnLat.LengteInVoet} voet.");Kleur mixer (Essential)
Doel: Meng twee kleuren door het gemiddelde te nemen van hun RGB-waarden.
Specificaties:
Klassenaam:
KleurProperties:
Rood(int)Groen(int)Blauw(int)
Methode:
MengKleur(Kleur andereKleur)(void)
Werking (MengKleur): Wanneer MengKleur wordt aangeroepen, veranderen de eigenschappen van de huidige kleur (this). De kleur die als parameter wordt meegegeven verandert niet.
Gebruik deze formules (gehele deling):
Nieuw Rood =
(Huidig Rood + Ander Rood) / 2Nieuw Groen =
(Huidig Groen + Ander Groen) / 2Nieuw Blauw =
(Huidig Blauw + Ander Blauw) / 2
Voorbeeldgebruik:
Pokémon (Essential)
We gaan een programma schrijven dat ons toelaat enkele basis-eigenschappen van specifieke Pokémon te berekenen terwijl ze levellen. Nadruk van deze oefening is het juist gebruiken van properties. Bekijk de cheat sheet bij twijfel.
Hoe Pokémon werken
Korte uitleg over Pokémon en hun interne werking: Iedere Pokémon wordt uniek gemaakt door z’n base-stats, deze zijn voor iedere Pokémon anders. Deze base-stats zijn onveranderlijk en blijven dus doorheen het hele leven van een Pokémon dezelfde. Je kan de base-stats als het dna van een Pokémon beschouwen.
De full-stats zijn echter de stats die de effectieve ‘krachten’ van een Pokémon bepalen in een gevecht. Deze stats worden berekend gebaseerd op de vaste base-stats en het huidige level van de Pokémon. Hoe hoger het level van de Pokémon, hoe hoger dus zijn full-stats.


De Pokémonopdracht
Maak een consoleapplicatie met daarin een klasse Pokémon die de werking zoals hierboven beschreven heeft:
Base-stats
De base-stats worden als int bewaard. Maak voor al deze basis-eigenschappen full properties, namelijk:
HP_BaseAttack_BaseDefense_BaseSpecialAttack_BaseSpecialDefense_BaseSpeed_Base
Extra stats
Voorts wordt een Pokémon ook gedefinieerd door z’n Naam (string), Type (string, bv. grass & poison) en Nummer (int), maak hiervoor auto properties aan.
Met
Nummerbedoelen we de Pokémon index die je in de Pokédex kunt opzoeken. Zo heeft Bulbasaur nummer 1 en Pikachu heeft 25.
Level
Voeg een fullproperty Level toe (int). Deze heeft een public get, maar een private setter.
Voeg een publieke methode VerhoogLevel toe. Deze methode zal, via de private setter van Level, het level van de Pokémon met 1 verhogen. Deze methode heeft géén parameters nodig en return'd niets.
Statistieken
Voeg 2 read-only properties toe (enkel get, géén set) genaamd Average (double) en Total (int):
De
Average-property geeft het gemiddelde van de 6 base-stats terug, dus(HP_Base + Attack_Base + Defense_Base + SpAttack_Base + SpDefense_Base +Speed_Base)/6.0.De
Total-property geeft de som terug van de 6 basestats. Daar de base stats niet evolueren met het level veranderen dusAverageenTotalook niet van zodra de base-stats werden ingesteld, toch mag je beide statistieken steeds herberekenen in de get.
Level-gebaseerde stats
De eigenschappen van de Pokémon die mee evolueren met het level gaan we steeds als read-only properties van het type int implementeren:
Voeg een read-only property
HP_Fulltoe om de maximum health voor te stellen. Deze wordt berekend als volgt:( ( (HP_Base + 50) * Level) / 50) + 10wanneer de get wordt aangeroepen.Voeg voor iedere ander base-stat een XX_Full readonly property toe . Dus
Defense_Full,Speed_Full, etc. Ook deze properties zijn readonly. Deze stats worden berekend als volgt:( (stat_Base*Level) / 50 ) + 5. Attack_Full bijvoorbeeld wordt dus berekend als:( (Attack_Base * Level) / 50) + 5
Maak enkele Pokémon
Kies enkele Pokémon uit deze lijst en maak in je Main enkele Pokémon-objecten aan met de juiste eigenschappen.
Opgelet: Je dient dus enkel de base stats in te stellen. Alle andere zaken zijn op deze stats en het huidige level van de Pokémon gebaseerd.
Toon aan dat de Average, Total, HP en andere stats correct berekend worden (controleer in de tabel op de voorgaande url).
Level-up tester
Maak een kleine loop die je toelaat om per loop een bepaalde Pokémon z’n level met 1 te verhogen en vervolgens toon je dan z’n nieuwe stats.
Test eens hoe de stats na bv 100 levels evolueren. Je zal zien dat bepaalde stats pas na een paar keer levelen ook effectief beginnen stijgen.
Deel 2: De Pokémontester
Het is een heel gedoe om telkens manueel de informatie van een Pokémon op het scherm te outputen. Voeg een methode public void ShowInfo() toe aan je Pokémon klasse. Deze methode zal alle relevante informatie (alle properties!) in een mooie vorm op het scherm tonen, bv:
Maak nu een nieuwe console-applicatie genaamd "Pokémon Tester":
Voeg je
Pokémon-klasse-bestand toe aan dit project. Verander de "namespace" van dit bestand naar de namespace van je nieuwe console-applicatie .Maak enkele Pokémon objecten aan en stel hun base stats in.
Schrijf een applicatie die aan de gebruiker eerst de 6 base-stats vraagt. Vervolgens wordt de Pokémon aangemaakt met die stats en worden de full-stats aan de gebruiker getoond.
Vraag nu aan de gebruiker tot welke level de Pokémon moet gelevelled worden. Roep zoveel keer de LevelUp-methode aan van de Pokémon. (of kan je dit via een parameter doorgeven aan
LevelUp?!)Toon terug de full-stats van de nu ge-levelde Pokémon.
Deel 3: Pokémon-battler
Pokémon generator
Maak een methode met volgende signatuur: static Pokémon GeneratorPokémon(). Plaats deze methode niet in je Pokémon-klasse, maar in Program.cs.
Deze methode zal telkens een Pokémon aanmaken met willekeurige base-stats. Bepaal zelf hoe je dit gaat doen.
Battle tester
Voeg een methode met volgende signatuur toe aan je hoofdprogramma (dus ook weer in Program.cs): static int Battle(Pokémon poke1, Pokémon poke2).
De methode zal een getal teruggeven dat aangeeft welke van de twee Pokémon een gevecht zou winnen. 1= poke1, 2 = poke2, 0 = gelijke stand.
Controleer steeds of 1 of beide van de meegegeven Pokémon niet null zijn. Indien er 1 null is, dien je een Exception op te werpen.
Bepaal zelf hoe Pokémon vechten (bv. degene met de hoogste average van full-stats). Werk niet enkel met de base-stats, daar deze constant zijn. Het is leuker dat het level ook een invloed heeft (maar ga niet gewoon het level vergelijken).
Alles samen
Genereer 2 willekeurige Pokémon met je generator en laat ze vechten met je battle-methode. Toon wat output aan de gebruiker zodat hij ziet wat er allemaal gebeurt (en gebruik zeker de ShowInfo methode om dit snel te doen). Kan je dit in een loop zetten en wat leuker maken met Pokémon die telkens levelen als ze een gevecht winnen?!
Meer info
Voor de volledige info over Pokémon hun stats. Klik hier.
Bankmanager 2 (Essential)
Breid de bankmanager oefening uit het vorige hoofdstuk uit.
Nieuwe Methoden (in Program.cs):
SimuleerOverdracht(Rekening r1, Rekening r2)(void)Loop: Herhaal 5 keer:
Kies een willekeurig bedrag tussen 1 en 100 euro.
Stort dit bedrag van de ene rekening naar de andere.
Wissel per iteratie om wie verzender en wie ontvanger is (r1 -> r2, dan r2 -> r1, etc).
CreeerTienerRekening(string klantNaam)(Rekening)Maak een nieuw
Rekeningobject aan.Stel de naam in op
klantNaam.Zorg dat de balans start op 50.
Retourneer dit nieuwe object.
Project: SpaceCommand (Combined Essential)
Doel Deze opdracht combineert alle concepten van dit hoofdstuk (Properties, Methoden, Statics, Referenties vs Copies) in één grote simulatie. Indien je de Pokémon-opdracht helemaal hebt gemaakt, dan heeft het niet zoveel nut om ook deze te maken.
Scenario: Je bent de software-architect van de Aardse Vloot. Je moet een systeem ontwerpen om ruimteschepen te beheren, upgrades te geven en gevechtssimulaties uit te voeren tegen de buitenaardse dreiging.
Deel 1: Het Ruimteschip
Ontwerp de klasse RuimteSchip.
1. Eigenschappen (Properties):
Identificatie:
Naam(string): De naam van het schip (bv. "USS Enterprise").Kapitein(string, private set): De naam van de bevelhebber. Deze kan enkel ingesteld worden via een methodeWisselKapitein(string nieuweKapitein).
Basisstatistieken (Base Stats):
Deze worden bij de bouw van het schip vastgelegd (in de main stel je ze in, daarna blijven ze conceptueel vast, hoewel we nog geen constructors gebruiken).
RompSterkte(int): 0-100.SchildKracht(int): 0-100.VuurKracht(int): 0-100.
Status:
Ervaring(int): Het level van de bemanning. Start standaard op 0.Schade(int): Hoeveel schade het schip heeft opgelopen. Start op 0.
2. Berekende Eigenschappen (Read-Only Properties):
IsKapot(bool): GeefttruealsSchadegroter dan of gelijk is aanRompSterkte.TotaleKracht(double): Een graadmeter voor de gevechtswaarde.Formule:
(VuurKracht * Ervaring) + (SchildKracht * 0.5).
3. Methoden:
Onderhoud(): ZetSchadeterug op 0 en toont: "Schip [Naam] is volledig hersteld.".TrainBemanning(): VerhoogtErvaringmet 1.ToonRapport(): Toont een volledig overzicht van het schip (Naam, Kapitein, Stats, Kracht, Status) in de console.
Deel 2: De Vloot Manager (Program.cs)
1. De Scheepswerf (Generator)
Maak in je Program klasse een static methode MaakWillekeurigSchip(string naam).
Deze methode maakt een nieuw
RuimteSchipaan.De stats (
Romp,Schild,Vuur) worden willekeurig bepaald (Random 10-100).De kapitein wordt ingesteld op "Onbekend".
Het schip wordt geretourneerd.
2. De Simulator (Methods & References) Maak een static methode SimuleerGevecht(RuimteSchip s1, RuimteSchip s2).
Null-check: Controleer eerst of
s1ofs2nullzijn. Indien ja: toon een foutmelding en stop.Logica:
Bereken de
TotaleKrachtvan beide schepen.Het schip met de laagste kracht verliest.
Gevolgen:
Het verliezende schip loopt schade op:
Schadeverhoogt met 20.Het winnende schip krijgt ervaring: Roep
TrainBemanning()aan.Toon een spannend verslag in de console.
3. De Garage (Object wijziging) Maak een methode PimpMijnSchip(RuimteSchip schip).
Deze methode accepteert een schip-object.
In de methode:
Zet de
VuurKrachtop 100.Zet de
SchildKrachtop 100.Let op: Omdat
RuimteSchipeen reference type is, zal deze wijziging zichtbaar zijn buiten de methode! Toon dit aan in je Main.
Deel 3: Het Scenario (Main)
Schrijf nu een Main programma dat alles samenbrengt:
Gebruik de
MaakWillekeurigSchipom twee schepen te genereren: "De Voyager" en "De Millenium Falcon".Zet voor beide schepen een kapitein ("Janeway" en "Solo").
Toon de rapporten van beide schepen.
Laat ze vechten (
SimuleerGevecht).Toon de rapporten opnieuw (zie je de schade en ervaring?).
Stuur de verliezer naar de garage (
PimpMijnSchip).Laat ze nog eens vechten. (De verliezer zou nu moeten winnen met zijn upgrades).
Extra Uitdaging: Wat als je een schip "kloneert"? RuimteSchip s3 = s1;. Pas s3 aan (bv. andere naam). Toon nu s1 opnieuw. Wat merk je? (Dit demonstreert dat variabelen slechts verwijzingen zijn naar hetzelfde object in het geheugen).
Last updated
Was this helpful?