Resource Mining Techniques - GT6

I have natrual resources avaialable on asteroids, moons, planets, etc…
My data feed for these from file looks like so: 0 521 147487 1459 204 0 0 0
Defined as so:
Gemstones 0
Metal Alloys 521
Metal Ores 147487
Minerals 1459
Precious Metals 204
Seeds 0
Spices 0
Water 0

I am trying to rework my ship mining laser system and base it on a “most avaialable is more likely to be mined.” When a ships mining laser is fired, it pings the server, and gets a result back. Right now it is based on a hardcoded percentage system with a Random int used to find what you get.
That method works for the above quantities because it was designed on that default asteroid set up. But…not all planetoids are the same. A moon made of ice may only have water and minerals available.

Ice Moon example:
Gemstones 0
Metal Alloys 0
Metal Ores 0
Minerals 14591
Precious Metals 0
Seeds 0
Spices 0
Water 578471

Any suggestions on how to take my numbers and base a “selection criteria” on the quantities? Should a mining laser ping possible return nothing?

Hi
Add up the total amount of all resources for the whole object, and then divide each resource quantity by that number (skipping 0s)

0 521 147487 1459 204 0 0 0

total = 149671

0 0.00348 0.98540 0.00974 0.00136 0 0 0

then you can do a Math.random and go along adding them up untill you go over that value, and pick that one. eg

Math.random() = 0.5234

0 + 0.00348 < 0.5234 so carry on
0 + 0.00348 + 0.98540 >= 0.5234 so that is what they mined

in this case you are really heavily weighted to the metal ores, but I suspect that is the point, in the last case you will most likely end up on water when you go over the random value

I know I explained it like you are a 4 year old, but my explaination in text was really really bad, so I put in noddy examples of what I meant :slight_smile:

As for returning nothing, I think unless you have a skill level attached to mining, then probably not, if you have some kind of skill level then you can just use that as an instant roll to work out if you even want to bother working out what they mined.

HTH

Endolf

Sounds good. But in cases where I have heavy weight in ore (for example), you will rarley get past it, and if you do, and the next item is less, then you will always get the next item and never make it further…I think. I will put it into code and give it a test. Thanks!!

Hi
Re not getting past heavily weighted objects, thats the point of them :), you have as much chance of getting <0.1 as you do of getting >=0.9, if you had 3 types, at 0.1, 0.8 and 0.1, then you would get the bottom and top ones as often as each other, roughtly 10% of the time you get the first, and roughly 10% you get the top, the other 80% you get stuck in the middle, which is the point of the high weighting :slight_smile:

I think that makes sence :slight_smile:

Endolf

No, I don’t think that’s how it works. Or maybe I’m reading it wrong. It basically looks like Endolf calculates the percentage of each item in the rock, then rolls math.random to get a percentage value. Whatever range the random falls into, that’s the item you get. In that case, you’d just have better odds of getting the material in greater quantity, but if a few other minerals had equal but smaller amounts, then you’d have an equally small chance of getting any one of them, as compared to the item you have the most of.

Hi
Thats exactly it :slight_smile:

Endolf

makes sense, but is stumping me at one place…

items on rock

0 0 1400 50010 200 1900

You may get past #4 on rare occasion, but you would never get past #5 to get to #6 because being larger than what is need to get #4 will always be large enough to get #5, thus #6 is never reached…

or did my brain freeze ;D

… ok after further review I understand and also relized I was increment the random, instead of the percentage totals…My last test got 4 #4’s and 1 #5. Now to see if I can get to # 6…

Thanks again!

Ok, I’ve written some test code, get it here. I get some nice looking results, like

Failed to mine anything: 9976
Gemstones              : 0
Metal Alloys           : 293
Metal Ores             : 88775
Minerals               : 843
Precious Metals        : 113
Seeds                  : 0
Spices                 : 0
Water                  : 0

Failed to mine anything: 9934
Gemstones              : 0
Metal Alloys           : 0
Metal Ores             : 0
Minerals               : 2167
Precious Metals        : 0
Seeds                  : 0
Spices                 : 0
Water                  : 87899

Thats over the two different objects you gave us with 100000 attempts to mine on each. It looks right, I’ve got in a 90% proficient miner there :slight_smile:

HTH

Endolf

Thanks a ton. Appreciate tht time you put into that! I actually took you reply lterally earlier and came up with this:

      public void sendMiningLaserResults(Connection con) {
            System.out.println();
            System.out.println();
            byte[][] args = new byte[3][];
            
            double total = 0.0;
            for(int i=0;i<naturalResources.length;i++) {      
                  total += naturalResources[i];
            }      
            // the chance roll d100
            double chance = Math.random();
            double runningTotal = 0.0;
            double[] percents = new double[naturalResources.length];
            for(int i=0;i<percents.length;i++) {
                  percents[i] = naturalResources[i]/total;
            }
            // get the resource mined
            for (int i=0;i<percents.length;i++) {
                  runningTotal += percents[i];
                  if(runningTotal > chance) {
                        // this is what is mined
                        if(con.hasCargoSpace(1)) {
                              // get resource
                              naturalResources[i]--;
                              int ind = getProductIndex(resourceNames[i]);
                              con.addCargo(ind, 1);

                              args[0] = ProtocolHelper.intToByteArray(1);  // 1 = success
                              args[1] = ProtocolHelper.intToByteArray(ind);// id of prod
                              args[2] = ProtocolHelper.intToByteArray(1);       // quantity
                              //con.addExperience(1);
                        }
                        else {
                              args[0] = ProtocolHelper.intToByteArray(0);
                        }
                        con.send(CMD_SHIPMININGLASER, args);
                        System.out.println(con.getAlias() + " mined: " + resourceNames[i]);
                        return;      
                  }      
            }
            
      }

This seems to work pretty well, but I may incorporate some of your system. Mine is set up to not have a fail, but I may change that.

Now that I review it again, I DO like your proficiency check…I have 9 blank skill slots in my player object…may have to make one mining_prof.