分享个权重算法吧,使用场景还是比较多的。
例如:游戏里有狮子、老虎、毒蛇、大象、鳄鱼5种怪物,每次刷怪都是按照概率随机。
权重算法可以随心所欲得控制每种怪物的刷新概率,做法如下:
1、设置每种怪物的权重,例如:
狮子5,老虎8,毒蛇12,大象3,鳄鱼17
2、计算权重之和
5+8+12+3+17 = 45
3、想象一把全长45的尺子,上面有5个刻度
5,13,25,28,45(每两个刻度之间的距离,刚好是权重)
4、随机一个0~45的数字,落在哪个刻度区间,就随出哪个怪物。
每种怪的刷新概率,完全与权重大小成正比。
5、改变怪物权重,可以随时改变他的刷新概率
例如:第二关想增加难度,就把老虎的权重从8增加到18
那么尺子就变长了,老虎的刻度也变长了,老虎刷新概率提高了。
使用方法:
1、初始化权重
let wt = weight();
wt.add(‘狮子’,5);
wt.add(‘老虎’,8);
wt.add(‘毒蛇’,12);
wt.add(‘大象’,3);
wt.add(‘鳄鱼’,17);
2、根据权重,获取随机ID
let enemy = wt.get();
这个enemy就是随机刷出的怪物名称
3、要增加毒蛇的刷新概率
wt.add(‘毒蛇’,10); //这样毒蛇的权重 = 12+10 = 22
4、要减少鳄鱼的刷新概率
wt.add(‘鳄鱼’,-15); //这样鳄鱼的权重 = 17-15 = 2
权重算法适用于任何精准操控概率的随机场景,例如刷怪、掉宝、怪物AI等等。
以下是可复制的源码:
export class Weight {
total: number = 0;
keys: string[] = [];
values: number[] = [];
add(key: string, value: number) {
let len = this.keys.length
for (let i = 0; i < len; ++i) {
if (this.keys[i] === key) {
if (value < 0) {
let wt = i === 0 ? this.values[i] : this.values[i] - this.values[i - 1];
if (wt < -value) {
value = -wt;
}
}
for (let j = i; j < len; ++j) {
this.values[j] += value;
}
this.total += value;
return;
}
}
value = Math.max(value, 0);
this.keys[len] = key;
this.values[len] = this.total + value;
this.total += value;
}
get(): string {
let rd = gi.random(this.total);
for (let i = 0, len = this.keys.length; i < len; ++i) {
if (rd < this.values[i]) {
return this.keys[i];
}
}
return null;
}
}
export function weight(obj?: Object): Weight {
let ret = new Weight();
if (obj) {
ret.keys = Object.keys(obj);
for (let i = 0, len = ret.keys.length; i < len; ++i) {
ret.values[i] = ret.total + obj[ret.keys[i]];
ret.total += obj[ret.keys[i]];
}
}
return ret;
}