203 lines
8.6 KiB
JavaScript
203 lines
8.6 KiB
JavaScript
//=============================================================================
|
||
// RPG Maker MZ - KN_ChestTest.js
|
||
//=============================================================================
|
||
|
||
/*:ja
|
||
* @target MZ
|
||
* @author kurogoma knights
|
||
* @base PluginCommonBase
|
||
* @orderAfter KN_Chest
|
||
* @plugindesc 宝箱排出率テスト用プラグイン
|
||
*
|
||
* @command TEST_WEIGHT_RATE
|
||
* @desc 1000回抽選して赤箱アイテムの排出率を表示(所持制限なし)
|
||
*
|
||
* @command TEST_WEIGHT_RATE_SILVER
|
||
* @desc 1000回抽選して銀箱スキルの排出率を表示(所持制限なし)
|
||
*
|
||
* @command TEST_WEIGHT_RATE_GOLD
|
||
* @desc 1000回抽選して金箱遺物の排出率を表示(所持制限なし)
|
||
*
|
||
*/
|
||
|
||
(() => {
|
||
'use strict';
|
||
const script = document.currentScript;
|
||
|
||
// 1000回排出率テスト(所持制限無視)
|
||
PluginManagerEx.registerCommand(script, "TEST_WEIGHT_RATE", function(args) {
|
||
const TEST_COUNT = 1000;
|
||
console.log("=".repeat(80));
|
||
console.log(`【排出率テスト】1000回抽選(所持制限無視)`);
|
||
console.log("=".repeat(80));
|
||
|
||
// 赤箱アイテムを登録
|
||
PluginManager.callCommand(this, "KN_Chest", "REGISTER_ITEMS_RED", {});
|
||
|
||
// 重み付きリストを作成(KN_Chestと同じロジック)
|
||
const weightedItems = [];
|
||
const itemWeights = {}; // 各アイテムの重み
|
||
let totalWeight = 0;
|
||
|
||
for (const item of $dataItems) {
|
||
if (!item) continue;
|
||
if (item.meta['SGカテゴリ'] !== 'アイテム') continue;
|
||
const weight = Number(item.meta['宝箱出現率'] ?? 0);
|
||
if (weight > 0) {
|
||
itemWeights[item.id] = weight;
|
||
totalWeight += weight;
|
||
for (let i = 0; i < weight; i++) {
|
||
weightedItems.push(item);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 1000回抽選
|
||
const drawCount = {};
|
||
for (let i = 0; i < TEST_COUNT; i++) {
|
||
const r = Math.floor(Math.random() * weightedItems.length);
|
||
const item = weightedItems[r];
|
||
drawCount[item.id] = (drawCount[item.id] || 0) + 1;
|
||
}
|
||
|
||
// 結果表示
|
||
let output = "\n";
|
||
output += "-".repeat(80) + "\n";
|
||
output += `${"ID".padStart(3)} | ${"アイテム名".padEnd(20)} | ${"重み".padStart(4)} | ${"理論値".padStart(7)} | ${"実測値".padStart(7)} | ${"実測回数".padStart(6)}\n`;
|
||
output += "-".repeat(80) + "\n";
|
||
|
||
// 重みでソート(降順)
|
||
const sortedItems = Object.entries(itemWeights).sort((a, b) => b[1] - a[1]);
|
||
|
||
for (const [itemId, weight] of sortedItems) {
|
||
const item = $dataItems[itemId];
|
||
const theoretical = (weight / totalWeight * 100).toFixed(2);
|
||
const actual = ((drawCount[itemId] || 0) / TEST_COUNT * 100).toFixed(2);
|
||
const count = drawCount[itemId] || 0;
|
||
output += `${itemId.toString().padStart(3)} | ${item.name.padEnd(20)} | ${weight.toString().padStart(4)} | ${theoretical.padStart(6)}% | ${actual.padStart(6)}% | ${count.toString().padStart(6)}回\n`;
|
||
}
|
||
|
||
output += "-".repeat(80) + "\n";
|
||
output += `合計重み: ${totalWeight} / アイテム種類: ${Object.keys(itemWeights).length}\n`;
|
||
output += "=".repeat(80);
|
||
|
||
console.log(output);
|
||
});
|
||
|
||
// 1000回排出率テスト(銀箱スキル版)
|
||
PluginManagerEx.registerCommand(script, "TEST_WEIGHT_RATE_SILVER", function(args) {
|
||
const TEST_COUNT = 1000;
|
||
console.log("=".repeat(80));
|
||
console.log(`【銀箱排出率テスト】1000回抽選(所持制限無視)`);
|
||
console.log("=".repeat(80));
|
||
|
||
// 銀箱スキルの対象を収集(偶数ID のみ)
|
||
const weightedItems = [];
|
||
const itemWeights = {}; // 各アイテムの重み
|
||
let totalWeight = 0;
|
||
|
||
for (const item of $dataItems) {
|
||
if (!item) continue;
|
||
if (item.meta['SGカテゴリ'] !== 'スキル') continue;
|
||
if (item.id % 2 !== 0) continue; // 奇数IDはスキップ(強化後)
|
||
const weight = Number(item.meta['宝箱出現率'] ?? 0);
|
||
if (weight > 0) {
|
||
itemWeights[item.id] = weight;
|
||
totalWeight += weight;
|
||
for (let i = 0; i < weight; i++) {
|
||
weightedItems.push(item);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 1000回抽選
|
||
const drawCount = {};
|
||
for (let i = 0; i < TEST_COUNT; i++) {
|
||
const r = Math.floor(Math.random() * weightedItems.length);
|
||
const item = weightedItems[r];
|
||
drawCount[item.id] = (drawCount[item.id] || 0) + 1;
|
||
}
|
||
|
||
// 結果表示
|
||
let output = "\n";
|
||
output += "-".repeat(80) + "\n";
|
||
output += `${"ID".padStart(3)} | ${"スキル名".padEnd(20)} | ${"重み".padStart(4)} | ${"理論値".padStart(7)} | ${"実測値".padStart(7)} | ${"実測回数".padStart(6)} | ${"タイプ".padEnd(8)}\n`;
|
||
output += "-".repeat(80) + "\n";
|
||
|
||
// 重みでソート(降順)
|
||
const sortedItems = Object.entries(itemWeights).sort((a, b) => b[1] - a[1]);
|
||
|
||
for (const [itemId, weight] of sortedItems) {
|
||
const item = $dataItems[itemId];
|
||
const theoretical = (weight / totalWeight * 100).toFixed(2);
|
||
const actual = ((drawCount[itemId] || 0) / TEST_COUNT * 100).toFixed(2);
|
||
const count = drawCount[itemId] || 0;
|
||
const skillType = item.meta['スキルタイプ'] || '不明';
|
||
output += `${itemId.toString().padStart(3)} | ${item.name.padEnd(20)} | ${weight.toString().padStart(4)} | ${theoretical.padStart(6)}% | ${actual.padStart(6)}% | ${count.toString().padStart(6)}回 | ${skillType.padEnd(8)}\n`;
|
||
}
|
||
|
||
output += "-".repeat(80) + "\n";
|
||
output += `合計重み: ${totalWeight} / スキル種類: ${Object.keys(itemWeights).length}\n`;
|
||
output += "=".repeat(80);
|
||
|
||
console.log(output);
|
||
});
|
||
|
||
// 1000回排出率テスト(金箱遺物版)
|
||
PluginManagerEx.registerCommand(script, "TEST_WEIGHT_RATE_GOLD", function(args) {
|
||
const TEST_COUNT = 1000;
|
||
console.log("=".repeat(80));
|
||
console.log(`【金箱排出率テスト】1000回抽選(所持制限無視)`);
|
||
console.log("=".repeat(80));
|
||
|
||
// 金箱遺物の対象を収集
|
||
const weightedItems = [];
|
||
const itemWeights = {}; // 各アイテムの重み
|
||
let totalWeight = 0;
|
||
|
||
for (const item of $dataItems) {
|
||
if (!item) continue;
|
||
if (item.meta['SGカテゴリ'] !== '遺物') continue;
|
||
const weight = Number(item.meta['宝箱出現率'] ?? 0);
|
||
if (weight > 0) {
|
||
itemWeights[item.id] = weight;
|
||
totalWeight += weight;
|
||
for (let i = 0; i < weight; i++) {
|
||
weightedItems.push(item);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 1000回抽選
|
||
const drawCount = {};
|
||
for (let i = 0; i < TEST_COUNT; i++) {
|
||
const r = Math.floor(Math.random() * weightedItems.length);
|
||
const item = weightedItems[r];
|
||
drawCount[item.id] = (drawCount[item.id] || 0) + 1;
|
||
}
|
||
|
||
// 結果表示
|
||
let output = "\n";
|
||
output += "-".repeat(80) + "\n";
|
||
output += `${"ID".padStart(3)} | ${"遺物名".padEnd(20)} | ${"重み".padStart(4)} | ${"理論値".padStart(7)} | ${"実測値".padStart(7)} | ${"実測回数".padStart(6)}\n`;
|
||
output += "-".repeat(80) + "\n";
|
||
|
||
// 重みでソート(降順)
|
||
const sortedItems = Object.entries(itemWeights).sort((a, b) => b[1] - a[1]);
|
||
|
||
for (const [itemId, weight] of sortedItems) {
|
||
const item = $dataItems[itemId];
|
||
const theoretical = (weight / totalWeight * 100).toFixed(2);
|
||
const actual = ((drawCount[itemId] || 0) / TEST_COUNT * 100).toFixed(2);
|
||
const count = drawCount[itemId] || 0;
|
||
output += `${itemId.toString().padStart(3)} | ${item.name.padEnd(20)} | ${weight.toString().padStart(4)} | ${theoretical.padStart(6)}% | ${actual.padStart(6)}% | ${count.toString().padStart(6)}回\n`;
|
||
}
|
||
|
||
output += "-".repeat(80) + "\n";
|
||
output += `合計重み: ${totalWeight} / 遺物種類: ${Object.keys(itemWeights).length}\n`;
|
||
output += "=".repeat(80);
|
||
|
||
console.log(output);
|
||
});
|
||
|
||
})();
|