Toon posts:

[Java] Probleem met berekening van waardes

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo,

Voor het vak informatica ben ik met een applet bezig waarmee je als het goed is een spel tegen de computer kan spelen. Een onderdeel van het programma is dat de computerspelers (1-9 ligt eraan hoeveel spelers je hebt geselecteerd) een random aantal lucifers raden. Nu wil het programma de berekening niet helemaal goed doen. Ik heb de berekening in een for-loop gezet om voor alle computerspelers een aantal lucifers te raden. Het programma geeft geen errors, alleen de waardes in de array waar ik de waardes in plaats blijven 0.

AantalSpelers is bovenaan gedeclareerd en wordt gewijzigd nadat je een keuze maakt uit een lijstje, die waarde wordt juist aangepast.
MAXLUCIFERS is een final int die de waarde 3 bevat.

Wie kan zien wat er fout gaat in mijn code?
Ik heb eerst al zelf de double geraden bovenaan gedeclareerd, maar dat werkte niet. Het zit dus echt in de berekening waarschijnlijk.

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void geradenlucifersComputer()
    {
        double geraden;
        int computerSpelers;
        
         for (computerSpelers = 1; computerSpelers < aantalSpelers; computerSpelers++)
         {
        
            geraden = ((Math.random() * MAXLUCIFERS) * (aantalSpelers ));
            geradenLucifers[computerSpelers] = (int) geraden;
            
            //  return geradenlucifers;
            // geradenlucifers van overige spelers wordt berekend en aan programma teruggegeven
          }
    }

[ Voor 0% gewijzigd door een moderator op 05-06-2007 10:21 . Reden: code=java. Syntax highlighting FTW \0/ ]


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 30-11 11:20

voodooless

Sound is no voodoo!

Aangezien MAXLUCIFERS en aantalSpelers ints zijn is het resultaat van je berekening ook een int en geen double! Je moet dus effe die dingen naar een double casten om het goed te laten werken.

Do diamonds shine on the dark side of the moon :?


Verwijderd

Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0.
Van java.sun.com, documentatie van math.random().

Zoals hierboven vermeldt, casten is noodzakelijk. Hou er ook rekening mee dat math.random nooit 1 is. Een voorbeeld is makkelijker dan uitleggen.

Java:
1
2
// random * 6 is nooit 6, vandaar +1, wat er ook voor zorgt dat de kleinste dice 1 is.
int dice = (int) (math.random() * 6 + 1);

Verwijderd

voodooless schreef op dinsdag 05 juni 2007 @ 09:50:
Aangezien MAXLUCIFERS en aantalSpelers ints zijn is het resultaat van je berekening ook een int en geen double! Je moet dus effe die dingen naar een double casten om het goed te laten werken.
double * int levert een double op, dus casten is idd noodzakelijk, maar dan naar int.
Verder zou ik dit:
Java:
1
2
geraden = ((Math.random() * MAXLUCIFERS) * (aantalSpelers ));
geradenLucifers[computerSpelers] = (int) geraden; 

Herschrijven naar dit:
Java:
1
geradenLucifers[computerSpelers] = (int) (Math.random()*MAXLUCIFERS*aantalSpelers);

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 07:20

.oisyn

Moderator Devschuur®

Demotivational Speaker

Alles op 1 regel zetten is niet per se duidelijker, daarnaast is het zo subjectief als het maar zijn kan, dus ik snap de tip niet echt :)

Ruben3123: Weet je wel zeker dat aantalSpelers correct gezet is?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Standaard debugwerk is het telkens printen van de waarde van geraden. Zie je meteen hoe veel iteraties je loopje maakt. :)

{signature}


  • sig69
  • Registratie: Mei 2002
  • Laatst online: 01:51
In dit geval zou ik er gewoon een breakpoint in zetten, zie je snel genoeg wat er verkeerd gaat

Roomba E5 te koop


  • QuaQu
  • Registratie: Oktober 2002
  • Laatst online: 18-08-2021
.oisyn schreef op dinsdag 05 juni 2007 @ 11:42:


Ruben3123: Weet je wel zeker dat aantalSpelers correct gezet is?
Daar zat ik ook net naar te kijken, je begint met element 1 in je array, waardoor je het eerste element (nr 0 dus) overslaat. Ik kom zelf uit de C-wereld, maar vond op Google dat het in Java hetzelfde is: java-tutorial
En met een for-loop in de vorm:
C++:
1
2
for(i = 0; i < max; i++)
..

wordt het max keer uitgevoerd. Als je nu dus bij 1 begint, dan wordt het max-1 keer uitgevoerd. Als je aantalSpelers dus als het werkelijke aantal spelers heb gedefinieerd, moet je bij 0 beginnen.

"Ik heb een boel geld uitgegeven aan drank, vrouwen en snelle auto's. De rest heb ik over de balk gesmeten." - George Best


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 30-11 11:20

voodooless

Sound is no voodoo!

Verwijderd schreef op dinsdag 05 juni 2007 @ 10:32:
double * int levert een double op, dus casten is idd noodzakelijk, maar dan naar int.
Stupid me 8)7

Do diamonds shine on the dark side of the moon :?


Verwijderd

Topicstarter
Java:
1
geradenLucifers[computerSpelers] = (int) geraden;


Op die manier ziet ik de double geraden toch om naar een int om hem vervolgens in de array te plaatsen?
Standaard debugwerk is het telkens printen van de waarde van geraden. Zie je meteen hoe veel iteraties je loopje maakt.
Verder naar onder heb ik op de volgende manier de waardes uit de array op het scherm af laten drukken, dus dan zie ik dat de waarde 0 blijft.
Java:
1
2
3
4
5
6
7
8
        g.drawString( "geradenlucifers = " + geradenLucifers[0] , 40, 350 );
        g.drawString( "geradenlucifers = " + geradenLucifers[1] , 40, 370 );
        g.drawString( "geradenlucifers = " + geradenLucifers[2] , 40, 390 );
        g.drawString( "geradenlucifers = " + geradenLucifers[3] , 40, 410 );
        g.drawString( "geradenlucifers = " + geradenLucifers[4] , 40, 430 );
        g.drawString( "geradenlucifers = " + geradenLucifers[5] , 40, 450 );
        g.drawString( "geradenlucifers = " + geradenLucifers[6] , 40, 470 );
        g.drawString( "geradenlucifers = " + geradenLucifers[7] , 40, 490 );


Hij moet bij de for loop beginnen bij plaats 2 van de array, omdat op plaats in de waarde komt die je zelf raadt. Die voer je zelf in, het programma hoeft alleen voor de computerspelers een random waarde te berekenen.

Off topic: welke tag moet ik gebruiken om in mijn bericht de opmaak voor java code te krijgen?

[ Voor 0% gewijzigd door een moderator op 05-06-2007 17:42 . Reden: code=java. Syntax highlighting FTW \0/ ]


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Verwijderd schreef op dinsdag 05 juni 2007 @ 17:18:
Off topic: welke tag moet ik gebruiken om in mijn bericht de opmaak voor java code te krijgen?
Lees maar even ;) code tags

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Verwijderd schreef op dinsdag 05 juni 2007 @ 17:18:
Verder naar onder heb ik op de volgende manier de waardes uit de array op het scherm af laten drukken, dus dan zie ik dat de waarde 0 blijft.
Ja, dat het 0 blijft weten we nu wel. :> Je moet op de goede plek debuggen. :) Print de waarde van geraden midden in de loop, bekijk de waarde van een element van geradenLucifers voor en na die assignment, doe iets. Begrijp wat er gebeurd, niet pas aan het einde van je programma kijken of er toevallig iets gebeurd is.

{signature}


  • Nick The Heazk
  • Registratie: Maart 2004
  • Laatst online: 07-09-2024

Nick The Heazk

Zie jij er wat in?

Waarom print je niet eens de waarde uit van je factoren in plaats van de resulterende waarde. Het feit dat hij altijd nul geeft duidt erop dat ofwel
code:
1
MAXLUCIFERS
ofwel
code:
1
aantalSpelers
nul is. Dit kan het geval zijn als je variabelen aan het schaduwen bent, of omdat je ze vergeet te instantiëren.

[ Voor 0% gewijzigd door Nick The Heazk op 05-06-2007 18:36 . Reden: Te laat :) ]

Performance is a residue of good design.


  • MetroidPrime
  • Registratie: Oktober 2003
  • Laatst online: 01-11 10:08

MetroidPrime

Turn it up loud, captain!

Volgens mij kunnen er twee oorzaken voor je probleem zijn. Ik heb je vorige topic bekeken en daarin zag ik dat je aantalSpelers als 0 initialiseert en pas aanpast zodra iemand een waarde uit het dropdown menu selecteert, in plaats van dat je aantalSpelers initialiseert op de standaard waarde in het dropdown menu. Als je dus geen waarde selecteert, dan is aantalSpelers automatisch 0.

Het tweede probleem is dat je begint met het vullen van de array op positie 1 in plaats van 0. Je slaat in feite een positie over bij het vullen van de array. Als je bij het uitlezen er van uitgaat dat speler 1 op positie 0 staat, dan ga je de fout in omdat je speler 1 op positie 1 hebt gezet.

Als het inderdaad de bedoeling is dat speler 1 op positie 0 van de array komt te staan, dan is het misschien handig om de array niet direct te benaderen, maar via een get en een set functie. Deze functies vertalen dan zelf het spelers nummer naar een positie in de array, waardoor je deze fout niet meer kan maken in de rest van je code.

"Some girl on the street outside the bar just asked me if I was saved yet." "Yeah? What did you say?" "I told her 'I saved at the checkpoint a couple of minutes back and I can reload from there if I die.'


Verwijderd

Topicstarter
Ik heb de fout met het raden van de lucifers al opgelost. Het zat hem in het juist aanroepen van de methodes. De berekening zelf ging wel goed. Maar nu heb ik een volgend probleempje gevonden. Ik wil dat het programma uit de array geradenLucifers een waarde haalt en daar het totaalaantallucifers vanaf haalt en dan de absolute waarde neemt van het verschil en die waarde in de array verschilLucifers zet. Maar nu kloppen de waardes in de array geradenlucifers wel en het totaalaantallucifers klopt ook, maar hij berekent het verschil niet goed. Weet iemand wat er fout gaat?
[code=java]
public void setVerschilLucifers()
{
int verschil;
int spelers;

for (spelers = 0; spelers < aantalSpelers; spelers++)
{

verschil = geradenLucifers[spelers] - aantalLucifersTotaal; // De waarde van de geraden lucifers wordt per speler uit de array gehaald en het verschil wordt berekend van het werkelijke aantal lucifers
verschilLucifers[spelers] = Math.abs(verschil); // De absolute waarde wordt berekend en in de array geplaatst
}
}
[/code=java]

  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 30-11 11:20

voodooless

Sound is no voodoo!

Misschien kun je uitleggen wat er niet goed is :? Wat verwacht je en wat krijg je?

Do diamonds shine on the dark side of the moon :?


  • Swaptor
  • Registratie: Mei 2003
  • Laatst online: 15-10 19:25

Swaptor

Java Apprentice

De standaardvragen komen bij mij op: heb je verschilLucifers wel goed geïnstantieerd?
Heb je aantalSpelers nog ergens in je code staan als variabele want in dit stukje blijft het 0 (als het überhaupt compilet)?
De code die hier staat ziet er goed uit, dus verder wat voodooless zegt.

Ontdek mij!
Proud NGS member
Stats-mod & forum-dude


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Tja, ik ga m'n posts herhalen: print dan midden in die loop de waarde van verschil. Als je dat al gedaan hebt (ik mag hopen dat je een advies dat al 2x gegeven is uitprobeert), vertel dan wat er mis is met de waarde van verschil.

Verder staan in dit topic al 9 zijdelingse opmerkingen over de waardes van je globale variabelen, dus wellicht handig als je die ook eens verklapt. Incl. declaratie zodat we ook zien met wat voor arrays je nou precies bezig bent. Wij kunnen de rest van je code niet zien, het enige dat we bij je nieuwe vraag zien is een triviale berekening. Ik weet zeker dat de '-' operator en de Math.abs() functie bugvrij zijn, dus we hebben gewoon meer code nodig. :)

{signature}


Verwijderd

Topicstarter
Ik ben er al achter bij welke waarde het misgaat.

[code=java]
public void setVerschilLucifers()
{
int verschil;
int spelers;

int aantalLucifers;
aantalLucifers = setTotaalAantalLucifers();
verschil = geradenLucifers[0] - aantalLucifersTotaal;
verschilLucifers[0] = Math.abs(verschil);
uitvoervak2.setText("aantalLucifersTotaal: " + aantalLucifersTotaal);

}
[/code=java]
Het trekt de waarde aantalLucifersTotaal wel van het aantal dat staat in de array op plaats 0 af, maar hij pakt voor aantalLucifersTotaal de verkeerde waarde. Hij pakt een andere waarde dan die hij zou moeten nemen. Ik heb in de een tekstvak de waarde aantalLucifersTotaal af laten drukken verder naar onderen in het programma en daar geeft het programma wel de juiste waarde. Hij geeft de juiste waarde in dit stukje code:
[code=java]
public void setAantalSpelers()
{

aantalSpelers = Integer.valueOf(selAantalSpelers.getSelectedItem());
tekstvak.setText(aantalSpelers + " spelers!");

int aantalLucifers;
aantalLucifers = setTotaalAantalLucifers();

uitvoervak.setText( "aantal = " + aantalLucifersTotaal );
setAantalLucifersMogelijk();

}
[/code=java]

Ik heb bovenaan in het programma de waarde aantalLucifersTotaal gedefinieerd op de volgende manier:
[code=java]
int aantalLucifersTotaal;
[/code=java]
Hij zou dus de waarde die ik heb berekend voor aantalLucifersTotaal goed moeten pakken. De methode waar dit aantal wordt bepaald is:

[code=java]
public int setTotaalAantalLucifers()
{

aantalLucifersSpeler = Integer.valueOf(selAantalLucifersSpeler.getSelectedItem()); // Haal het aantal lucifers op wat de speler heeft geselecteerd
double tempTotaalAantalLucifers;

/*
* Er wordt een willekeurige waarde berekend tussen 0 en 3 vermenigvuldigd met het aantal
* computerspelers minus de speler zelf plus het aantal lucifers dat de speler zelf heeft geselecteerd
*/

tempTotaalAantalLucifers = ((Math.random() * MAXLUCIFERS) * (aantalSpelers - 1)) + aantalLucifersSpeler;
aantalLucifersTotaal = (int) tempTotaalAantalLucifers;

return aantalLucifersTotaal;
}
[/code=java]

Er zit denk ik dus ergens een fout in de verwijzing, want de waarde wordt elders in het programma goed weergegeven, maar in de methode setVerschilLucifers is de waarde ineens anders.

Als laatste wil ik nog even laten zien hoe ik de methodes aanroep, maar dat gebeurt volgens mij op de juiste manier:
[code=java]
public void actionPerformed (ActionEvent e)
{


if ( e.getSource() == btnStartknop ) {
startnummer ++;
selAantalRonden.disable();
selAantalSpelers.disable();
btnStartknop.disable();
setAantalSpelers();
setAantalLucifersMogelijk();
repaint();

}

if (e.getSource() == btnVolgendeRonde ) {
setTotaalAantalLucifers();
setGeradenLucifers();
setVerschilLucifers();
bepaalWinnaar();
setAantalSpelers();
volgenderonde++;
// uitvoervak2.setText("Ronde: " + volgenderonde);
repaint();


}

if (e.getSource() == btnResultaat ) {
totaalnummer ++;
uitvoervak2.setText( "Eind: = " + totaalnummer );
}

}
[/code=java]

[ Voor 16% gewijzigd door Verwijderd op 07-06-2007 10:11 . Reden: Klein deel vergeten ]


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 30-11 11:20

voodooless

Sound is no voodoo!

actually... never mind..(zie onder mij ;) )

Volgens mij gaat het mis als setVerschilLucifers() voor setAantalSpelers() aanroept volgens mij.

[ Voor 167% gewijzigd door voodooless op 07-06-2007 10:53 ]

Do diamonds shine on the dark side of the moon :?


  • NetForce1
  • Registratie: November 2001
  • Laatst online: 08:51

NetForce1

(inspiratie == 0) -> true

voodooless schreef op donderdag 07 juni 2007 @ 10:41:
[...]


Denk hier nog maar eens even over na :)
Dat dacht ik eerst ook, maar aantalLucifersTotaal wordt gezet in de methode setTotaalAantalLucifers(). Het stukje code dat jij aanhaalt is dus hooguit overbodig, maar het veroorzaakt volgens mij niet het probleem.

edit:
Volgens mij heeft het ermee te maken dat je verschillende keren setTotaalAantalLucifers aanroept, wat voodooless dus ook ongeveer zegt.

[ Voor 16% gewijzigd door NetForce1 op 07-06-2007 10:57 ]

De wereld ligt aan je voeten. Je moet alleen diep genoeg willen bukken...
"Wie geen fouten maakt maakt meestal niets!"


Verwijderd

Topicstarter
Ik heb de volgorde van het aanroepen van de methodes veranderd. Maar dat maakt helaas geen verschil. Ik roep iedere keer setTotaalAantalLucifers op, omdat er iedere keer een ander totaal aantal lucifers in de pot zit, wat je dan moet raden. Gek genoeg berekent hij wel goed het verschil tussen het aantallucifers dat hij afdrukt in uitvoervak2 en wat je zelf ingeeft, dus de berekening gaat goed, maar hij pakt de verkeerde waarde.
Ik zal eens proberen de waarde een andere naam te geven en kijken of dat effect heeft.

  • MetroidPrime
  • Registratie: Oktober 2003
  • Laatst online: 01-11 10:08

MetroidPrime

Turn it up loud, captain!

Verwijderd schreef op vrijdag 08 juni 2007 @ 00:02:
Ik heb de volgorde van het aanroepen van de methodes veranderd. Maar dat maakt helaas geen verschil. Ik roep iedere keer setTotaalAantalLucifers op, omdat er iedere keer een ander totaal aantal lucifers in de pot zit, wat je dan moet raden. Gek genoeg berekent hij wel goed het verschil tussen het aantallucifers dat hij afdrukt in uitvoervak2 en wat je zelf ingeeft, dus de berekening gaat goed, maar hij pakt de verkeerde waarde.
Ik zal eens proberen de waarde een andere naam te geven en kijken of dat effect heeft.
Is dit niet weer het probleem waarbij je de array begint te vullen bij 1 in plaats van 0, maar dat je bij het uitlezen wel bij 0 begint?

"Some girl on the street outside the bar just asked me if I was saved yet." "Yeah? What did you say?" "I told her 'I saved at the checkpoint a couple of minutes back and I can reload from there if I die.'


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
setTotaalAantalLucifers() gebruikt aantalSpelers, een variabele die je pas later bijwerkt?

Het probleem is overigens niet de volgorde van die functies, het echte probleem zit hem in het gebruik van globale variabelen. Door minder met globale variabelen te werken kan deze code al een stuk overzichtelijker worden. Imo heb je nu last van je globals, de korte termijn fix is debuggen en volgorde controleren, de lange termijn fix is dus minder globals. :)

Overigens kan je binnen actionPerformed ook met if else werken, scheelt weer wat checks, plus dat je sneller kan zien dat maar 1 van die blokken code uitgevoerd wordt.
MetroidPrime schreef op vrijdag 08 juni 2007 @ 00:05:
[...]
Is dit niet weer het probleem waarbij je de array begint te vullen bij 1 in plaats van 0, maar dat je bij het uitlezen wel bij 0 begint?
Speler 0 is de user, spelers >= 1 is de computer.

{signature}


Verwijderd

Topicstarter
Mijn applet is inmiddels helemaal af. Als je benieuwd bent hoe hij nu werkt moet je me maar even een pm sturen met je emailadres. Dan zal ik hem naar je mailen.

Nog bedankt voor jullie hulp

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Verwijderd schreef op woensdag 20 juni 2007 @ 21:56:
Mijn applet is inmiddels helemaal af. Als je benieuwd bent hoe hij nu werkt moet je me maar even een pm sturen met je emailadres. Dan zal ik hem naar je mailen.

Nog bedankt voor jullie hulp
Op een forum, en zeker op GoT, moet je PM/DM zien als een leuke bonus; de primaire manier van communiceren is dan ook via het forum. Als je resultaten hebt zijn er vast een boel mensen die geïnteresseerd zijn en je resultaten willen zien zonder daarbij hun email adres af te hoeven staan. Waarom plaats je je applet niet ergens online?

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Verwijderd

Topicstarter
Ok, ik snap het. Niet dat de mensen bang hoeven te zijn dat ik allerlei vreemde dingen met hun mailadres ga doen, maar ik snap de motivatie van sommigen. Ik heb zelf geen webruimte van mijn provider dus ik kan het moeilijk ergens op internet plaatsen. Of weet iemand een andere goede manier om het op internet te plaatsen?

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Verwijderd schreef op vrijdag 22 juni 2007 @ 00:53:
Of weet iemand een andere goede manier om het op internet te plaatsen?
Genoeg ;)

Hier heb je er zo een, of zip/rar het hele spul en knal het hier neer. En anders, uiteraard de ultieme plek om je bestanden te hosten voor een prikkie: hier :Y) :+

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Verwijderd

Topicstarter
Het is me gelukt. Hij staat hier: http://www.mediafire.com/?2g1xtjs19p9

Ik heb ook van een stuk van het programma een programma structuur diagram moeten maken. Die staat hier: http://www.mediafire.com/?7gwzcndewug

Lijkt me leuk als jullie zeggen wat jullie ervan vinden.

[ Voor 37% gewijzigd door Verwijderd op 22-06-2007 16:26 ]

Pagina: 1