Oefeningen H16
Last updated
Was this helpful?
Last updated
Was this helpful?
Voeg een filter toe aan de dierentuin applicatie uit :
Filter praten: er wordt gevraagd welke dieren moeten praten (Koe
, Slang
of Varken
) vervolgens zullen enkel die dieren praten (tip: "is" operator).
Implementeer de Equals
methode (via override
) in je Pokemon
klasse. Twee Pokémon zijn dezelfde indien volgende zaken gelijk zijn:
Basis stats
Naam
Level
Gebruik compositie én overerving om een klasse Huis
te voorzien van enkele kamers, waarbij iedere kamer een klasse op zich is (denk aan BadKamer
, Salon
, etc). Alle kamers erven over van de klasse Kamer
.
Iedere kamer heeft een oppervlakte (in vierkante meter), een naam en prijs. Standaard is de prijs van een kamer 400euro, maar mogelijke child-klassen zullen deze property soms overriden. De Prijs is een readonly property (zonder setter, en heeft ook geen achterliggende instantievariabele).
Maak minstens volgende klassen:
Badkamer: kost 500 euro
Gang: kost 10euro per vierkante meter dat deze kamer groot is
Salon: kost 300 euro indien er geen schouw aanwezig is (via bool
bijhouden) anders 500euro
De klasse Huis
heeft een lijst van kamers. De klasse heeft ook een methode BerekenPrijs
die de totale prijs van het huis berekent gebaseerd op de prijzen van iedere kamer in de lijst.
Test je klasse door enkele huizen te maken en er enkele kamers in te plaatsen (bepaal zelf hoe je de kamers aan het huis toevoegt: via methode, constructor, etc) en vervolgens de prijs ervan te tonen.
Ontwerp een applicatie waarin diverse typen vliegende voertuigen meedoen aan een luchtvaartshow en hun unieke vlieg‑gedrag demonstreren. In deze opgave werk je met inheritance, polymorfisme, het base‑keyword, de Dictionary‑klasse en statische methoden.
Basisklasse Vliegtuig:
Maak een basisklasse Vliegtuig
met een property ModelNaam
en een constructor die deze initialiseert.
Implementeer een virtuele methode Vlieg()
die een standaardbericht naar de console schrijft (bijvoorbeeld "Het vliegtuig [ModelNaam] stijgt op.").
Voeg een static instantievariabele toe: een Dictionary<string, Vliegtuig>
waarin alle aangemaakte vliegtuigobjecten geregistreerd worden (gebruik de modelnaam als sleutel).
Implementeer een statische methode, ToonVliegtuigenRegister()
, die alle geregistreerde objecten uit de dictionary uitleest en hun details (zoals modelnaam en type voertuig) weergeeft op het scherm.
Subklassen:
Raket
:
Laat Raket overerven van Vliegtuig
.
Overschrijf de methode Vlieg()
zodat een uniek bericht wordt weergegeven, namelijk "De raket [ModelNaam] schiet de ruimte in!"”"
Helikopter
:
Laat Helikopter
erven van Vliegtuig
en voeg een extra property toe, RotorSnelheid
.
Overschrijf de methode Vlieg()
zodat eerst het standaardgedrag van Vliegtuig wordt aangeroepen (met base.Vlieg()) en daarna een extra bericht wordt getoond met de huidige rotor snelheid (namelijk "De helikopter [ModelNaam] draait met een rotor snelheid van [RotorSnelheid] RPM.").
Maak in het hoofdprogramma meerdere objecten van de types Vliegtuig, Raket en Helikopter.
Zorg ervoor dat elk nieuw vliegtuigobject automatisch wordt toegevoegd aan het statische dictionary-register ( via de constructor).
Roep ten slotte de statische methode ToonVliegtuigenRegister()
aan om een overzicht van alle geregistreerde voertuigen te tonen.
Voorzie een Teken
methode die een huis kan tekenen, gebruikmakend van de Teken
-methoden van de kamers. Hiervoor dien je een X
en Y
coördinaat per , alsook lengte en breedte per huis én kamer te hebben zodat je deze op de juiste plekken op het scherm kan plaatsen.
Kan je ervoor zorgen dat een architect nieuwe kamers kan toevoegen en verwijderen?
Kan je de manager aanpassen zodat deze niet met card1
en card2
werkt, maar met een List<Card>
.
Voeg zelf enkele kaarten toe en verzin ook enkele afgeleide Card
-types , bv Land
en Artifact
.
Bordspelen zoals Ganzenbord of Monopoly zijn goede oefeningen om je polymorfisme mee te oefenen. Het speelbord is niet meer dan een lijst van objecten, met ieder vakje een object in die lijst. Echter, sommige vakjes kunnen meer dan andere en je lijst bevat dus objecten van verschillende child-klassen die allemaal overerven van een basisklasse Vakje
of iets dergelijks. Volgende opgave uit een oud examen toont dit. Kan je deze oefening maken?
De kinderen van meneer Dams en Van Camp spelen graag Ganzenbord. Laatst toen we speelden vroegen ze zich af of mijn studenten eigenlijk ganzenbord zouden kunnen programmeren? "Uiteraard!" antwoordde meneer Dams. "Weliswaar een vereenvoudigde versie, maar toch. Ze zouden dat wel kunnen, ja", vulde hij fier aan.
En hier zit je nu dus, opgescheept met het programmeren van de basisfunctionaliteit van ganzenbord voor 1 speler (geen flauw benul hoe ganzenbord werkt? Geen probleem! Alles wordt duidelijk doorheen de opgave!)
Ganzenbord, the single player edition, wordt gespeeld door één speler die moet proberen zo ver mogelijk te geraken op een traject van vakjes. Sommige vakjes doen iets met de speler wanneer deze op het vakje belandt (bijvoorbeeld een stapje vooruit), anderen doen niets.
Het bord wordt aan de start van ieder spel random aangemaakt. De speler moet een dobbelsteen werpen om te weten hoeveel stappen z'n pion vooruit zal gaan. De speler verdient punten hoe verder hij geraakt.
Dobbelsteen
Deze eenvoudige klasse heeft een statische methode Rol
en geeft een willekeurig getal, namelijk 1, 2 of 3.
Speelvakje
Het spelbord zal opgebouwd worden door een reeks van speelvakjes. Daarom maken we eerst dit vakje.
Een vakje wordt gedefinieerd door:
Een read-only int-property BeweegVakjes
(met private set): deze eigenschap geeft aan hoeveel vakjes vooruit (positief) of achteruit (negatief) de speler zal gaan als op dit vakje wordt geland.
Een default constructor die de BeweegVakjes
instelt op een waarde als volgt:
30% kans op +1 of +2
20% kans op -1 of -2
50% kans op 0
Een virtuele methode ToonVakje
dat op de huidige locatie van de cursor in de console de BeweegVakjes
waarde van het vakje op het scherm schrijft. Indien de waarde positief of 0 is, toon je dit met een + voor. Bijvoorbeeld: +2 of +0. Een negatief toon je met de - , zoals -2.
Ganzenbord
Een ganzenbord heeft altijd een lijst,SpeelVakjes
van 10 Speelvakje
-objecten. Deze zijn niet publiek zichtbaar.
Een ganzenbord heeft:
Een default constructor die de lijst vult met 10 Speelvakje
-objecten.
Een instantievariabele pionIndex
die aangeeft op welke vakje in de lijst de speler zich momenteel bevindt.
Een autoproperty HuidigeScore
die standaard op 0 staat.
Een methode BeweegPion
die een int
als parameter aanvaardt en een bool
teruggeeft. De werking van de methode wordt verderop uitgelegd.
Een methode TekenBord
die het ganzenbord op het scherm toont zoals verderop uitgelegd.
BeweegPion()
Deze methode zal de speler voortbewegen op het bord en laten weten of de speler het einde heeft gehaald heeft of niet.
De speler kan een getal (het getal dat hij met de dobbelsteen verderop zal rollen) aan deze methode meegeven zodat het volgende gebeurt:
De pionIndex
wordt verhoogd met het getal dat wordt meegeven, vervolgens:
Indien pionIndex
hierdoor hoger wordt dan 9 en dus voorbij het laatste vakje wordt gegaan, dan wint de speler en wordt eerst de HuidigeScore
met 10 verhoogd en wordt vervolgens true
teruggegeven om aan te geven dat de speler gewonnen is.
Indien pionIndex
eindigt op een getal 8 of lager, dan gebeurt het volgende:
In de lijst van SpeelVakje
-objecten wordt gekeken op welk vakje de speler is aangekomen. De BeweegVakjes
waarde van dit vakje wordt bijgeteld of afgetrokken van pionIndex
. Dit wordt de nieuwe locatie van de speler. Er gebeurt niets meer na het belanden op dit nieuwe vakje (ook al is het een vakje waar vooruit of achteruit zou moeten gegaan worden).
De methode geeft false
terug indien pionIndex
terug een getal tussen 0 en 8 wordt, anders true
indien hoger dan 8 (hij is dan gewonnnen-. Indien de speler op een index onder 0 belandt wordt false
teruggegeven, wordt de score met 10 verlaagd én wordt de pionIndex
finaal op 0 teruggezet (reset), ongeacht waar de speler op negatief belandde.
TekenBord()
Deze methode zal de 10 vakjes naast elkaar op het scherm visualiseren door de lijst SpeelVakjes
te overlopen en van ieder object de ToonVakje
methode aan te roepen.
Vervolgens wordt de pionIndex
locatie gebruikt om dat vakje op het scherm te overschrijven met een 'T'
Indien de speler dus op index 3 (het vierde vakje) zit van een willekeurig bord, dan kan de output zijn:
Dus het eerste vakje heeft waarde -1, het volgende 2, het derde 1, het vierde zien we niet want daar staat het mannetje (het was was blijkbaar een negatief vakje) en zien we een T, dan krijgen we twee vakjes met waarde 0.
De main spelloop werkt als volgt:
Een nieuw Ganzenbord
object wordt aangemaakt.
Een loop wordt gestart die blijft duren tot de speler aan het einde geraakt. Deze loop doet het volgende:
Het scherm wordt leeggemaakt.
Het spelbord wordt getoond mbv van de TekenBord
methode.
Een nieuw getal wordt met de Rol
methode van de dobbelsteen gerold. Dit getal wordt op het scherm getoond , onder het spelbord Je rolde 2
De loop pauzeert nu tot de gebruiker op enter duwt.
Het gerolde getal wordt aan de BeweegPion
-methode meegeven en het resultaat van die methode wordt gebruikt om te bepalen of de loop nog een iteratie zal doen of niet.
Finaal wordt de HuidigeScore
van de speler getoond.
Voeg volgende uitbreidingen toe nadat je een werkend geheel hebt.
Maak een klasse KleurVakje
dat overerft van SpeelVakje
Dit vakje doet alles wat een gewoon vakje doet, het zal enkel de ToonVakje
method aanvullen zodat het huidige vakje een rode achtergrond met witte letters heeft indien de BeweegVakjes
waarde negatief is. Anders groen met zwarte letters bij positieve of waarde 0.
Aan de start van het spel wordt aan de speler gevraagd of hij de kleuren of zwartwit versie van het spel wil spelen.
Voeg een overloaded constructor aan GanzenBord
toe die een bool aanvaardt. Deze bool geeft aan of de speler een kleuren of klassiek zwart/wit speelbord wil gebruiken. Afhankelijk van deze parameter wordt dan het juiste soort vakjes in de ``SpeelVakjes`lijst geplaatst.
Bij het opstarten van het spel vraag je aan de gebruiker of hij de kleur of de zwartwit versie van Ganzenbord wil spelen.
Vanaf nu kan je de variabele del
als object gebruiken én aanroepen:
Of zelfs doorgeven als parameter
Kan je de hele tekst volgen en de gemaakte finale oefening uitbreiden naar een echte "applicatie"?
Bekijk de vraag en het goedgekeurde antwoord op
Begin aan het all-in-project "". Stop aan de sectie interfaces (die je pas in volgend hoofdstuk zult leren gebruiken). Je zal in dit project dingen herkennen die je eerder al in de "Een eigen huis" oefening hebt moeten maken.
Tot hiertoe hebben we altijd gepraat over enerzijds objecten, en anderzijds methoden. Twee zaken die wel een relatie met elkaar hebben (een klasse kan methoden hebben, een methode kan objecten als parameter of return type hebben). Maar wat als ik je vertel dat je ook methoden als objecten kunt gebruiken. Het concept "delegate" laat ons toe om methoden als parameters doorheen een applicatie door te geven. Hier een droog, maar duidelijk voorbeeld ()
Omdat delegates al wat oldschool zijn geworden, heeft .NET ook al vele jaren wat meer generieke (en dus bruikbaardere) versies hiervan, namelijk Action<T>
en Func<T>
. De werking hiervan legt deze gekende man stap voor stap .