Java – how to write a probabilistic algorithm that can be easily maintained?

Suppose I want to create a game At the beginning of the game, the player will choose a monster

It's easy to choose monsters fairly

// get all monsters with equal chance
public Monster getMonsterFair(){
    Monster[] monsters = {new GoldMonster(),new SilverMonster(),new BronzeMonster()};
    int winIndex = random.nextInt(monsters.length);
    return monsters[winIndex];
}

Choose monsters unfairly

// get monsters with unequal chance
public Monster getMonsterUnFair(){
    double r = Math.random();
    // about 10% to win the gold one
    if (r < 0.1){
        return new GoldMonster();
    }
    // about 30% to winthe silver one
    else if ( r < 0.1 + 0.2){
        return new SilverMonster();
    }
    // about 70% to win the bronze one
    else {
        return new BronzeMonster();
    }   
}

The problem is, when I add a new monster to the game, I have to edit if else Or I'll change my chance to win goldmonster to 0.2. I have to change all 0.1 to 0.2. It's ugly and not easy to maintain

// get monsters with unequal change & special monster
public Monster getMonsterSpecial(){
    double r = Math.random();
    // about 10% to win the gold one
    if (r < 0.1){
        return new GoldMonster();
    }
    // about 30% to win the silver one
    else if ( r < 0.1 + 0.2){
        return new SilverMonster();
    }
    // about 50% to win the special one
    else if ( r < 0.1 + 0.2 + 0.2){
        return new SpecialMonster();
    }
    // about 50% to win the bronze one
    else {
        return new BronzeMonster();
    }
}

How can this probabilistic algorithm be refactored so that code can be easily maintained when adding new monsters and adjusting the chances of winning monsters?

Solution

Basically what @ Egor skriptunoff said This should be easy to expand You can use the collection of class < monster > If you don't want to use enumeration

enum Monster {
    GOLD(1),SILVER(3),BRONZE(6) // pseudo probabilities

    private int weight;
    // constructor etc..
}

public Monster getMonsterSpecial() {
    List<Monster> monsters = new ArrayList<>();

    for(Monster monsterType : Monster.values()) {
        monsters.addAll(Collections.nCopies(monsterType.getWeight(),monsterType)); 
    }

    int winIndex = random.nextInt(monsters.length);
    return monsters.get(winIndex);
}

You may be able to enumerate the monster plural and point it to a class if you also want to instantiate the monster class I just want to make this example clearer

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>