Thread: What's the best way to handle many program options?

  1. #16
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Here's some sample code I just wrote. Take a look at it and you'll see what I'm trying to explain. Does it do what you want it to do?
    Code:
    #include <stdio.h>
    
    struct data_t {
        int n;
        int (*func)(int x, int n);
        const char *name;
    };
    
    int func_add(int x, int n) { return x + n; }
    int func_multiply(int x, int n) { return x * n; }
    int func_subtract(int x, int n) { return x - n; }
    
    void permutations(int x, struct data_t *data, size_t n);
    
    int main() {
        struct data_t data[] = {
            {3, func_add, "+"},
            {3, func_multiply, "*"},
            {1, func_subtract, "-"}
        };
        
        permutations(17, data, sizeof(data)/sizeof(*data));
        
        getchar();
        return 0;
    }
    
    void permutations(int x, struct data_t *data, size_t n) {
        if(!n) return;
        
        permutations(x, data + 1, n - 1);
        printf("&#37;d %s %d = ", x, data[0].name, data[0].n);
        x = (*data[0].func)(x, data[0].n);
        printf("%d [%d]\n", x, 3-n);
        permutations(x, data + 1, n - 1);
        
        putchar('\n');
    }
    [edit] Wait, I think my algorithm is flawed . . . [/edit]

    [edit=2] This simpler program works better:
    Code:
    #include <stdio.h>
    
    void permutations(int *data, size_t n, const char *prev);
    
    int main() {
        int data[] = {1, 2, 3};
        
        permutations(data, sizeof(data)/sizeof(*data), "combination:");
        
        getchar();
        return 0;
    }
    
    void permutations(int *data, size_t n, const char *prev) {
        char stack[100];
        
        if(!n) return;
    
        permutations(data + 1, n - 1, prev);
    
        sprintf(stack, "%s %d", prev, *data);
        printf("%s %d\n", prev, *data);
    
        permutations(data + 1, n - 1, stack);
    }
    [/edit]

    [edit=3] There you go, this one's much easier to understand:
    Code:
    #include <stdio.h>
    
    struct data_t {
        int n;
        int (*func)(int x, int n);
        const char *name;
    };
    
    int func_add(int x, int n) { return x + n; }
    int func_multiply(int x, int n) { return x * n; }
    int func_subtract(int x, int n) { return x - n; }
    
    void permutations(int x, struct data_t *data, size_t n, const char *prev);
    
    int main() {
        struct data_t data[] = {
            {3, func_add, "+"},
            {3, func_multiply, "*"},
            {1, func_subtract, "-"}
        };
        
        permutations(17, data, sizeof(data)/sizeof(*data), "combination:");
        
        getchar();
        return 0;
    }
    
    void permutations(int x, struct data_t *data, size_t n, const char *prev) {
        char stack[BUFSIZ];
        int t;
        
        if(!n) return;
        
        permutations(x, data + 1, n - 1, prev);
        
        t = (*data[0].func)(x, data[0].n);
        sprintf(stack, "%s [%d %s %d = %d]", prev, x, data[0].name, data[0].n, t);
        puts(stack);
        
        permutations(t, data + 1, n - 1, stack);
    }
    Have you ever programmed a solution to the Towers of Hanoi? It's quite similar to this. [/edit]

    [edit=4] Here's the Wikipedia entry for "Towers of Hanoi": http://en.wikipedia.org/wiki/Tower_of_Hanoi
    It includes a recursive solution written in C. [/edit]
    Last edited by dwks; 06-05-2007 at 01:03 AM.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  2. #17
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I think that last post has enough edits, time for a new one.

    In case you can't run it, here's the output from the last program in the previous post:
    Code:
    combination: [17 - 1 = 16]
    combination: [17 * 3 = 51]
    combination: [17 * 3 = 51] [51 - 1 = 50]
    combination: [17 + 3 = 20]
    combination: [17 + 3 = 20] [20 - 1 = 19]
    combination: [17 + 3 = 20] [20 * 3 = 60]
    combination: [17 + 3 = 20] [20 * 3 = 60] [60 - 1 = 59]
    As you can see, though the order is reversed, the program calculates all possible combinations, "permutations" if you will.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #18
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    My 2D game made in August of 2006 has over 200 options. In it, I used a bunch of if statements nested inside one another and it wasn't unusual to see 6 levels of nested ifs for several dozen options/settings. Basically, it went like this:

    Code:
    if (OptionSelected[0] == 1) // first option
    {
    	if (OptionSelected[1] == 1) // first option of the submenu
    	{
    		// do stuff that the option refers to
    	}
    	
    	else if (OptionSelected[1] == 2) // second option of the submenu
    	{
    		if (OptionSelected[2] == 1) // another submenu's first option
    		...
    	}
    	
    	else // last option
    	{
    		OptionSelected[0] = 0; // allows for going up a menu level for going back
    	}
    }
    
    else if (OptionSelected[0] == 2) // second option on the main menu
    {
    	// do stuff
    }
    Perhaps something similar could be used.
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  4. #19
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    This whole thread is about how to avoid that sort of code! From the original post:
    A massive function full of nested if statements doesn't sound good to me.
    The code I provided, a recursive Towers-of-Hanoi type function, will find every permutation of its arguments, which is a much cleaner solution than a bunch of nested if statements.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #20
    Registered User
    Join Date
    Oct 2006
    Posts
    250
    You should read up on the concept of a parse tree.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Program optimization
    By a.mlw.walker in forum C Programming
    Replies: 1
    Last Post: 03-27-2009, 06:12 AM
  2. Direct3D problem
    By cboard_member in forum Game Programming
    Replies: 10
    Last Post: 04-09-2006, 03:36 AM
  3. Encryption program
    By zeiffelz in forum C Programming
    Replies: 1
    Last Post: 06-15-2005, 03:39 AM
  4. Date program starts DOS's date
    By jrahhali in forum C++ Programming
    Replies: 1
    Last Post: 11-24-2003, 05:23 PM
  5. fopen();
    By GanglyLamb in forum C Programming
    Replies: 8
    Last Post: 11-03-2002, 12:39 PM