GML [SOLVED] How to make a script to have 10³ (1000) options without code duplication?

Discussion in 'Programming' started by jobjorgos, Apr 12, 2017.

  1. jobjorgos

    jobjorgos Member

    Joined:
    Jun 23, 2016
    Posts:
    147
    Hello!

    I have a character with multiple choosable equipments as helm/chest/pants which each gives an amount of armor depending on which one is equiped (global.helm=0 for example means no helm is equiped).
    In the user interface the total amount of armor is drawn, after it has been caculated.

    A little problem now is that I need extreme much of combinations in a ultra long script to fit every combination of armor equiped. I have about 10 difference helms/chests/pants, this would requires 10x10x10 = 1000 combinations, and that is mission impossible.:(

    So, does anybody know a way to make the following script more automatic?
    Code:
    //global.helm=0 means +0 armor
    //global.helm=1 means +2 armor
    //global.helm=2 means +12 armor
    //global.chest=0 means +0 armor
    //global.chest=1 means +1 armor
    //global.chest=2 means +17 armor
    //global.pants=0 means +0 armor
    //global.pants=1 means +1 armor
    //global.pants=2 means +11 armor
    
        if (global.chest==0) and (global.pants==0) and (global.helm==0){
            draw_text(1214,793,'0');
        }else
        if (global.chest==1) and (global.pants==0) and (global.helm==0){
            draw_text(1214,793,'1');
        }else
        if (global.chest==2) and (global.pants==0) and (global.helm==0){
            draw_text(1214,793,'17');
        }else
        if (global.chest==0) and (global.pants==1) and (global.helm==0){
            draw_text(1214,793,'1');
        }else
        if (global.chest==1) and (global.pants==1) and (global.helm==0){
            draw_text(1214,793,'2');
        }else
        if (global.chest==2) and (global.pants==1) and (global.helm==0){
            draw_text(1214,793,'18');
        }else
        if (global.chest==0) and (global.pants==2) and (global.helm==0){
            draw_text(1214,793,'11');
        }else
        if (global.chest==1) and (global.pants==2) and (global.helm==0){
            draw_text(1214,793,'12');
        }else
        if (global.chest==2) and (global.pants==2) and (global.helm==0){
            draw_text(1214,793,'28');
        }else
        if (global.chest==0) and (global.pants==0) and (global.helm==1){
            draw_text(1214,793,'2');
        }else
        if (global.chest==1) and (global.pants==0) and (global.helm==1){
            draw_text(1214,793,'3');
        }else
        if (global.chest==2) and (global.pants==0) and (global.helm==1){
            draw_text(1214,793,'19');
        }else
        if (global.chest==0) and (global.pants==1) and (global.helm==1){
            draw_text(1214,793,'3');
        }else
        if (global.chest==1) and (global.pants==1) and (global.helm==1){
            draw_text(1214,793,'4');
        }else
        if (global.chest==2) and (global.pants==1) and (global.helm==1){
            draw_text(1214,793,'20');
        }else
        if (global.chest==0) and (global.pants==2) and (global.helm==1){
            draw_text(1214,793,'13');
        }else
        if (global.chest==1) and (global.pants==2) and (global.helm==1){
            draw_text(1214,793,'14');
        }else
        if (global.chest==2) and (global.pants==2) and (global.helm==1){
            draw_text(1214,793,'30');
        }else
        if (global.chest==0) and (global.pants==0) and (global.helm==2){
            draw_text(1214,793,'12');
        }else
        if (global.chest==1) and (global.pants==0) and (global.helm==2){
            draw_text(1214,793,'13');
        }else
        if (global.chest==2) and (global.pants==0) and (global.helm==2){
            draw_text(1214,793,'29');
        }else
        if (global.chest==0) and (global.pants==1) and (global.helm==2){
            draw_text(1214,793,'13');
        }else
        if (global.chest==1) and (global.pants==1) and (global.helm==2){
            draw_text(1214,793,'14');
        }else
        if (global.chest==2) and (global.pants==1) and (global.helm==2){
            draw_text(1214,793,'30');
        }else
        if (global.chest==0) and (global.pants==2) and (global.helm==2){
            draw_text(1214,793,'23');
        }else
        if (global.chest==1) and (global.pants==2) and (global.helm==2){
            draw_text(1214,793,'24');
        }
        if (global.chest==2) and (global.pants==2) and (global.helm==2){
            draw_text(1214,793,'40');
        }
    
    In the example above I have 27 combinations because I have 2 helms/chests/pants and for each the option to not wear a helm/chest/pants at all which cause 3x3x3=27 options.

    In case I add more helms/chests/pants the script would become waaay to long.
     
  2. arirish

    arirish Member

    Joined:
    Mar 13, 2017
    Posts:
    266
    Code:
    var h,c,p;
    switch (global.helm) {
    case 0: h=0; break;
    case 1: h=2; break;
    case 2: h=12; break;
    }
    switch (global.chest) {
    case 0: c=0; break;
    case 1: c=1; break;
    case 2: c=17; break;
    }
    switch (global.pants) {
    case 0: p=0; break;
    case 1: p=1; break;
    case 2: p=11; break;
    }
    draw_text(1214,793,string(h+c+p))
    Or something. I bet someone can come up with something even better, but because your armor numbers were so random I couldn't think of one.
     
    jobjorgos likes this.
  3. jobjorgos

    jobjorgos Member

    Joined:
    Jun 23, 2016
    Posts:
    147
    Hmm that looks like what I needed
    I gonna try it out and will post a update to confirm if it worked.
    Thanks alot for the help this looks very efficient
     
  4. Cloaked Games

    Cloaked Games Member

    Joined:
    Jul 4, 2016
    Posts:
    792
    No offense, but the first code there almost killed me. I'm glad you asked for help...

    I have a game with a lot of items that all do different things. Here's what I would recommend if it's going to get any more complicated than what you have here already. This is possibly more than you need, but if it makes sense to you, then it may be useful. Can't tell if I explained it well or not.

    You can store all of the information about the armor types in a big ds grid. Each item or armor would have an ID number, in numerical order. You create these id's via an enumerator, this also lets you access them by a name instead of just an arbitrary number:
    Code:
    enum armor
     {
     HELMET_WOOD,
     PANTS_WOOD,
     CHESTPLATE_WOOD,
     HELMET_STEEL,
     PANTS_STEEL,
     CHESTPLATE_STEEL
     }
    Then, there is a corresponding grid, where each row is a different item, and each column stores a certain piece of information about them.

    First:
    Code:
    enum stat
     {
     NAME,
     TYPE,
     ARMOR
     }
    
    global.item_index = ds_grid_create(<total items>, <total stats>);
    Then a script can be used to fill all of those slots in the grid with the information for each new item.
    Code:
    ///scr_create_helmet(item ID, name, armor)
    
    global.item_index[#argument0, stat.NAME] = argument1;
    global.item_index[#argument0, stat.TYPE] = type.HELMET;
    global.item_index[#argument0, stat.ARMOR] = argument2;
    
    To create a new helmet, add it's ID into the item enum and then run this line:
    Code:
    scr_create_helmet(item.HELMET_STEEL, "Steel Helmet", 17);
    Then when you want to get the total protection from armor:
    Code:
    total_armor = global.item_index[#global.chest, stat.ARMOR] + global.item_index[#global.pants, stat.ARMOR] + global.item_index[#global.helmet, stat.ARMOR];
    This requires a bit more overhead initially, but it scales infinitely for any number of items. And, most importantly, it allows you to make items of any sort of type. You can use the same exact system to find out how much damage a sword does, or how much a potion should heal you, or what lock a key opens. You just add a new item to the enum and fill out the relevant information in the grid. Your current system (with either code option suggested here) would quickly spiral out of control as soon as you added new stuff.
     
    arirish likes this.
  5. bojack29

    bojack29 Member

    Joined:
    Jun 21, 2016
    Posts:
    407
    Why don't you do things like an RGB format?
    Code:
    var s = global.chest + global.helm * 10 + global.pants * 100;
    draw_text(x, y, string(s));
    
    This is based on a series of 10. Every variable fits inside another to give you a unique number for all sets. This is exactly colours in RGB work as well.
     
  6. jobjorgos

    jobjorgos Member

    Joined:
    Jun 23, 2016
    Posts:
    147
    Thanks Cloaked Games for that explanation,
    it looks very proffesional and efficient, but also a downside is that it is extreme abstract and with my scripting knowledge it gonna be hard even when I littarly copy what you made.
    Is your way of scripting called object oriented programming?

    Hmm a RGB format? I know every color has an unique code that is caculated by red/green/blue 0-255 x 0-255 x 0-255. But then I still got the problem that I have to assign 1000 results, unless I miss the point of what you meaning.

    I still rather to use arirish method, its simple and good enough for me even while it could be more efficient.
    arirish methods also seems to work good so far:D
    I'm a person who cares more on the final result, than on how to get there even when its programmed ugly as hell :p
     
  7. Cloaked Games

    Cloaked Games Member

    Joined:
    Jul 4, 2016
    Posts:
    792
    No problem. It wouldn't work if you just copied what I wrote anyways. It's a system that works well if you understand it, but I've got 5 years of GML experience behind that system so it is probably more complicated than what you need. Do what you understand and what works! One clarification, as far as I know, it has nothing to do with object oriented programming, but the difference between that and regular programming is nebulous to me as well.

    I'm glad you figured it out, good luck!
     
    jobjorgos likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice