Jump to content

  • Log In with Google      Sign In   
  • Create Account


Multiple switches vs if-else conditions


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
11 replies to this topic

#1 lmbarns   Members   -  Reputation: 458

Like
0Likes
Like

Posted 23 May 2012 - 11:21 AM

I'm wondering what's more efficient, using inner switches, or lengthy if-else conditions, if you have 20+ cases which have multiple options for each case?

So I prototyped a menu system for npcs, and I'm trying to figure out if I could do it better. Basically there are potentially more than 20 npcs with dialogue over several levels in the game.

Currently, when you trigger a dialogue from an npc, it calls a function makeMenu(true, npcName, interactionNum){}


Within that function is a switch for the npcName, within the npc's "case:" it has an if-else to check interactionNum and I'm wondering if a second switch would be better, within a switch?

switch(npcName){
case "smith":
	 if(interactionNum == 0){}
	 if(interactionNum == 1){}
	 if(interactionNum == 2){}
	 if(interactionNum == 3){}
break;
case "mage":
	 if(interactionNum == 0){}
	 if(interactionNum == 1){}
	 if(interactionNum == 2){}
	 if(interactionNum == 3){}
break;
//etc repeated 20x
}

Instead of:
switch(npcName){
	 case "smith:
		  switch(interactionNum){
			   case 1:
	 	 	 	 //dialogue 1
			   break;     
	 		  case 2:
	 	 	 	 //dialogue 2
	 		  break;
	 		  case 3:
	 	 	 	 .//dialogue 3
	 		  break;
}
	 case "mage":
	 	 	 switch(interactionNum){
			   case 1:
	 	 	 	 //dialogue 1
			   break;    
	 		  case 2:
	 	 	 	 //dialogue 2
	 		  break;
	 		  case 3:
	 	 	 	 .//dialogue 3
	 		  break;
}
//etc repeated 20x
}


On top of this there are quests in addition to dialogue, and it's on mobile.

Any advice or recommended reading? Thanks

Sponsor:

#2 6510   Members   -  Reputation: 151

Like
1Likes
Like

Posted 23 May 2012 - 11:31 AM

Don't use ifs or switches for that.
Create some kind of a dialog manager class which gets a game context as input and returns the appropriate dialog.
Store the dialog mapping in some external format so you can add, modify and delete without compiling.

#3 Nyndex   Members   -  Reputation: 102

Like
0Likes
Like

Posted 23 May 2012 - 11:35 AM

Whenever I see a big switch or if-else block I think of the Strategy Pattern

#4 way2lazy2care   Members   -  Reputation: 782

Like
0Likes
Like

Posted 23 May 2012 - 12:01 PM

Don't use ifs or switches for that.
Create some kind of a dialog manager class which gets a game context as input and returns the appropriate dialog.
Store the dialog mapping in some external format so you can add, modify and delete without compiling.

This is probably a better specific solution.

In general, if/else and switch performance varies by language. Generally switches are more readable for cases like this though, and rarely perform any worse than if/else. AVOID STRINGS AS SWITCH KEYS though. Much better to make some sort of enumeration/other uid that can go into the switch somehow. If/else comparisons too for that matter. String comparison can be redonkulously expensive and dangerous.

#5 lmbarns   Members   -  Reputation: 458

Like
0Likes
Like

Posted 23 May 2012 - 12:18 PM

Thanks guys. I'm using C#, and can definitely switch out the strings for an int and just keep track of which npc is which number, or an enum/list of npcs.

I thought about using xml to hold the dialogue but it seems in the switch it wasn't terribly difficult to read/edit.

Currently each npc has a collider, when the player walks close enough and collides with the trigger, it toggles the menu elements and populates them with the text from the switch. I have a GUI layout of buttons/background/text placeholders which are toggled off in a Start() function, then when the player triggers a menu it enables the proper elements and updates their content. Then if the player touches "read more" button, it increments a pageNum variable, and re-calls the same function passing itself as the argument, and the incremented pageNum gets caught in an if() conditional and overwrites the text with the next page of dialogue and enable/disables any other buttons/icons available.

This is what the prototype looks like:



#6 frob   Moderators   -  Reputation: 18373

Like
2Likes
Like

Posted 23 May 2012 - 01:24 PM

Thanks guys. I'm using C#, and can definitely switch out the strings for an int and just keep track of which npc is which number, or an enum/list of npcs.

I thought about using xml to hold the dialogue but it seems in the switch it wasn't terribly difficult to read/edit.

Currently each npc has a collider, when the player walks close enough and collides with the trigger, it toggles the menu elements and populates them with the text from the switch.


Again, the strategy pattern strongly applies here.

Have an interface such as:

IHasCollisionMenu
{
int CollisionMenuGetCount();
string CollisionMenuGetItemText(int item);
void CollisionMenuDoCommand(int index);
}

If you decide to add submenus and visual trees, just add another entry such as string GetCollisionMenuPath(). Allow your menu system to merge items with a duplicate path. The menu path to a command is just extra visual spice; you really just have a list of things to choose from regardless of if you chose to view it as a single list or as a fancy tree.


When you collide with a thing you can display whatever menu it has and let the object worry about the command details.

Don't spend time looking for micro-optimizations between if trees or switch statements in code that doesn't matter. Instead look at saving yourself hours or days of work by keeping a flexible abstract interface.
Check out my personal indie blog at bryanwagstaff.com.

#7 jefferytitan   Members   -  Reputation: 1595

Like
0Likes
Like

Posted 23 May 2012 - 08:32 PM

Indeed, in this case code speed is entirely minimal compared to ease-of-editing. This is not code which is called every frame, only when certain events happen. You don't want to recompile every time you change some dialog.

#8 Bacterius   Crossbones+   -  Reputation: 7979

Like
0Likes
Like

Posted 24 May 2012 - 05:16 AM

I agree with everyone else in the thread. Unless you are working on really high-performance code (say, a method that's executed several million/billion times per second, or a real-time scientific computation kernel), micro-optimizations which degrade code readability and maintenance are not called for (and unless you are fairly experienced with "the inner workings", the compiler will generally do a better job than you at making code run faster anyhow).

If it's just for academic interest or just pure curiosity, the short answer is: it depends on the language. In many languages a switch case is implemented as... a succession of if/else conditions, so there will be no difference. In others, a switch may be faster, or it may be much slower. The best way to tell is to time a practical example, changing the number of conditions and seeing how that affects the timings. If you're feeling adventurous you can even make a case study (no pun intended) out of it, with graphs and stuff, using various languages.

Optimizing the hell out of a bunch of conditions with hardcore assembler and insane bit hacks was useful back when computers took milliseconds to do a single calculation, where you could actually save several hours of computation with just a few tricks. Considering nowadays, a computer can add two numbers faster than an atom can decay, the gain is so minimal it is not even worth looking into. It simply doesn't make a difference unless the time saved constitutes a significant fraction of the program's actual running time.

Edited by Bacterius, 24 May 2012 - 05:23 AM.

The slowsort algorithm is a perfect illustration of the multiply and surrender paradigm, which is perhaps the single most important paradigm in the development of reluctant algorithms. The basic multiply and surrender strategy consists in replacing the problem at hand by two or more subproblems, each slightly simpler than the original, and continue multiplying subproblems and subsubproblems recursively in this fashion as long as possible. At some point the subproblems will all become so simple that their solution can no longer be postponed, and we will have to surrender. Experience shows that, in most cases, by the time this point is reached the total work will be substantially higher than what could have been wasted by a more direct approach.

 

- Pessimal Algorithms and Simplexity Analysis


#9 lmbarns   Members   -  Reputation: 458

Like
0Likes
Like

Posted 24 May 2012 - 11:21 AM

Thanks guys. I'm still trying to digest the strategy pattern within my menu system, but it looks like something I need to overcome and understand as I use A LOT of switches in my game. Not all as long as my npc menu system, but whenever I want to choose one of several scenarios....

Example is my combat system. The player has 5 sword swings, when they press the attack button, it Random.Range(minSwing, maxSwing) and passes that into a switch which performs the attack for the number generated, each attack has a different damage amount and animation. As the player unlocks new attacks, the minSwing and maxSwing are incremented, with a total of 15 attacks but you start on 0-4, and at the end of learning them all you have access to swings 10-14 which do a lot more damage than 0-4. It's basically the same as rolling a 5 sided die and performing the action for whichever number you land on.

Another case is my magic system....14 different spells accessed from putting together a combination of 4 runestones and pressing attack. 1, 2, 3, 4 individually, or 1+2, 1+3, 1+4, 2+3, 2+4, 3+4, 1+2+3, 1+3+4, etc etc etc 14 potential combinations.

I'm working within Unity, so I'm trying to wrap my head around patterns in general within Unity. When I was making a html5 javascript sprite engine I bought a book "Javascript patterns" which was perfect for that project, now I'm trying to wrap my head around classes instead of the object/prototypal inheritance. I'm halfway through an O'Reilly book called "Learning C# 3.0" which helps making the switch from arrays to lists and enums, as well as utilizing get{} and set{}.

I'm a student learning with the hopes of making something I can put on the app store. My school uses Java but I like C#. Even my crappy C# runs faster than the best OOP javascript I ever encountered with html5.

My main goal is to complete a project I can use to get an entry level job or internship to get my foot in the door and gain experience. So my lengthy switches might scare people away. Ugh.

edit::I see there are tons of "strategy pattern" examples but it seems you still have to make 20 strategies and a way for it to determine which one to choose. Is it really shorter than the switch system I have?

Edited by lmbarns, 24 May 2012 - 12:03 PM.


#10 frob   Moderators   -  Reputation: 18373

Like
0Likes
Like

Posted 24 May 2012 - 11:51 AM

I'm working within Unity, so I'm trying to wrap my head around patterns in general within Unity. When I was making a html5 javascript sprite engine I bought a book "Javascript patterns" which was perfect for that project, now I'm trying to wrap my head around classes instead of the object/prototypal inheritance.
...
My main goal is to complete a project I can use to get an entry level job or internship to get my foot in the door and gain experience. So my lengthy switches might scare people away. Ugh.

Unity3D relies heavily on composition with this pattern so I'm surprised you continue with your massive switch statements.

You frequently see code of the form FindObjectsOfType(IHasSomeFeature). You won't care if the object is a gun or a sword or a player or a door or a couch. If the object implements the interface then you get it in your list of results, and you can use the feature with it. That is what makes the pattern so powerful.



As for trying to get an entry level job, don't worry about that too much. Apply to jobs, use your game as a portfolio item no matter what state it is in; employers know that entry level workers need training before they become reasonably competent programmers.
Check out my personal indie blog at bryanwagstaff.com.

#11 lmbarns   Members   -  Reputation: 458

Like
0Likes
Like

Posted 24 May 2012 - 12:41 PM

Hmmm...I think I'm actually doing what you're talking about with my vitalBar class. I have a single vitalBar class, when you target an "enemy" it enables the vitalbar which grabs the enemyHealth script attached to the targeted "enemy" and populates the vitalBar with it's min, max, and current health.

So all monsters share the same vitalbar, it just loads the health from the active target.

I guess on each NPC I can add the dialogue (a long string or reference to wherever I store the text) for that npc and pass it to the enabled menu when the player enters the collider. Then each npc and it's dialogue is independent of one another........which makes sense.....thanks a lot.

Edited by lmbarns, 24 May 2012 - 12:43 PM.


#12 drenith   Members   -  Reputation: 101

Like
0Likes
Like

Posted 01 June 2012 - 04:05 PM

I'm a student learning with the hopes of making something I can put on the app store. My school uses Java but I like C#. Even my crappy C# runs faster than the best OOP javascript I ever encountered with html5.

Tad off topic, but I'd like to point out that Java and Javascript are actually not the same at all. Javascript is a completely seperate creation developed by a different group that just "borrowed" the name. Actual java will perform at about the same as c# (and is very very similar to c#, it's believed that microsoft "borrowed" the syntax in developing c# to make it easier to convert java developers), javascript in a browser will (as you've noticed) be much slower in general and is a decent bit different with it's prototypal inheritance instead of classes.

http://www.java.com/en/download/faq/java_javascript.xml

Edited by drenith, 01 June 2012 - 04:07 PM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS