cod*_*e4j 7 java algorithm maintainability refactoring
假设我想创造一个游戏.在游戏开始时,玩家将挑选一个怪物.
公平地挑选怪物很容易.
// 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];
}
Run Code Online (Sandbox Code Playgroud)
并不公平地挑选怪物.
// 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();
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,当我在游戏中添加一个新怪物时,我必须编辑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();
}
}
Run Code Online (Sandbox Code Playgroud)
如何重构这种概率算法,以便在添加新怪物并调整获胜怪物的机会时可以轻松维护代码?
基本上就是@Egor Skriptunoff 所说的。这应该很容易扩展。如果您Class<Monster>
不想使用enum
.
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);
}
Run Code Online (Sandbox Code Playgroud)
如果您仍然想实例化怪物类,您也许可以将枚举设为复数Monsters
,并让它指向 a 。Class<? extends Monster>
我只是想让这个例子更清楚。