refactor: much better mix calculation

This commit is contained in:
2025-11-05 09:32:49 +01:00
parent 8b3b026aea
commit 3dec539b26
+29 -3
View File
@@ -65,6 +65,18 @@ const utils = {
}
return defaultValue;
},
gcd(numA, numB) {
let tmpA = numA;
let tmpB = numB;
while (tmpA !== tmpB) {
if (tmpA > tmpB) {
tmpA -= tmpB;
} else {
tmpB -= tmpA;
}
}
return tmpA;
},
};
class TableGenerator {
@@ -81,6 +93,7 @@ class TableGenerator {
this.minMixScore = 0;
this.maxMixScore = 0;
this.lastIndexes = [];
this.mixTable = this.initMixTable();
}
initIndexScores() {
@@ -103,6 +116,19 @@ class TableGenerator {
return scores;
}
initMixTable(seed) {
const mixSlots = Math.round(this.mixThreshold * this.slots.length);
if (mixSlots <= 0) {
return [false];
}
const gcd = utils.gcd(mixSlots, this.slots.length);
const mixTableLength = this.slots.length / gcd;
const tmpMixTable = new Array(mixTableLength)
.fill(0)
.map((unused, index) => index < mixSlots / gcd);
return utils.shuffleSeeded(tmpMixTable, seed + 1);
}
// eslint-disable-next-line class-methods-use-this
mixKey(index1, index2) {
return Math.min(index1, index2) * 1000 + Math.max(index1, index2);
@@ -185,8 +211,8 @@ class TableGenerator {
return this.candidates[index];
}
getSlotValue() {
if (this.prng() < this.mixThreshold) {
getSlotValue(index) {
if (this.mixTable[index % this.mixTable.length]) {
const value = this.getMixValue();
if (value !== null) {
return value;
@@ -196,7 +222,7 @@ class TableGenerator {
}
generate() {
return this.slots.map((slot) => [slot, this.getSlotValue()]);
return this.slots.map((slot, index) => [slot, this.getSlotValue(index)]);
}
}