Public Group

# 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.

## 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 on other sites
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 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 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 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 on other sites
Can you give a C++ example of splitting them into groups? :)

Code-driven is fine. There are 16 total rules. They'll be hard coded and never change.

##### 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 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_ifbool 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 nutsbool rule2 = num_standing == 2;  // Implies 3 holes with 5 nutsbool rule3 = num_standing == 4;  // Implies 1 hole with 5 nutsbool rule4 = num_colors == 3;    // Implies at least 3 standingbool rule5 = num_holes == 2 && num_pairs == 1;

Any more rules you need implemented?

##### 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 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_.

1. 1
2. 2
Rutin
19
3. 3
4. 4
5. 5

• 9
• 9
• 9
• 14
• 12
• ### Forum Statistics

• Total Topics
633301
• Total Posts
3011270
• ### Who's Online (See full list)

There are no registered users currently online

×