java – 如何编写一个可以轻松维护的概率算法?

假设我想创造一个游戏.在游戏开始时,玩家将挑选一个怪物.

公平地挑选怪物很容易.

// 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];
}

并不公平地挑选怪物.

// 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();
    }   
}

问题是,当我在游戏中添加一个新怪物时,我必须编辑if-else.
或者我将赢得GoldMonster的机会改为0.2,我必须将所有0.1改为0.2
这很难看,也不容易维护.

// 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();
    }
}

如何重构这种概率算法,以便在添加新怪物并调整获胜怪物的机会时可以轻松维护代码

解决方法

基本上是@Egor Skriptunoff所说的.这应该很容易扩展.你可以使用Class< Monster>的集合.如果你不想使用枚举.
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);
}

你也许可以使枚举怪物复数,并让它指向一个类<?延伸怪物>如果你还想实例化怪物类.我只是想让这个例子更加清晰.

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...