Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to simplify an if-statement that checks for a combination?

I'm currently working on adding sound effects to a game, and although my current code is working fine, I'm looking for a way to simplify it. Basically, each object in the game has a string value indicating its material (ie. "wood", "metal", etc.), and when two objects collide, a sound effect is played based on the combination. The code essentially looks like this:

if( (matA == "metal" && matB == "wood") || (matA == "wood" && matB == "metal") ) {     //play sound for metal-wood collision } 

But I'm wondering if there's a way to simplify the if-statement to something like this:

if( one of the materials is wood && one of the materials is metal ) {     //play sound for metal-wood collision } 
like image 214
Rimply Avatar asked Apr 17 '16 04:04

Rimply


People also ask

What operator can simplify chained if statements?

To combine the logic of nested ifs into a single if statement we use C#'s logical AND operator ( && ). This operator combines two Boolean expressions into a single true/false value. When the value on its left and the value on its right are both true , && returns true as well.

How do you refactor multiple if statements in C#?

So, how do you refactor multiple nested if statements? The easiest possible way is to use guard clauses. A guard clause is an if statement that checks for a condition and favors early exit from the current method. If the condition is satisfied, the if block returns from the method.


1 Answers

You should use an enum for materials instead of string and you can use a Dictionary to hold corresponding sound combinations. You can skip multiple if statements and select corresponding object for each material automatically using the Dictionary. For example:

[Flags] enum Material       {           Wood=1,         Iron=2,         Glass=4         //...       }   Dictionary<Material,SoundObject> sounds = new Dictionary<Material,SoundObject>();   sounds.add(Material.Wood,woodSound);   sounds.add(Material.Iron,ironSound);   sounds.add(Material.Wood | Material.Iron,woodAndIronSound);  // And play corresponding sound directly without any if statement.   sounds[object.Material].Play();   sounds[matA | matB].Play();   

Performance advantages:

You also will improve performance by using this approach. because definitely integer comparison of Enum values or hash codes would easier and faster than string comparison. And about dictionary VS multiple if-else statements, series of if/else if statements executes linearly; so its performance very depends on number of if statements and equality comparer of object; while Dictionary is based on a Hashtable. It uses an index-optimized collection to store values, which has effectively constant access time. It means often there is no matter how many keys are in dictionary, you will access to values in a constant time and in most scenarios it's very faster than multiple if statements.

Performance comparison:

We will compare performance of two approach in this example:

//If you want to try, just copy the code and see the result.   static Dictionary<char, short> myHashTable = Enumerable.Range((short)'A', (short)'z').ToDictionary((ch) => (char)ch, (sh) => (short)sh);    static void Main(string[] args)   {       System.Diagnostics.Stopwatch SW = new   System.Diagnostics.Stopwatch();       short temp = 0;       SW.Start();       for(int i=0;i<10000000;i++)       temp = getValue('z');       SW.Stop();       Console.WriteLine(SW.ElapsedMilliseconds );       SW.Reset();                   SW.Start();       for(int i =0;i<10000000;i++)       temp = myHashTable['a'];       SW.Stop();       Console.WriteLine(SW.ElapsedMilliseconds);   }   static short getValue(char input)   {       if (input == 'a')           return (short)'a';       else if (input == 'b')           return (short)'b';       else if (input == 'c')           return (short)'c';       else if (input == 'd')           return (short)'d';       else if (input == 'e')           return (short)'e';       else if (input == 'f')           return (short)'f';       else if (input == 'g')           return (short)'g';       else if (input == 'h')           return (short)'h';       else if (input == 'i')           return (short)'i';       else if (input == 'j')           return (short)'j';       else if (input == 'k')           return (short)'k';       else if (input == 'l')           return (short)'l';       else if (input == 'm')           return (short)'m';       else if (input == 'n')           return (short)'n';       else if (input == 'o')           return (short)'o';       else if (input == 'p')           return (short)'p';       else if (input == 'q')           return (short)'q';       else if (input == 'r')           return (short)'r';       else if (input == 's')           return (short)'s';       else if (input == 't')           return (short)'t';       else if (input == 'u')           return (short)'u';       else if (input == 'v')           return (short)'v';       else if (input == 'w')           return (short)'w';       else if (input == 'x')           return (short)'x';       else if (input == 'y')           return (short)'y';       else if (input == 'z')           return (short)'z';       return 0;    }  

result:

if statements with 26 items| dictionary with 122 items.
593 254
579 256
572 252
570 246
587 248
574 291
576 246
685 265
599 282
723 338

which indicates dictionary is more than 2 times faster than if/else if statements.

like image 197
mehrdad safa Avatar answered Sep 21 '22 16:09

mehrdad safa