Jump to content
  • Advertisement
Sign in to follow this  
Gary the Llama

How to implement a set of rules...

This topic is 4835 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Let's say I have an array:
a[5];
Each element in the array will hold a random integer, ranging from 1-8. I want to implement a set of rules to check against the elements of the array. For instance... The first rule is this: Out of the 5 elements, 2 of them MUST be 7 or 8 and the others can be any other value (1-6). What's the best way to check whether my array will meet this rule? There are 16 more rules I'll need to check for too, so the implementation needs to be flexible. I've been racking my brain all night and I have yet to figure out a solution. (If it matters the values 1-6 will represent colors, 7 and 8 will represent a side.) Edit: I'm coding this in C++/OOP.

Share this post


Link to post
Share on other sites
Advertisement
You can always create a function that you pass a value through a parameter to be put in the posiiton of the array and you can do the checking there.

Share this post


Link to post
Share on other sites
Elegantly parameterizing a ruleset is one of the trickiest tasks in computer science. The first step is to abstract all the rules into one form. In your case, it sounds like the form will be something like "at least X elements must be in the set Y". You could then parameterize the rule you gave as [X=2, Y={7,8}]. Of course, it's possible that your other rules won't fall into that pattern. You can break them up into groups, each of which has its own form, or try to find a form which encapsulates all possible rules.

Can you give 3-4 other example rules?

Share this post


Link to post
Share on other sites
I'll explain a bit more. The game revolves around nuts that act as dice. When you "roll" a nut, it can either fall down (hole facing up) or land on one of it's 6 sides. There are 2 colors per 6 sides for a total of 3 colors. (In other words, 2 sides of the nut contain blue, 2 contain red, and 2 contain yellow.) I'm trying to simulate the 5 nuts being rolled. Here are the first few rules:

1. TWO holes / THREE standing (any color)
2. THREE holes / TWO standing (any color)
3. FOUR standing (any color)
4. At least THREE standing, ONE OF EACH COLOR (1 blue, 1 red, 1 yellow)
5. THREE holes / A pair of equal colors standing

I hope this helps...

Share this post


Link to post
Share on other sites
Heh... you've just described, in remarkably few rules, a system that really should have a full first-order logic checker for full parameterization. Instead, I suggest you take the other tack, splitting them into groups. Further, you can split them into clauses which are ANDed together.

Now, I have to ask: do you want these rules to be data driven, or can they be code-driven? Data-driven will be much more difficult.

Share this post


Link to post
Share on other sites
I guess you could have something like this:


CheckRule(int min_amount, std::vector<int> match_set, std::vector<int> set);


Pass it these values:

min_amount: The number of values in the set that must match something from match_set.

match_set: The set of numbers to be checked against (like 7, 8 or 1, 2, 3, 4, 5, 6)

set: The array of numbers to check against the ruleset.

This sounds like homework, so I'll let you sort out the implementation :)

Share this post


Link to post
Share on other sites
If they're hard-coded it's not too difficult to write a set of functions that test the basic elements of your rules and can be combined to test the rules:


#include <algorithm> // for std::count_if

bool is_blue(int nut) { return nut == 1 || nut == 2; }
bool is_red(int nut) { return nut == 3 || nut == 4; }
bool is_yellow(int nut) { return nut == 5 || nut == 6; }

const int num_nuts = 5;
int nuts[num_nuts];

int num_blue = std::count_if(nuts, nuts+num_nuts, is_blue );
int num_red = std::count_if(nuts, nuts+num_nuts, is_red );
int num_yellow = std::count_if(nuts, nuts+num_nuts, is_yellow);
int num_standing = num_blue + num_red + num_yellow;
int num_holes = num_nuts - num_standing;

int num_colors = (num_blue>0) + (num_red>0) + (num_yellow>0);
int num_pairs = (num_blue>1) + (num_red>1) + (num_yellow>1);
int num_triples = (num_blue>2) + (num_red>2) + (num_yellow>2);

bool rule1 = num_standing == 3; // Implies 2 holes with 5 nuts
bool rule2 = num_standing == 2; // Implies 3 holes with 5 nuts
bool rule3 = num_standing == 4; // Implies 1 hole with 5 nuts
bool rule4 = num_colors == 3; // Implies at least 3 standing
bool rule5 = num_holes == 2 && num_pairs == 1;


Any more rules you need implemented?

Share this post


Link to post
Share on other sites
Fruny's example is how I would do it in C++. std::count and std::count_if can save you a fair amount of code here. Out of interest - because a lot of people do this - are you randomly generating an array, testing for compliance, and if it fails, regenerating the array until it complies? If so, a better way of doing it is usually to generate a compliant array in a predetermined order and then shuffle it using std::random_shuffle.

As an aside, Fruny's code also shows why I would not do this sort of thing in C++ if I could avoid it. :)

Python example:

arrayIsOk = (a.count(7) + a.count(8) = 2) and (len(a) = 5)

You probably wouldn't even need the last check.

Share this post


Link to post
Share on other sites
I'd have started in a completely different place. "I need a set of 16 rules but I'm not sure how to make them" means to me "I need to make a base class called 'rule' and derive 16 concrete classes from it"

class rule
{
bool matches(int a[5]) = 0;
};

class my_rule : public rule
{
bool matches(int a[5]) { hard coded test; }
};

It ends up more flexible but also larger than the parameterized version people have suggested. It can cope, with remarkably little change, with a new rule involving "3 yellow if there are 2 red, or 1 blue and 4 yellow if there is only 1 red" which doesn't fit in the original pattern of rules. The best thing about it is that when faced with the original problem, it's obvious how to work out a solution this way. The worst thing about it is that it is more complicated than it needs to be. It probably isn't the best solution in your case, but it isn't _bad_.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!