Simon Verbeke
Simon Verbeke

Reputation: 3005

Dynamic if-statement?

I'm working on a Game of Life clone (can't link wiki, as it's down). The basic functionality is done, but I want to give the user the option to also define his own rules. The standard game of life rules are:

Cell with 2 or 3 neighbors keeps living.

Cell with 0-1 and 4-8 neighbors dies.

Dead cell with 3 neighbors becomes alive.

This is easy to do with 2 if-statements. But a user could also define something like:

Cell with 1-3 or 5-7 neighbors keeps living.

Cell with another number dies.

Dead cell with 2 or 4 neighbors becomes alive.

How can I implement this in if-statements? Can I use some sort of list to check against?

EDIT: I'm seeing some great solutions here. Will have to determine what fits my code best. For anyone still answering: I can properly handle user input, do not worry about that ;)

I will probably have a window where I ask How many neighbors to stay alive?, How many neighbours to become alive when dead?, with some textboxes. These will also check if the input is valid.

(This is C# in Unity3D)

Upvotes: 4

Views: 1989

Answers (7)

George Duckett
George Duckett

Reputation: 32438

I'd define an enum with values Propogate, Die, NoChange.

Then create a list/array, with an element of that type for each number of possibly neighbours (0 to 8). The user can then set this list some how (maybe a comma separated list of enums as strings, which is split then cast to the enum type).

Then all you'd do is count the neighbours and perform a lookup and act accordingly.

var UserActionList =
    "Die, Die, NoChange, NoChange, Propogate, Propogate, Die, Die, Die"
    .Split(',').Select(s => Enum.Parse(typeof(CellAction), s).ToArray();

// Count neighbours

swtich(UserActionList[NeighboursCount])
{
    case Die:
    /////

    case Propogate:
    /////
}

Upvotes: 1

CloudyMarble
CloudyMarble

Reputation: 37566

Well if the User is allowed to define unlimited number of rules you may need to translate, and validate User definitions and create a C# code file including a class, and run it through the CodeDom provider for C#, compile into an assembly, and execute. this file should return the resulkt of all if statetments which are generated from the User definition.

If the number of options is limited you can save a file in which you save a Vector which contains a binary array of all combinations which causes dead.

Upvotes: 0

parapura rajkumar
parapura rajkumar

Reputation: 24403

What you should probably have is something like a class

class DyingRule
{

   enum RuleResult{ Neutral , Death , Lives}; 

   //evaluates if according to this rule
   //death occurs.. pass parameter as needed
   RuleResult Evaluate();
}

And somewhere in your code you maintain a vector of them. Users are free to append the vector and add their own rules.

You evaluate them as

foreach ( currentRule in Rules )
   {
          RuleResult r = currentRule.Evaluate();
           if ( r ==  Death )
           {
                 ProcessDeath();
                 break;
           }
          else if ( r == Lives )
          {
                ProcessLiving();
                break;
          }
   } 

Optionally you can have priority for rules and sort them according if a rule supersedes another

Upvotes: 0

Giuseppe Romagnuolo
Giuseppe Romagnuolo

Reputation: 3402

I would only check those conditions that would make a cell dead. I would structure my function along the line:

bool CalculateIfDead(Cell c, int[] deadlyCountRules)
{       
   foreach(int n in deadlyCountRules)
   {
      if(c.NeighbourCount == n)
      {
         return true;
      }
   }
   return false;
}

Upvotes: 1

Reza
Reza

Reputation: 834

this is more OO and design pattern question. Here you need something similar to strategy pattern.

http://www.oodesign.com/strategy-pattern.html

Upvotes: 0

rekire
rekire

Reputation: 47945

Try a solution matix.

bool life[] = new bool[] {false, false, true, true, false, false, false, false, false};
bool die[] = new bool[] {true, true, false, false, true, true, true, true, true};
bool alive[] = new bool[] {false, false, false, true, false, false, false, false, false};

bool shouldLife=live[count];
bool shouldDie=die[count];
bool getAlive=alive[count];

Upvotes: 1

Mark Langen
Mark Langen

Reputation: 389

Well, the primary problem is the "Cell with another number _" clause. There's two options for that.

-Just disallow having that clause, and make the user specify exactly what numbers do what.

-Handle that clause as a special case last, and assign it any currently unassigned values.

The way I would implement it is with an array of #neighbours => IAction (IAction being one of Same, Kill or Grow). Since you only have a very finite number of possible neighbor counts, you can easily populate the map from the given data, and then you don't even need any if statements, just a direct call to the IAction at the index if the array associated with the current number of neighbors.

Upvotes: 0

Related Questions