[alg] Veel If-statements voorkomen

Pagina: 1
Acties:
  • 311 views sinds 30-01-2008
  • Reageer

  • Piels
  • Registratie: Maart 2001
  • Laatst online: 27-11 14:22
Op het moment ben ik bezig met het schrijven van een programma. In het programma kijk ik naar het mouse click event. Onder het mouse click event heb ik op het moment even kort door de bocht dit:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
private void Node_MouseClick(object sender, MouseEventArgs e)
{
     if (e.Button == MouseButtons.Left)
     {
         if (blaat == blaat)
         {
             if (bleet == bleet)
             {

             }
             else if (bloot == bloot)
             {

             }
             else if (bluut == bluut)
             {

             }
         }
     }
     else if (e.Button == MouseButtons.Right)
     {
         if (blaat2 == blaat2
         {
             if (bleet2 == bleet2)
             {

             }
             else if (bloot2 == bloot2)
             {

             }
             else if (bluut2 == bluut2)
             {

             }
         }
     }
}


Zoals je ziet ga ik hier al 3 diep qua if statements en eigenlijk zou ik op nog meer condities moeten checken, waardoor ik nog meer if statements erbij zou krijgen.Hele lelijke code dus.

Wat ik me nu afvraag, wat is de beste manier van programmeren om alle condities te controleren, zonder dat ik 3, 4, 5 levels diep ga met mijn if statements?

[ Voor 15% gewijzigd door Piels op 08-03-2007 10:02 ]

Windows Phone Apps: Belstatus, Pinautomaten


  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 10:26

TeeDee

CQB 241

Case / Switch?

Heart..pumps blood.Has nothing to do with emotion! Bored


Verwijderd

ik heb geen ervaring met C# maar ik zou het opdelen in meerder functie's. dus deze node_mouseClick laten vaststellen wat er wordt geklikt, left of right mousebutten dus. en een functie voor de left mousebutton en een functie voor de right_mousebutten die dan aan de hand van de sender de juiste actie onderneemt.

tis maar een een idee'tje.

@teedee, lol in de zelfde minutt een antwoord. een case/switch lijkt me niet handig omdat je ook met de sender te maken hebt, en ik weet niet hoeveel mogelijk heden er kunnen zijn voor sender maar het lijkt me niet handig om alle mogelijk heden voor sender+left&right mousebutten te hard-coden.

@piels: niet volgensmij, een case-switch springt gelijk naar het antwoord en anders naar de else.

[ Voor 37% gewijzigd door Verwijderd op 08-03-2007 09:50 ]


  • Piels
  • Registratie: Maart 2001
  • Laatst online: 27-11 14:22
Hoe maak je met een Case / Switch je code meerdere levels diep? :/

Windows Phone Apps: Belstatus, Pinautomaten


  • Wouter Tinus
  • Registratie: Oktober 1999
  • Niet online

Wouter Tinus

Whee!

Je zou eventueel met een bitmask kunnen werken om er een switch van te maken, dan kun je de situaties waar je niets speciaals hoeft te doen afvangen met de default. Ook kun je natuurlijk gewoon meerdere condities in één if-statement checken, of de checks in een aparte functie onderbrengen :).

[ Voor 11% gewijzigd door Wouter Tinus op 08-03-2007 09:51 ]

Professioneel Hyves-weigeraar


Verwijderd

Met Docey, en je kunt je soms afvragen of je soms een: if (var1==var1 && var2==var2) kunt doen.

/edit, met Docey en met Wouter Tinus dus :D

[ Voor 19% gewijzigd door Verwijderd op 08-03-2007 09:51 ]


  • Chester
  • Registratie: September 2003
  • Niet online
Je kunt ook gewoon 1 statement voor je bleets pakken?

code:
1
2
3
if ((blaat == blaat) && (bleet == bleet) {
    //code
}

"The test of a work of art is, in the end, our affection for it, not our ability to explain why it is good." - Stanley Kubrick | Trakt


  • Piels
  • Registratie: Maart 2001
  • Laatst online: 27-11 14:22
Maar het checken van meerdere condities in een if-statement is in mijn geval niet van toepassing. :)

Bestaat hier toevallig geen design pattern voor die beschrijft hoe je dit het beste kunt aanpakken?

Windows Phone Apps: Belstatus, Pinautomaten


  • Wouter Tinus
  • Registratie: Oktober 1999
  • Niet online

Wouter Tinus

Whee!

Lees dit eens: http://www.vipan.com/htdocs/bitwisehelp.html

Je kunt zo tot 31 true/false-dingen in één getal coderen en dan daarop switchen.

Maar ik vraag me eigenlijk af wat je precies probeert te bepalen, want waarschijnlijk kan het wel makkelijker dan door zoveel code onder een event te hangen.

[ Voor 37% gewijzigd door Wouter Tinus op 08-03-2007 09:58 ]

Professioneel Hyves-weigeraar


  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 10:26

TeeDee

CQB 241

Dan is het de vraag of het niet beter ingedeeld kan worden. Misschien als je aangeeft wat je probeert te bereiken/doen.
Wouter Tinus schreef op donderdag 08 maart 2007 @ 09:56:
Lees dit eens: http://www.vipan.com/htdocs/bitwisehelp.html

Je kunt zo tot 31 true/false-dingen in één getal coderen en dan daarop switchen.

Maar ik vraag me eigenlijk af wat je precies probeert te bepalen, want waarschijnlijk kan het wel makkelijker dan door zoveel code onder een event te hangen.
Nette oplossing. Die bookmark ik ook maar even :)

[ Voor 66% gewijzigd door TeeDee op 08-03-2007 09:59 ]

Heart..pumps blood.Has nothing to do with emotion! Bored


  • ColdSTone|IA
  • Registratie: December 2002
  • Laatst online: 28-12-2017

ColdSTone|IA

lui..

Piels schreef op donderdag 08 maart 2007 @ 09:44:
Zoals je ziet ga ik hier al 3 diep qua if statements en eigenlijk zou ik op nog meer condities moeten checken, waardoor ik nog meer if statements erbij zou krijgen.Hele lelijke code dus.

Wat ik me nu afvraag, wat is de beste manier van programmeren om alle condities te controleren, zonder dat ik 3, 4, 5 levels diep ga met mijn if statements?
Piels schreef op donderdag 08 maart 2007 @ 09:54:
Maar het checken van meerdere condities in een if-statement is in mijn geval niet van toepassing. :)

Bestaat hier toevallig geen design pattern voor die beschrijft hoe je dit het beste kunt aanpakken?
Wat je nu laat zien zijn meerdere condities in een if-statement, dat is dus wel van toepassing.

[ Voor 35% gewijzigd door ColdSTone|IA op 08-03-2007 10:01 ]


  • mithras
  • Registratie: Maart 2003
  • Niet online
Hoewel het volgens sommigen redelijk ugly is, doe ik met php soms het volgende om achter elkaar bepaalde checks te kunnen doen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function doe_iets($getal){
  if(!is_numeric($getal)){
    echo "Geen getal!";
    return false;
  }if($getal < $ondergrens){
    echo "Getal te klein!";
    return false;
  }if($getal > $bovengrens){
    echo "Getal te groot!";
    return false;
  }
  $getal = do_something($getal);
  return $getal;
}
Zo voorkom je dat je drie niveau's diep gaat zitten, maar enkel bij fouten eruit springt :)

* mithras vind dit een stuk overzichtelijker dan die one exit points die sommigen willen creeeren en dan heel diep met if statements zitten.

  • Piels
  • Registratie: Maart 2001
  • Laatst online: 27-11 14:22
ColdSTone schreef op donderdag 08 maart 2007 @ 09:59:
[...]


[...]

Wat je nu laat zien zijn meerdere condities in een if-statement, dat is dus wel van toepassing.
Ik heb de code even aagepast. Hopelijk wordt het zo iets duidelijker. :)

Overigens werkt het allemaal hoor, maar ik zou graag horen wat de best practice is voor zo'n geval.

[ Voor 45% gewijzigd door Piels op 08-03-2007 10:04 ]

Windows Phone Apps: Belstatus, Pinautomaten


  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Wat mithras zegt, ook wel Guard Clauses genoemd. En er zijn inderdaad voor- en tegenstanders :)

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


Verwijderd

ik zou toch eerder in deze richting gaan werken:

(in php maar goed, gaat om het idee)
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    function mouse_leftklik($blaat, $bleet)
    {
        if($blaat == $bleet){
         return true;
        }elseif($blaat != $bleet){
         return false;
        }elseif($blaat > $bleet){
         return $blaat;
        }elseif($blaat < $bleet){
         return $bleet;
        }else{
         return NULL;
        }
    }
    
    function mouse_rightklik($blaat, $bleet)
    {
        if($blaat == $bleet){
         return true;
        }elseif($blaat != $bleet){
         return false;
        }elseif($blaat > $bleet){
         return $blaat;
        }elseif($blaat < $bleet){
         return $bleet;
        }else{
         return NULL;
        }
    }

    function mouse_klik($klik_event, $blaat, $bleet)
    {
        switch ($klik_event){
        case "left":
         return mouse_leftklik($blaat, $bleet);
        case "right":
         return mouse_rightklik($blaat, $bleet);
        default: 
         return NULL;
        }
    }


probeer je if-statement in blokken te stoppen en die in verschillende functie's te stoppen. volgensmij wat dat ook het hele idee van functie's. code opsplisten en modulair aanroep baar te maken waar nodig.

mischien als eens wat meer verteld over wat $blaat en $bleet moeten voorstellen, want eigenlijk moet je natuurlijk zulke diepe if-statement proberen te vermijden tenzij het echt niet anders kan.

  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Mja functies opsplitsen om het opsplitsen is natuurlijk ook niet altijd zaligmakend of verhelderend. Soms heb je gewoon lange switches/if-statements, dan zij het zo.

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Piels schreef op donderdag 08 maart 2007 @ 09:54:
Bestaat hier toevallig geen design pattern voor die beschrijft hoe je dit het beste kunt aanpakken?
Ja, met een strategy kan je afhankelijk van een bepaalde voorwaarde, een bepaalde implementatie van een algoritme gaan uitvoeren, maar ik denk niet dat het hier veel nut heeft. (Als in: een tank gebruiken om een mug te killen enzo).

https://fgheysels.github.io/


  • Piels
  • Registratie: Maart 2001
  • Laatst online: 27-11 14:22
kenneth schreef op donderdag 08 maart 2007 @ 10:05:
Wat mithras zegt, ook wel Guard Clauses genoemd. En er zijn inderdaad voor- en tegenstanders :)
Ik denk niet dat dit voor mij van toepassing is aangezien ik meerder waardes set.

@Docey, zat ik ook al aan te denken. Komt op hetzelfde neer, maar is iets overzichtelijker. :)

Windows Phone Apps: Belstatus, Pinautomaten


  • Feyd-Rautha
  • Registratie: November 2001
  • Laatst online: 02-08 23:34
Door een goed OO ontwerp en maximaal gebruik maken van polymorfisme kun je veelal veel if-statements weghalen. Kijk bijvoorbeeld eens naar verschillende design patterns, zoals het 'state' DP

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.


Verwijderd

Feyd-Rautha schreef op donderdag 08 maart 2007 @ 10:48:
Door een goed OO ontwerp en maximaal gebruik maken van polymorfisme kun je veelal veel if-statements weghalen. Kijk bijvoorbeeld eens naar verschillende design patterns, zoals het 'state' DP
dat is inderdaad het beste, OO is dan ook de meest logische volgende stap.

ik probeer me nog steeds iets voor te stellen wat je met blaat en bleet bedoelt. ik neem even aan de je de muis gebruikt om een GUI te besturen en dat je met blaat en bleet probeert om te achterhalen waar er op geklikt is.

stel je hebt dan dus een GUI met verschillende knoppen, textfields, images etc. als die GUI controll's al OO zijn kun je dan niet beter van elke object de top-left coordinaat en width-height waardes in een array stoppen. het enige wat je dan doet is met aan de hand van een x-y coordinaat kijken welk onderdeel van de GUI daarbij hoort. dus waar op geklikt is.

vervolgens roep je dan de leffklik of de rightklik aan van dat object en die moet dan maar uitzoeken wat er moet gebeuren als er met links of rechts op is geklikt. die functie's kunnen dan vervolgens middels een terugkoppeling een menu te voorschijn toveren bijvoorbeeld waarna het hele verhaal zich herhaalt.

mischien dat je nog eens kunt proberen uit te leggen wat je precies met de muis probeert te bereiken want het wordt zo wel erg moeilijk om te bepalen wat het beste is. if statemens of OO? uitleg graag.

  • YopY
  • Registratie: September 2003
  • Laatst online: 06-11 13:47
Of je maakt voor elke knop waar je op kunt klikken een aparte listener (in Java tenminste, weet niet of het ook zo werkt in C#). Met andere woorden, als op knop A gedrukt word, moet functie B in de ActionListener klasse uitgevoerd worden.

Zodanig is het simpelweg onmogelijk om een stuk functionaliteit dat onder de ene knop zit uit te voeren onder de andere, ook wanneer er anderen met je code bezig gaan en, bijvoorbeeld, de knopjes een andere naam gaan geven.

Een action listener systeem is volgens mij ook niet moeilijk om zelf in elkaar te zetten.

  • Piels
  • Registratie: Maart 2001
  • Laatst online: 27-11 14:22
Met het klikken van de mouse button bestuur ik inderdaad de GUI.

Ik ben bezig met PathFinding dmv het A* algoritme.

Afbeeldingslocatie: http://www.xs4all.nl/~pielsa/PathFinding.PNG
Afbeeldingslocatie: http://www.xs4all.nl/~pielsa/PathFinding2.PNG

De groene node stelt het startpunt voor. De rode node het eindpunt. De zwarte blokken stellen muren voor. De roze nodes geven de gevonden route aan.

Op het moment het ik het zo geimplementeerd dat ik met de linkermuisknop de Startnode en de Goalnode kan zetten en met de rechtermuisknop de muren neer kan zetten.

Nu moet ik dus als ik op een node klik kijken wat er allemaal al geset is. Bestaat er al een Startnode, bestaat er al een Goalnode, bestaat er nog helemaal niets, bestaan ze beide al?
Allemaal dingen die ik moet afvangen.

Hopelijk is het zo iets duidelijker :)

Windows Phone Apps: Belstatus, Pinautomaten


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 11:17

Janoz

Moderator Devschuur®

!litemod

Dat lijkt me redelijk makkelijk te ondervangen. Ten eerste moet je de gui scheiden van je eigenlijke gebeuren. Met leftclick roep je op je buisnesslogic de 'placeNode' aan. Binnen placeNode hou je een state bij die aangeeft om welke node het gaat (start of eind. Ik neem aan dat je om en om plaatst). Binnen die die methode kijk je of het kan en als het kan plaats je.

Met rightclick roep je de toggle wall methode aan in je buisness logic. In die methode kijk je of er al een muur staat en afhankelijk daarvan zet je een muur of haal je hem weg. Als er een node staat doe je niks.

Deze implementatie heeft volgens mij nergens een if nesting dieper dan 1.

Het probleem dat jij waarschijnlijk eerder hebt is dat je je applicatie compleet in je eventhandlers aan het implementeren bent.

[ Voor 9% gewijzigd door Janoz op 08-03-2007 11:42 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Dit lijkt me nou meer iets voor SEA.
PRG >> SEA

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


  • cspare
  • Registratie: Oktober 2006
  • Laatst online: 29-07 22:19

cspare

What the deuce?!

Ik zou in jouw geval een klasse maken SpeelVeld en Node. Van de klasse Node kan je dan 2 subklasses maken, WayPointNode (een start en eind node hebben denk ik het zelfde gedrag?) en WallNode.
vanuit je mouseclick event roep je dan uit je speelVeld object afhankelijk van welke muisknop werd geklikt. dus bijvoorbeeld speelVeld.setWayPointNode en speelVeld.setWallNode.

Ik denk dat je zo alleen een if-statement hebt voor welke muisknop je hebt geklikt. eventueel nog een toevoegen om te kijken of de node al bestond zodat je 'm ook weer uit kan toggelen

The one who says it cannot be done, should never interrupt the one who is doing it.


  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Waarom subklasses WayPointNode en WallNode? Kunnen waypoint/wall niet gewoon states van Nodes zijn? Ik zie geen extra functionaliteit voor de subklasses. Ik vind het een beetje naar overdesign ruiken.

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


  • Piels
  • Registratie: Maart 2001
  • Laatst online: 27-11 14:22
Ik heb een klasse AStarNode bevat de BL van de node.

En ik heb een klasse AStarNode2D die een wit hokje voorsteld. Een AStarNode2D maakt op het moment dat er op geklikt wordt een StartNode / GoalNode / MuurNode aan van het type AStarNode. Dus een AStarNode2D bevat niet standaard een object AStarNode. Dit is ook de klasse die de het Paint event triggert.
Deze klasse handeld ook het mouse_click event af.

En ik heb een klasse Gameboard die een twee dimensionale array bevat met AStarNode2D objecten.

Zou ik het anders moeten opzetten?

[ Voor 6% gewijzigd door Piels op 08-03-2007 12:05 ]

Windows Phone Apps: Belstatus, Pinautomaten


Verwijderd

is het niet makkelijker om dat gewoon allemaal in de klasse Gameboard te zetten?

eigenlijk zijn zowel de start-node als de eind-node als mede de lege of gevonden node gewoon state's van een node. elke node kan dus een van deze 4 node's zijn. het moet dan ook niet moeilijk zijn om de start en eind node hieruit te vinden tenzij je array echt in de duizenden nodes loopt.

maak dan gewoon zoals hierboven al werd gezegt een klasse met een methode die een muur plaats en een welke een einde of start node. daarnaast zou je nog een aparte "helper" methode kunnen maken welke de state van een x/y node geeft zoals een isMuur($x, $y) of een whereStart() methode.

volgensmij was je met al die if's veel te moeilijk aan het denken en voor elke state een aparte klasse is denk ik ook inderdaad een geval van overdesign. immers hoeveel informatie kan een node bevatten?

  • Piels
  • Registratie: Maart 2001
  • Laatst online: 27-11 14:22
Ik heb niet voor elke state een aparte klasse.

De klasse AStarNode bevat de functies IsGoal(), IsStart, IsInAccessible.

Die geeft gewoon terug of deze node een Goal-, Start-, of Muurnode is. Dus ik denk dat het goed in elkaar zit.
Dus als een GoalNode geset wordt, dan weet ook het object Gameboard dat er een GoalNode is en welke dat is.

En dus in de if-statement moet ik dus kijken of er al een muur is, een start en een goal. En als er al een van bestaat, dan moet ik weer verder gaan kijken.

Hoop dat het zo iets duidelijker is.

Windows Phone Apps: Belstatus, Pinautomaten


  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 09:27

mulder

ik spuug op het trottoir

Piels schreef op donderdag 08 maart 2007 @ 12:48:
Ik heb niet voor elke state een aparte klasse.

De klasse AStarNode bevat de functies IsGoal(), IsStart, IsInAccessible.

Die geeft gewoon terug of deze node een Goal-, Start-, of Muurnode is. Dus ik denk dat het goed in elkaar zit.
Dus als een GoalNode geset wordt, dan weet ook het object Gameboard dat er een GoalNode is en welke dat is.

En dus in de if-statement moet ik dus kijken of er al een muur is, een start en een goal. En als er al een van bestaat, dan moet ik weer verder gaan kijken.

Hoop dat het zo iets duidelijker is.
Dan wil je toch gewoon Node.Type checken dmv een simpele enum:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
public enum NodeType
{
    Normal,
    Start,
    Goal,
    Wall
}
switch(obj.Type)
{
    case NodeType.Normal
     blablabla
}
En dan kun je toch kijken wat je allemaal in huis hebt qua Nodes?

oogjes open, snaveltjes dicht


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 11:17

Janoz

Moderator Devschuur®

!litemod

Met hierboven.

Ik zie weinig fucntionaliteit voor de node zelf en vooral voor het gameboard. Een array van nodes die alleen van zichzelf weten of ze start, end of wall zijn moet genoeg zijn (een enum). Sterker nog. Ik zou mijn start- en eindnode niet eens op mijn board zetten, maar gewoon als x,y coordinaat bijhouden in het gameboard. Maakt het verplaatsen een stuk makkelijker. Hoef je bij het toggelen van een wall alleen te kijken of het de start of eind node is, en als dat niet zo is de state omdraaien.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Marcj
  • Registratie: November 2000
  • Laatst online: 11:39
Is het hele probleem hier dat je voor de GUI 1 eventhandler hebt voor alle vakjes, terwijl je juist zou willen dat elk vakje z'n eigen eventhandler had. Op die manier ben je ook van al die if's af. Dat zou de OO manier zijn om het zoiets te programeren. Welk object je dan als eventhandler gebruikt hangt er natuurlijk weer van af. Je zou er bijvoorbeeld voor kunnen kiezen dat iedere node een eventhandler is, maar er zijn meer opties.

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 11:17

Janoz

Moderator Devschuur®

!litemod

Mwah, elk vakje een event handler lijkt me nou ook weer wat overdreven. Of je nu 1 eventhandler hebt waarin je toggleVakje(x,y) doet, of 64 eventhandlertjes die elk aan een vakje worden gekoppeld en toggleMijnVakje() aanroepen, dan gaat mijn voorkeur toch uit naar de eerste.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 09:27

mulder

ik spuug op het trottoir

Marcj schreef op donderdag 08 maart 2007 @ 16:37:
Is het hele probleem hier dat je voor de GUI 1 eventhandler hebt voor alle vakjes, terwijl je juist zou willen dat elk vakje z'n eigen eventhandler had. Op die manier ben je ook van al die if's af. Dat zou de OO manier zijn om het zoiets te programeren. Welk object je dan als eventhandler gebruikt hangt er natuurlijk weer van af. Je zou er bijvoorbeeld voor kunnen kiezen dat iedere node een eventhandler is, maar er zijn meer opties.
Sorry maar dit verhaal gaat niet echt ergens over :? Je wilt juist alle NodeClicks oid in 1 eventhandler (de NodeClick handler) afvangen, je kan prima aan de Node zien wat voor een en welke het is. Dat ga je niet een x aantal keer implementeren. Hoe je van een appel een peer maakt weet ik trouwens ook niet :)

oogjes open, snaveltjes dicht


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 11:17

Janoz

Moderator Devschuur®

!litemod

@Don Facundo: Ik denk dat je class en object verward. In marcj's voorbeeld is ook maar 1 class, maar hiervan zijn dan 64 instanties. Je implementeerd dus maar 1 keer, maar instantieerd 64 keer. Verder ben ik het wel eens dat het een wat overdreven aanpak is, maar dat is om een andere reden en heb ik in de post boven je al aangegeven.

[ Voor 43% gewijzigd door Janoz op 08-03-2007 17:06 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Piels
  • Registratie: Maart 2001
  • Laatst online: 27-11 14:22
Janoz schreef op donderdag 08 maart 2007 @ 15:12:
Ik zou mijn start- en eindnode niet eens op mijn board zetten, maar gewoon als x,y coordinaat bijhouden in het gameboard. Maakt het verplaatsen een stuk makkelijker. Hoef je bij het toggelen van een wall alleen te kijken of het de start of eind node is, en als dat niet zo is de state omdraaien.
Wat bedoel je precies met "Niet op het bord zetten" van de node?

Op het moment heb ik dus eigenlijk voor elk vakje een event handler. Voor elke AStarNode2D, 1.

[ Voor 9% gewijzigd door Piels op 08-03-2007 17:50 ]

Windows Phone Apps: Belstatus, Pinautomaten


  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 09:27

mulder

ik spuug op het trottoir

Janoz schreef op donderdag 08 maart 2007 @ 17:06:
@Don Facundo: Ik denk dat je class en object verward. In marcj's voorbeeld is ook maar 1 class, maar hiervan zijn dan 64 instanties. Je implementeerd dus maar 1 keer, maar instantieerd 64 keer. Verder ben ik het wel eens dat het een wat overdreven aanpak is, maar dat is om een andere reden en heb ik in de post boven je al aangegeven.
Ja dat begreep ik ;) 64 instanties plus dat je er 64 handlers aanhangt ipv 1 die het zelfde event voor allemaal afhandeld.

oogjes open, snaveltjes dicht


  • Piels
  • Registratie: Maart 2001
  • Laatst online: 27-11 14:22
Dus dan zou ik in mijn geval, op mijn Gameboard, waar ik alle AStarNode2D aanmaak mijn eventhandler moeten plaatsen?

Windows Phone Apps: Belstatus, Pinautomaten


  • Marcj
  • Registratie: November 2000
  • Laatst online: 11:39
Piels schreef op donderdag 08 maart 2007 @ 18:29:
Dus dan zou ik in mijn geval, op mijn Gameboard, waar ik alle AStarNode2D aanmaak mijn eventhandler moeten plaatsen?
Wat ik bedoelde is dat de AStarNode2D ook een eventhandler implementeerd zodat als je deze aanmaakt, hij gelijk kan fungeren als handler voor als op die node geklikt wordt. Het kost niet meer geheugen (de instanties zijn er immers al) en het is ook nog een vrij makkelijk te programmeren, omdat je direct weet op welke node geklikt is. Het enige extra wat je dan moet doen is bij het aanmaken van de AStarNode2D ook die nieuwe instantie laten registreren als eventhandler.

Even een voorbeeld:
Java:
1
2
3
4
5
6
7
8
9
10
11
public class AStarNode2D implements MouseListener {
  //Hier staat alle andere code

  public void mouseClicked(MouseEvent e) {
    if(e.getButton() == MouseEvent.BUTTON1) {
      // linker muisknop
    } else(e.getButton() == MouseEvent.BUTTON2) {
      // rechter muisknop
    }
  }
}


Als je nu ergens die grid aanmaakt zul je toch iets hebben als:
Java:
1
2
3
4
5
6
7
8
public void createGrid() {
  for(int y = 0; y < 10; y++) {
    for(int x = 0; x < 10; x++) {
      AStarNode2D node = new AStarNode2D(x, y);
      getButton(x, y).addMouseListener(node);
    }
  }
}


Begrijp je nu wat ik bedoel? Ps. dit is in java, mbv een MouseListener. Hoe dat in C# gaat weet ik zo snel ff niet uit m'n hoofd, maar daar kan vast iets vergelijkbaars.

edit: Toch ff opgezocht hoe het ook alweer in C# ging, maar daar is dat iets anders (maar het zelfde principe)

Even een voorbeeld:
C#:
1
2
3
4
5
6
7
8
9
10
11
public class AStarNode2D {
  //Hier staat alle andere code

  public void MouseClicked(object sender, MouseEventArgs e) {
    if(e.Button == MouseButtons.Left) {
      // linker muisknop
    } else(e.Button == MouseButtons.Right) {
      // rechter muisknop
    }
  }
}


C#:
1
2
3
4
5
6
7
8
public void createGrid() {
  for(int y = 0; y < 10; y++) {
    for(int x = 0; x < 10; x++) {
      AStarNode2D node = new AStarNode2D(x, y);
      getButton(x, y).Click += new EventHandler(node.MouseClicked());
    }
  }
}


Blijkbaar moet het in C# wel een extra object kosten, of snap ik het principe niet helemaal? Kan iemand dat even beter uitleggen? (delegates etc.. snap ik toch nog niet helemaal, want ik werk daar nooit mee)

[ Voor 22% gewijzigd door Marcj op 08-03-2007 23:23 ]


  • cspare
  • Registratie: Oktober 2006
  • Laatst online: 29-07 22:19

cspare

What the deuce?!

@marcj, minor issue maar zoals Piels het uitlegde is zijn AStarNode2D klasse een GUI klasse die het hokje op het scherm tekened en dus eigenlijk ook zelf al als button dient. Hij raised dus zelf het event MouseClicked. In zijn business logic heeft hij een klasse AStarNode gedefineerd.

En een delegate is in principe niet veel anders dan een (lijst van) function pointers. Kost daarom ook vrij weinig geheugen/resources afaik.

The one who says it cannot be done, should never interrupt the one who is doing it.


Verwijderd

daarnaast zijn het ook vrij simpele klasse die mischien een paar kb extra geheugen kost. dus of dat je 64 klasse in je geheugen hebt of 1 klasse 64 maal inniteert scheelt mischien een paar honder kb in een worst case scenario.

@TS:
ik denk dat inderdaad de beste aanpak is om elke node zijn eigen state en event-handler mee te geven. tenminste ik neem aan dat elke node weet op welke x,y coordinaat deze zit anders kon je heb ook niet gebruiken voor path-finding natuurlijk.

dus dan hou je eigenlijk alleen nog de if over voor de linkse of de rechte muisknop. typische geval van overdesign en het jezelf te moeilijk maken. maar zelfs in je originele design kan ik moeilijk een situatie bedenken waarin je 5-levels diep if-statments zou kunnen gebruiken. terug naar de tekentafel dus.

  • Piels
  • Registratie: Maart 2001
  • Laatst online: 27-11 14:22
Mijn AStarNode2D is inderdaad een GUI element.

Even de flow beschrijven.

Ik maak eerst het GUI element gameboard aan. Deze vult een twee dimensionale array met AStarNode2D. Ook dit is een GUI element.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void DrawGameboard()
{
            m_Field             = new AStarNode2D[8, 8];

            for (int i = 0; i < 8; i++ )
            {
                for (int j = 0; j < 8; j++ )
                {
                    m_Field[i, j] = new AStarNode2D(this, 22, 22, i, j);
                    m_Field[i, j].Location = new System.Drawing.Point(i * (m_Field[i, j].Width + 1), j * (m_Field[i, j].Height + 1));

                    this.Controls.Add(m_Field[i, j]);
                }
            }
}


Dus als ik op een wit hokje click, wordt gewoon het mouse_click event aangeroepen.
Als de AStarNode2D waar op geklikt is nog geen node bevat, wordt deze aangemaakt. Als deze al een object AStarNode heeft, kijk ik wat er al bestaat, dus of een StartNode of een GoalNode. Deze StartNode en GoalNode wordt doorgegeven aan mijn Gameboard object, die deze gegevens nodig heeft voor het pathfinding algoritme.

Ik moet dus veel dingen controleren en daar komt eigenlijk mijn vraag vandaan. :)


Hoe kan ik dus het beste op bovenstaande condities controleren zonder een if-statement van 3 / 4 diep te krijgen.

[ Voor 5% gewijzigd door Piels op 09-03-2007 09:01 ]

Windows Phone Apps: Belstatus, Pinautomaten


  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 09:27

mulder

ik spuug op het trottoir

Je moet je realiseren dat het Gameboard de gene is die z'n weg moet vinden, niet de Nodes. Nodes hebben eigenlijk alleen eigenschappen die bepalend zijn voor de route. Je wilt dus weten waar je bent, waar je heen kunt en dan daar heen gaan. Die logica zal niet in je Node zitten. Deze hele flow is volgens mij in 1 functie/method/eventhandler te realiseren.

oogjes open, snaveltjes dicht


  • Piels
  • Registratie: Maart 2001
  • Laatst online: 27-11 14:22
Ik heb het ook precies zo geimplementeerd zoals je zegt. Logica op het Gameboard. Nodes bevatten alleen maar bepaalde eigenschappen voor het bepalen van de route.

En inderdaad, de pathfinding methode staat maar in één methode :)

Maar ik snap eigenlijk niet goed waar je heen wilt met je reply.

Windows Phone Apps: Belstatus, Pinautomaten


  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 09:27

mulder

ik spuug op het trottoir

:o ik niet wat jou vraag dan nog is, misschien zie je te veel beren op de weg? Die If's kunnen misschien mooier/korter neergezet gaan worden maar uiteindelijk heb je het mechanisme toch gewoon nodig, als dit dan doe dat :P

oogjes open, snaveltjes dicht


  • Marcj
  • Registratie: November 2000
  • Laatst online: 11:39
Piels: Waarvoor ben je dan nog zoveel ifs nodig? Het lijkt me toch dat als je het goed ontwerpt je alleen in de eventhandler moet controleren op welke muisknop is gedrukt. Hoezo ben je dan nog veel (geneste) ifs nodig?

  • Piels
  • Registratie: Maart 2001
  • Laatst online: 27-11 14:22
Ik zal al mijn if's maar even posten :)

Dit komt dus uit de klasse AStartNode2D.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
private void Node_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (m_Gameboard.StartNode != null) // Gameboard has Startnode
                {
                    if (m_Node == null)
                    {
                        m_Node = new AStarNode(null, null, this.m_ArrayX, this.m_ArrayY);
                    }

                    m_Gameboard.GoalNode = m_Node;
                    m_Node.GoalNode = m_Gameboard.GoalNode;
                }
                else if (m_Gameboard.GoalNode != null) // Gameboard has Goalnode
                {
                    if (m_Gameboard.StartNode != null)
                    {
                        m_Gameboard.GoalNode = null;
                        m_Node = null;
                    }
                }
                else if (!m_Gameboard.IsReady) // Startnode == null && Goalnode == null
                {
                    m_Node = new AStarNode(null, null, this.m_ArrayX, this.m_ArrayY);

                    m_Gameboard.StartNode = m_Node;
                    m_Node.StartNode = m_Gameboard.StartNode;
                    m_Gameboard.IsReady = false;
                }

                if ((m_Gameboard.StartNode != null) && (m_Gameboard.GoalNode != null))
                {
                    m_Gameboard.IsReady = true;
                }
            }
            else if (e.Button == MouseButtons.Right)
            {
                if (m_Node != null)
                {
                    if (m_Node.IsInAccessible)
                    {
                        m_Gameboard.InAccessibleList.Remove(m_Node);
                        m_Node = null;
                        m_Gameboard.GoalNode = m_Node;
                        m_Gameboard.IsReady = false;
                    }
                    else if (!m_Node.IsInAccessible)
                    {
                        m_Gameboard.InAccessibleList.Add(m_Node);
                        m_Node.IsInAccessible = true;
                    }
                }
                else
                {
                    m_Node = new AStarNode (null, null, this.m_ArrayX, this.m_ArrayY);
                    m_Node.IsInAccessible = true;
                    m_Gameboard.InAccessibleList.Add(m_Node);
                }
            }
            FillRectangle(m_Node);
        }


Zo ziet ie dus op het moment eruit. Ik moet dus, naar mijn inziens, kijken of bepaalde nodes al bestaan, om niet meerdere start / goal nodes te krijgen.
Maar ik hoop dus dat iemand mij kan vertellen hoe ik dit op een mooie / goede manier kan oplossen..
:)
Kan best zijn dat er wat fouten in de code staan, maar heb laatst snel wat code aangepast..

Windows Phone Apps: Belstatus, Pinautomaten


  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 09:27

mulder

ik spuug op het trottoir

Dan ga ik effe proberen een ander flow voor te stellen, pseudo (joh):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Node is null > nee: haal Node weg, isReady = (Start != null) && (Goal != null), exit
ja: new Node
if(LeftButton)
{
   if(hasStartNode)
   {
        addStartNode
    }
    else
    {
        addGoalNode
    } 
}
else(RightButton)
{
   addInAccessible
}
Maar volgens mij ik hier dan alleen niet dat je een Goal maakt als je een muur aanklikt.
Edit:
IsReady hoef je eigenlijk niet te setten, je zou gewoon de property IsReady dit kunnen laten checken
code:
1
2
3
4
5
6
7
public property string IsReady
{
    get
    {
        return ((this.StartNode != null) && (this.GoalNode != null))
    }
}

[ Voor 22% gewijzigd door mulder op 09-03-2007 18:13 ]

oogjes open, snaveltjes dicht

Pagina: 1