[Prog] Variabele i gebruiken bij objecten

Forum van 1ste Bachelor Informatica.

Moderator: Praesidium

Glenn
Posts: 280

[Prog] Variabele i gebruiken bij objecten

Post#1 » Wed Feb 04, 2009 2:46 pm

Code: Select all

PROCEDURE (dobbelsteen : DobbelSteen) Gooi*(VAR aantalpogingen : INTEGER; aantaldobbelstenenherwerpen : INTEGER; 
dobbelstenenherwerpen : ARRAY 5 OF INTEGER);

VAR
randomgetal : REAL;
i : INTEGER;

BEGIN
IF aantalpogingen <= 2 THEN
IF aantalpogingen = 0 THEN
FOR i := 1 TO 6 DO
randomgetal := RandomNumbers.Uniform();
IF randomgetal < 0.2 THEN
dobbelsteen^.i := 1;
ELSIF randomgetal < 0.4 THEN
dobbelsteen^.i := 2;
ELSIF randomgetal < 0.6 THEN
dobbelsteen^.i := 3;
ELSIF randomgetal < 0.8 THEN
dobbelsteen^.i := 4;
ELSE
dobbelsteen^.i := 5;
END;
END;
INC(aantalpogingen);
ELSE
FOR i := 0 TO (aantaldobbelstenenherwerpen-1) DO
randomgetal := RandomNumbers.Uniform();
IF randomgetal < 0.2 THEN
dobbelsteen^.dobbelstenenherwerpen[i] := 1;
ELSIF randomgetal < 0.4 THEN
dobbelsteen^.dobbelstenenherwerpen[i] := 2;
ELSIF randomgetal < 0.6 THEN
dobbelsteen^.dobbelstenenherwerpen[i] := 3;
ELSIF randomgetal < 0.8 THEN
dobbelsteen^.dobbelstenenherwerpen[i] := 4;
ELSE
dobbelsteen^.dobbelstenenherwerpen[i] := 5;
END;
END;
INC(aantalpogingen);
END;
ELSE
OutExt.String("U hebt maar drie pogingen");
END;
END Gooi;
Met bovenstaande methode wil ik een randomgetal geven aan de 5 elementen (INTEGERs) van de klasse DobbelSteen. Nu denk ik niet dat dit gaat werken omdat ik in mijn code o.a. verwijs naar "dobbelsteen^.i := 1; ". De i waar de pointer naar wijst zou een variabele i moeten zijn die door de FOR lus verandert, is dit mogelijk in Oberon? Als dit niet mogelijk is zal ik dus wel heel wat extra schrijfwerk moeten doen.

Groetjes,
Glenn

User avatar
Tom
Posts: 602

Post#2 » Wed Feb 04, 2009 3:56 pm

Eens zien...


Voor wat het doet lijkt me de procedure vrij lang, het is naar later de bedoeling toe om procedures zo kort mogelijk te houden. (Ze zijn dan ook efficienter als ze veel gebruikt moeten worden)

Wat jouw code lang maakt is de verschillende condities, zo kan je dobbelsteen^.i toewijzen aan 1 plus de afronding van Uniform() maal 5. Zo krijg je steeds een waarde van 1 tot en met 6 met maar één regel te moeten gebruiken.



Ik overloop even je tekst want het is niet geheel duidelijk waar je heen wil...
Met bovenstaande methode wil ik een randomgetal geven aan de 5 elementen (INTEGERs) van de klasse DobbelSteen.
Er worden 5 willekeurige getallen aan de elementen van de array in je klasse DobbelSteen gegeven in de tweede FOR lus.
Nu denk ik niet dat dit gaat werken omdat ik in mijn code o.a. verwijs naar "dobbelsteen^.i := 1; ".
Daarmee zet je een enkele variabele in je klasse op die willekeurige waarde.
De i waar de pointer naar wijst zou een variabele i moeten zijn die door de FOR lus verandert, is dit mogelijk in Oberon? Als dit niet mogelijk is zal ik dus wel heel wat extra schrijfwerk moeten doen.
Dit begrijp ik niet goed, kan je uitleggen wat de bedoeling van de functie is?
Hier is documentatie belangrijk voor. En veel schrijfwerk gaat volgens mij niet nodig zijn. :wink:


Met vriendelijke groeten

Tom

User avatar
racekakje
WOZ
Posts: 740

Post#3 » Wed Feb 04, 2009 10:59 pm

Kunde ni beter ne setter maken
en iets in den trend van Dobbelsteen.Set(i, getal).

Da ga sowieso werken en dan kunde ni aan de velden van Dobbelsteen, wat eigenlijk niet slecht is..

User avatar
Shinta
WOZ
Posts: 1122

Post#4 » Wed Feb 04, 2009 11:00 pm

Kzou die procedure precies wat herwerken door te vermenigvuldigen met 5, vervolgens tel je 1 bij je berekening op en laat je het kommagedeelte vallen, dus i.p.v.

Code: Select all


randomgetal := RandomNumbers.Uniform();
IF randomgetal < 0.2 THEN
dobbelsteen^.i := 1;
(* REST VAN IF *)
doe je

Code: Select all


dobbelsteen^.i := DROPFRACTIONALPART(RandomNumbers.Uniform() * 5 + 1);
In plaats van DROPFRACTIONALPART neem je dan de oberon functie die het kommagedeelte van een waarde wegdoet, dus 5.8 wordt 5 ofzo. Ik weet niet juist welke functie dat is.[/code]
Remember remember the fifth of November
Gunpowder, treason and plot.
I see no reason why gunpowder, treason
Should ever be forgot...

User avatar
Tom
Posts: 602

Post#5 » Wed Feb 04, 2009 11:46 pm

racekakje wrote:Kunde ni beter ne setter maken
en iets in den trend van Dobbelsteen.Set(i, getal).

Da ga sowieso werken en dan kunde ni aan de velden van Dobbelsteen, wat eigenlijk niet slecht is..
Dat doet hij volgens mij nu al omdat hij dobbelsteen gebruikt als object waar i en zijn array insteken, alleen maken die VARs bovenaan de functie dat onduidelijk. (Dat array wordt verder niet gebruikt in de code, enkel de i als index van de FOR loop)
Shinta wrote:In plaats van DROPFRACTIONALPART neem je dan de oberon functie die het kommagedeelte van een waarde wegdoet, dus 5.8 wordt 5 ofzo. Ik weet niet juist welke functie dat is.
Inderdaad, heb ik al gesuggereerd. Merk op dat 5.8 onmogelijk is als je 0 tot 1 vermenigvuldigt met 5. Mja, iets anders uitgelegd maakt het alsnog handiger en meer overtuigender.

User avatar
nasam
Posts: 233
Contact:

Post#6 » Thu Feb 05, 2009 12:03 am

Shinta wrote:

Code: Select all


dobbelsteen^.i := DROPFRACTIONALPART(RandomNumbers.Uniform() * 5 + 1);
ENTIER(RandomNumbers.Uniform()*5+1);

wordt dat dus
http://www.nathansamson.be" onclick="window.open(this.href);return false; Flattr me!Image

User avatar
Robbe
WOZ
Posts: 2161
Contact:

Post#7 » Thu Feb 05, 2009 1:39 am

zou het niet gewoon handiger zijn van met een array van 5 dobbelsteenobjecten te werken?
"I'm not afraid of falling, I'm afraid of landing" -- Sam
How To Ask Questions The Smart Way

Zingen? UKA-n dat ook!

User avatar
Tom
Posts: 602

Post#8 » Thu Feb 05, 2009 1:45 am

Robbe wrote:zou het niet gewoon handiger zijn van met een array van 5 dobbelsteenobjecten te werken?
Zelf begrijp ik de bedoeling van die functie niet helemaal, het is een beetje verwarrend zoals het er staat. De Gooi actie staat gekoppelt aan de Dobbelsteen, als het gaat om een dobbelsteen een willekeurig getal te genereren van 1 tot 6 dan begrijp ik het nog.

Maar met aantaldobbelstenenherwerpen : INTEGER gaat mijn begrip de mist in, je kan immers een dobbelsteen niet zichzelf en andere dobbelstenen laten gooien. Als dit vanuit iemand die gooit is dan zou ik het wel begrijpen. (Met dan de klasse die de dobbelstenen gooit als receiver van de procedure hoofding)

Glenn
Posts: 280

Post#9 » Thu Feb 05, 2009 3:16 pm

Wat ik wilde doen is het spelletje Yahtzee implementeren. Ik heb hiervoor al drie classes aangemaakt:

1) de klasse Speler
Dit is een dubbel gelinkte lijst. De waarden van 1,2,3,4,5,6,tripple,carre,...,chance worden standaard allemaal op 0 gezet bij het aanmaken van de lijst. Dit betekent dat de vakjes eigenlijk nog open zijn, en de Speler er nog mag in schrijven. Als een speler een vakje wil doorstrepen (wanneer hij bv. geen enkele legale zet meer kan doen), dan zal er in dat vakje een zodanig hoge score geschreven worden die men niet met dobbelstenen kan behalen (bij elk vakje dezelfde hoge score). Alleen wanneer een vakje nog niet ingevuld of doorstreept is, kan de speler daar nog iets invullen. Als de speler iets op een leeg vakje wil invullen, zal eerst nagegaan worden of dat wel kan. Je kan bv. niets invullen op het vakje tripple, als je geen drie dobbelstenen hebt die gelijk aan elkaar zijn. Als het legaal is worden vervolgens de punten berekend en wordt de score ingevuld. Als het niet legaal is, wordt de speler gevraagd om iets anders te doen. Hij kan dan bv iets anders invullen of iets doorstrepen.

Code: Select all

Speler* = POINTER TO SpelerDesc;

SpelerDesc* =
RECORD
nr : INTEGER;
naam : String;
1 : INTEGER;
2 : INTEGER;
3 : INTEGER;
4 : INTEGER;
5 : INTEGER;
6 : INTEGER;
triple : INTEGER;
carre : INTEGER;
fullhouse : INTEGER;
kleinestr : INTEGER;
grotestr : INTEGER;
yahtzee : INTEGER;
chance : INTEGER;
next : Speler;
prev : Speler;
END;
De methodes die hiervoor al gepland zijn zijn:
- Create (de lijst aanmaken)
- Add (speler toevoegen)*

* de Add communiceert op zijn beurt met de SpelLeider om telkens bij het toevoegen van een nieuwe speler, het aantalspelers te verhogen.

2) De klasse SpelLeider
Deze klasse bevat eigenlijk de spelinfo. Het aantal spelers houd ik bij om te bepalen welke speler aan de beurt is. Het spel begint steeds bij de speler met het nummer 1. Vervolgens is het aan speler 2 enz. Wanneer we ten slotte aan de speler zijn aangekomen met een spelernummer die gelijk is aan het aantalspelers, weten we dat het de beurt daarna terug aan speler 1 is.

Via ronde weten we hoe ver het spel al gevorderd is, een yahtzee spel eindigt na een vast aantal ronden. Wanneer het aantal ronden bereikt is, eindigt het spel en gaan we naar een eindprocedure.

Code: Select all

SpelLeiderDesc* =
RECORD
aantalspelers : INTEGER;
speleraandebeurt : INTEGER;
ronde : INTEGER;
END;
3) De klasse DobbelSteen
Deze klasse houdt enkel de dobbelstenen bij die net geworpen zijn. Door het sturen van berichten naar een object aangemaakt volgens de richtlijnen van deze klasse, kan men te weten komen welke waarde dobbelsteen1, dobbelsteen2, dobbelsteen3, dobbelsteen4 en dobbelsteen5 hadden bij de laatste worp.

Code: Select all


DobbelSteenDesc* =
RECORD
1 : INTEGER;
2 : INTEGER;
3 : INTEGER;
4 : INTEGER;
5 : INTEGER;
END;
De methodes die hiervoor gepland zijn zijn:
- Gooi (de dobbelsteen gooit zich als het ware zelf)


Om terug te komen op de vraag. Bij Yahtzee kan elke speler 3 pogingen doen (misschien moet ik het aantal gedane pogingen ook opslaan in de spelleider, en dit telkens terug resetten). Wanneer men geworpen heeft, kiest de speler zelf, welke dobbelstenen die hij opnieuw werpt, de andere blijven liggen.

Wat jullie voorstellen om het fractionele deel weg te laten vallen vind ik echt geweldig en was er zelf niet opgekomen. Ik ga dat nu doen en dan verder proberen mijn Yahtzee in elkaar te steken. Als jullie nog tips hebben zijn deze altijd welkom :D . Het OO programmeren is nieuw voor me en ben nu aan het uitzoeken had je het best gebruikt.

EDIT: ik zie net dat velden met een getal vooraan niet zijn toegestaan in Oberon. Ik heb dus de velden van spelers een andere naam moeten geven.
Last edited by Glenn on Fri Feb 06, 2009 12:08 pm, edited 1 time in total.

Glenn
Posts: 280

Post#10 » Thu Feb 05, 2009 3:22 pm

Voor ik heb vergeet, allemaal nog is nen dikke merci om me te helpen :D ! WINAK, you're great :D !

Glenn
Posts: 280

Post#11 » Thu Feb 05, 2009 3:42 pm

Robbe wrote:zou het niet gewoon handiger zijn van met een array van 5 dobbelsteenobjecten te werken?
Eigenlijk wel denk ik. Niet aan gedacht. Maar dan heb ik wel maar een klasse bestaande uit 1 'attribuut' (1 recordveld).

EDIT: ik bedenk net dat het misschien toch beter is om alle dobbelstenen in een object 'Dobbelstenen' te steken. Ik ga nu ook nog de methodes BerekenSom, BepaalTriple, ... maken en deze koppelen aan de klasse DobbelStenen. Misschien dat het ook wel gaat via die array maar ik ga toch nog even werken met een klasse DobbelStenen om te wennen aan het OO programmeren :).
Last edited by Glenn on Thu Feb 05, 2009 3:51 pm, edited 1 time in total.

User avatar
Tom
Posts: 602

Post#12 » Thu Feb 05, 2009 3:46 pm

Kan je niet beter een klasse Dobbelstenen en een klasse Dobbelsteen maken? Dan kan je gewoon een array van de Dobbelsteen-objecten in de klasse Dobbelstenen steken.
Glenn wrote:
Robbe wrote:zou het niet gewoon handiger zijn van met een array van 5 dobbelsteenobjecten te werken?
Eigenlijk wel denk ik. Niet aan gedacht. Maar dan heb ik wel maar een klasse bestaande uit 1 'attribuut' (1 recordveld).
Een klasse hoeft niet persee attributen te bevatten, functies daarentegen zijn meestal wel nodig (al zijn het maar getters en setters, wat dit zijn zie je bij inleiding software engineering).

Maar je zou dus in Dobbelstenen een array van Dobbelsteen-objecten kunnen gebruiken en dan functies voorzien waarmee je dingen kan doen met de Dobbelstenen, die dan op zich functies van Dobbelsteen aanroept.

DobbelStenen.GooiDobbelsteen(0) <-- Gooi de eerste
Die roept dan aan: dobbelstenen[0].Gooi()

Enzovoort, zo kan de speler ook niet per ongeluk gaan rotzooien met de individuele dobbelsteen-objecten aangezien die verstopt zitten in DobbelStenen. (Toegang tot attributen, zie je ook in inleiding software engineering)
Last edited by Tom on Thu Feb 05, 2009 3:55 pm, edited 1 time in total.

Glenn
Posts: 280

Post#13 » Thu Feb 05, 2009 3:54 pm

Tom wrote:Kan je niet beter een klasse Dobbelstenen en een klasse Dobbelsteen maken? Dan kan je gewoon een array van de Dobbelsteen-objecten in de klasse Dobbelstenen steken.
Ja, maar ik zie dat ik ook de som van al mijn dobbelstenen zal moeten berekenen. Is het dan niet logischer dat ik de klasse Dobbelstenen hou en een PROCEDURE BerkenSom maak die rechtstreeks verbonden is met de klasse DobbelStenen?

Maar de som van alle dobbelstenen op de gewone manier berekenen uit die array is natuurlijk ook ni veel werk... . Arrays werken mss wel flexibeler.

User avatar
Tom
Posts: 602

Post#14 » Thu Feb 05, 2009 3:56 pm

Glenn wrote:
Tom wrote:Kan je niet beter een klasse Dobbelstenen en een klasse Dobbelsteen maken? Dan kan je gewoon een array van de Dobbelsteen-objecten in de klasse Dobbelstenen steken.
Ja, maar ik zie dat ik ook de som van al mijn dobbelstenen zal moeten berekenen. Is het dan niet logischer dat ik de klasse Dobbelstenen hou en een PROCEDURE BerkenSom maak die rechtstreeks verbonden is met de klasse DobbelStenen?

Maar de som van alle dobbelstenen op de gewone manier berekenen uit die array is natuurlijk ook ni veel werk... . Arrays werken mss wel flexibeler.
Terwijl jij antwoorde heb ik mijn bericht nog aangepast. :wink:

Glenn
Posts: 280

Post#15 » Fri Feb 06, 2009 10:59 am

Tom wrote:Kan je niet beter een klasse Dobbelstenen en een klasse Dobbelsteen maken? Dan kan je gewoon een array van de Dobbelsteen-objecten in de klasse Dobbelstenen steken.
Glenn wrote:
Robbe wrote:zou het niet gewoon handiger zijn van met een array van 5 dobbelsteenobjecten te werken?
Eigenlijk wel denk ik. Niet aan gedacht. Maar dan heb ik wel maar een klasse bestaande uit 1 'attribuut' (1 recordveld).
Een klasse hoeft niet persee attributen te bevatten, functies daarentegen zijn meestal wel nodig (al zijn het maar getters en setters, wat dit zijn zie je bij inleiding software engineering).

Maar je zou dus in Dobbelstenen een array van Dobbelsteen-objecten kunnen gebruiken en dan functies voorzien waarmee je dingen kan doen met de Dobbelstenen, die dan op zich functies van Dobbelsteen aanroept.

DobbelStenen.GooiDobbelsteen(0) <-- Gooi de eerste
Die roept dan aan: dobbelstenen[0].Gooi()

Enzovoort, zo kan de speler ook niet per ongeluk gaan rotzooien met de individuele dobbelsteen-objecten aangezien die verstopt zitten in DobbelStenen. (Toegang tot attributen, zie je ook in inleiding software engineering)
Bedoel je zoiets als hieronder of bedoel je dat je in de klasse DobbelStenen expliciet een veld moet komen van het type PROCEDURE?

Code: Select all

TYPE
DobbelStenen* = POINTER TO DobbelStenenDesc;

DobbelStenenDesc* =
RECORD
dobbelstenen : ARRAY 5 OF DobbelSteen;
END;

DobbelSteen =
RECORD
waarde : INTEGER;
END;

PROCEDURE (dobbelsteen : DobbelStenen) GooiDobbelSteen (nr : INTEGER);

BEGIN
DobbelStenen^.dobbelstenen[nr].waarde := ENTIER(RandomNumbers.Uniform()*5+1);
END GooiDobbelSteen;
Als ik natuurlijk alleen maar de waarde van elke dobbelsteen nodig heb, kan ik er evengoed ook een ARRAY 5 OF INTEGER van maken :) .

Return to “1ste Bachelor”

Who is online

Users browsing this forum: No registered users and 58 guests