1

I've just started to learn Java, and I'm pretty new.

I am trying to create a very simple text based RPG game in Java.

I have created a class called "enemy". This class contains certain variables, such as a string for the enemy's name, integers for the enemy's health, damage, and so on. With this "enemy" class, I create specific enemies. For example, using the "enemy" class, I'll make a zombie enemy and assign certain values to the above mentioned variables.

What I would like to be able to do is to have a random enemy encounter. For example, lets say I have a zombie enemy, giant spider enemy, and an assassin enemy, each with values assigned to variables within the "enemy" class, I would like to have a random battle encounter. The zombie appear maybe 45% of the time, the spider 25% of the time, and the assassin, 30% of the time.

How can I do this or something similar? Any tutorials maybe?

Sorry if I'm not making much sense...

jmarkmurphy
  • 11,030
  • 31
  • 59
gurgy11
  • 37
  • 5
  • 1
    Code is the universal language of programmers, you know. Better than words – Dici Jul 10 '16 at 04:19
  • What have you tried so far and where are you stuck? As mentioned above, code is a must in these kind of circumstances. – Michael Jul 10 '16 at 04:20

2 Answers2

5

This would be the general format for acheiving that (as in a uniform probability of selecting an Enemy):

Enemy[] enemies = new Enemies[10];
//fill in your array with a bunch of enemies
//...
//ahh, time for a battle encounter!
int randIndex = new Random().nextInt(enemies.length);
Enemy encounterEnemy = enemies[randIndex];
//now you can use encounterEnemy for the simulated battle

Note: the random element selection was taken from here

For different probabilities of Enemy selection

The idea is to create a random double in the range of 0-1, then based on different ranges within that, select/create an Enemy. In this case, an array would not make sense.

double randVal = Math.random();
Enemy encounterEnemy;
if (randVal < 0.25){
    encounterEnemy = createZombie();
}else{
    encounterEnemy = createGiantSpider();
}

In this case, there's a 25% probability of running into a zombie, and a 75% chance of running into a giant spider.

Community
  • 1
  • 1
Michael
  • 2,673
  • 1
  • 16
  • 27
  • This does not meet the requirement of being able to selectively pick the probability of each outcome. In your case, all enemies have the same likelihood to be picked – Dici Jul 10 '16 at 04:35
  • A bit better, but still not enough to be fully generic. You only support a fixed number of variants of enemy. How about an arbitrary number of enemies ? – Dici Jul 10 '16 at 04:42
  • @Dici You offer a better generalized solution. I wanted to steer clear of creating methods and such for the sake of simplicity. – Michael Jul 10 '16 at 04:45
  • What if I want different enemies to have different specific stats? For example, the zombie has 50 health, drops 10 gold, while the spider has 30 health, 5 gold. I guess what I'm asking is, how can I assign a few variables to the items in the array? BTW, thanks for the answer above! :) – gurgy11 Jul 10 '16 at 04:50
  • @gurgy11 *What if I want different enemies to have different specific stats?* The entire creation of a zombie, which includes its stats, should be handled in `createZombie`. The same goes for a `GiantSpider` and so on. – Michael Jul 10 '16 at 04:51
  • I just wonder how come this solution has 5 upvotes and mine 0, while being less general. @gurgy11 did you have trouble grasping my answer ? I'm positive it would give you more flexibility and maintanability in your design – Dici Jul 10 '16 at 14:52
  • @Dici I believe it's because your solution forces conditions onto the caller that are quite easy to mess up. It also introduces tight dependencies between the implementation and interface. Mine, while not as generalized, is a bit more direct and offers a more proof-of-concept answer. – Michael Jul 10 '16 at 15:47
  • @Michael the list needs to be sorted, that's pretty much it. Also, I don't really get your point with the "implementation and interface" – Dici Jul 10 '16 at 17:09
  • @Dici I don't want you to take this the wrong way, but Michael's answer had a bit more explaining with it, which, in my opinion, made it easier for a me to understand. I appreciate your answer though :) – gurgy11 Jul 10 '16 at 18:25
  • @gurgy11 is that so ? :D Two lines per snippet, just like me, and I believe it's the right level of detail for both answers which do not involve complex code. There's only so much you can say about a 4 lines code. Good code is self-explanatory. – Dici Jul 10 '16 at 19:16
  • @Dici You have a point. But I don't think you should get mad over this xD. Besides, I'm pretty new to this stuff, heck, I don't even really know which of the two answers is actually the best. – gurgy11 Jul 11 '16 at 10:15
  • @gurgy11 Haha I'm not mad, I'm just surprised. But it happens, for example I have made a few answers which got a large amount of votes (like 40-50) while they were trivial. On the contrary, some complex answers I was proud of received just a few upvotes. The real probelm with that is that most future visitors will take the first answer as the best one, while it's not always true. – Dici Jul 11 '16 at 16:56
0

If you put your Enemy instances in a list, and have a separate sorted list to store the probabilies, you can do the following to pick one randomly:

// in real code you would have to build this list and check it is sorted in reverse order
// and that the total sum is 100
List<Double> probabilities = Arrays.asList(45, 30, 25);
List<Enemy> enemies = Arrays.asList(new Zombie(), new Spider(), new Assassin());

public static Enemy randomEnemy(List<Enemy> enemies, List<Double> probabilities) {
    double d = Math.random();
    double threshold = 0;

    for (int i = 0; i < probabilities.size(); i++) {
        threshold += probabilities.get(i) / 100;
        if (d < threshold) return enemies.get(i);
    }
    throw new IllegalArgumentException("Probabilities don't add up to 1. Total: " + threshold);
}
Dici
  • 25,226
  • 7
  • 41
  • 82