console
<!DOCTYPE html>
<html>
<head>
<title>木块合成计算器</title>
<style>
.container {
margin: 20px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 8px;
background-color: #f9f9f9;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
h3 {
color: #2c3e50;
border-bottom: 2px solid #3498db;
padding-bottom: 8px;
margin-top: 0;
}
.input-group {
margin: 15px 0;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 10px;
}
.input-group label {
min-width: 80px;
}
input[type="number"] {
width: 80px;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
button {
padding: 8px 16px;
background: #3498db;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
transition: background 0.3s;
}
button:hover {
background: #2980b9;
}
.result {
margin-top: 15px;
padding: 15px;
background: #fff;
border-radius: 4px;
box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
}
.blocks-info {
background: #eaf6ff;
padding: 10px;
border-radius: 4px;
margin-bottom: 20px;
line-height: 1.6;
font-weight: bold;
color: #2c3e50;
}
.block-levels {
display: flex;
gap: 5px;
font-size: 0.9em;
margin-top: 5px;
}
.block-group {
display: inline-block;
padding: 2px 8px;
border-radius: 4px;
background: #d5e8ff;
}
</style>
</head>
<body>
<div class="blocks-info">
木块等级说明:
<div class="block-group">黑 1 2 3</div>
<div class="block-group">灰 4 5 6</div>
<div class="block-group">白 7 8 9</div>
<div class="block-group">绿 10 11 12</div>
<div class="block-group">蓝 13 14 15</div>
<div class="block-group">紫 16 17 18</div>
<div class="block-group">红 19 20 21</div>
<div class="block-group">橙 22 23 24</div>
<div class="block-group">金 25 26 27</div>
<div class="block-group">彩 28 29 30</div>
</div>
<div class="container">
<h3>功能1: 合成所需木块计算</h3>
<div class="input-group">
<label>从:</label>
<input type="number" id="m1" min="1" value="1">级
<label>合成为:</label>
<input type="number" id="n1" min="1" value="2">
<button onclick="handleCalculateRequired()">计算</button>
</div>
<div id="result1" class="result"></div>
</div>
<div class="container">
<h3>功能2: 最大合成等级计算</h3>
<div class="input-group">
<label>有</label>
<input type="number" id="m2" min="1" value="10"> 个
<input type="number" id="n2" min="1" value="3"> 级木块
<button onclick="handleCalculateMaxLevel()">计算</button>
</div>
<div id="result2" class="result"></div>
</div>
<div class="container">
<h3>功能3: 智能合成计算</h3>
<div class="input-group">
<label>从</label>
<input type="number" id="start" min="1" value="1">级
<label>到</label>
<input type="number" id="end" min="1" value="3">级,
<label>额外概率:</label>
<input type="number" id="prob" min="0" max="100" value="0">%
<label style="margin-left:15px">
<input type="checkbox" id="altRule"> 启用5合2模式
</label>
<button onclick="handleSmartCalculate()">计算</button>
</div>
<div id="result3" class="result"></div>
</div>
<div class="container">
<h3>功能4: 智能最大等级计算</h3>
<div class="input-group">
<label>有</label>
<input type="number" id="m4" min="1" value="10"> 个
<input type="number" id="n4" min="1" value="3"> 级木块
<label>额外概率:</label>
<input type="number" id="prob4" min="0" max="100" value="0">%
<label style="margin-left:15px">
<input type="checkbox" id="altRule4"> 5合2模式
</label>
<button onclick="handleEnhancedCalculate()">计算</button>
</div>
<div id="result4" class="result"></div>
</div>
<div class="container">
<h3>功能5: 逆向合成计算</h3>
<div class="input-group">
<label>目标:</label>
<input type="number" id="targetLevel" min="1" value="10">级木块
<label>起始:</label>
<input type="number" id="baseLevel" min="0" value="3">级木块(0或空表示所有低级)
<button onclick="handleReverseCalculate()">计算</button>
</div>
<div id="result5" class="result"></div>
</div>
<div class="container">
<h3>功能6: 中和合成计算</h3>
<div class="input-group">
<label>木块A:</label>
<input type="number" id="levelA" min="1" value="5">级
<label>数量:</label>
<input type="number" id="countA" min="1" value="1">
<label style="margin-left:15px">木块B:</label>
<input type="number" id="levelB" min="1" value="10">级
<label>数量:</label>
<input type="number" id="countB" min="1" value="1">
<button onclick="handleNeutralize()">计算</button>
</div>
<div id="result6" class="result"></div>
</div>
<script>
formatNumberWithUnits = function(num) {
const units = [
{ value: 1e12, symbol: '万亿' },
{ value: 1e8, symbol: '亿' },
{ value: 1e4, symbol: '万' }
];
const unit = units.find(unit => num >= unit.value);
if (unit) {
const formatted = num / unit.value;
const fixed = formatted.toFixed(2).replace(/\.?0+$/, '');
return `${fixed}${unit.symbol}`;
}
return num.toString();
}
function handleCalculateRequired() {
const m = parseInt(document.getElementById('m1').value);
const n = parseInt(document.getElementById('n1').value);
if (m > n) {
document.getElementById('result1').innerHTML = "⚠️ 错误:n必须大于或等于m";
return;
}
const required = 3 ** (n - m);
const displayNum = formatNumberWithUnits(required);
document.getElementById('result1').innerHTML =
`从 ${m}级 合成到 ${n}级 需要 <strong>${displayNum}</strong> 个${m}级木块`;
}
handleCalculateMaxLevel = function() {
const m = parseInt(document.getElementById('m2').value);
const n = parseInt(document.getElementById('n2').value);
let currentLevel = n;
let currentCount = m;
const remainders = {};
while (currentCount >= 3) {
const nextLevelCount = Math.floor(currentCount / 3);
const remainder = currentCount % 3;
remainders[currentLevel] = remainder;
currentLevel++;
currentCount = nextLevelCount;
}
remainders[currentLevel] = currentCount;
let remainStr = Object.keys(remainders)
.filter(lv => remainders[lv] > 0)
.map(lv => `${lv}级×${remainders[lv]}`)
.join(",");
document.getElementById('result2').innerHTML =
`最高可合成到 <strong>${currentLevel}级</strong>,数量为 <strong>${currentCount}个</strong><br>
剩余木块:${remainStr || "无"}`;
}
handleSmartCalculate = function() {
const start = parseInt(document.getElementById('start').value);
const end = parseInt(document.getElementById('end').value);
const prob = parseFloat(document.getElementById('prob').value);
const useAltRule = document.getElementById('altRule').checked;
if (start >= end) {
document.getElementById('result3').innerHTML = "⚠️ 目标等级必须大于起始等级";
return;
}
if (prob < 0 || prob > 100) {
document.getElementById('result3').innerHTML = "⚠️ 概率应在0-100之间";
return;
}
let required = 1;
for (let lv = end - 1; lv >= start; lv--) {
if (useAltRule) {
required = optimizedHybridCost(required, prob);
} else {
const successRate = 1 + (prob / 100);
required = Math.ceil(required / successRate) * 3;
}
}
const display = formatNumberWithUnits(required);
document.getElementById('result3').innerHTML =
`从 ${start}级 到 ${end}级 最少需要 <strong>${display}</strong> 个${start}级木块`;
}
function optimizedHybridCost(required, prob) {
const output5 = 2 + prob / 100;
const output3 = 1 + prob / 100;
const candidates = [];
const mA = Math.floor(required / output5);
candidates.push(calcCost(mA, required, output5, output3));
candidates.push(calcCost(mA + 1, required, output5, output3));
candidates.push(calcCost(0, required, output5, output3));
return Math.min(...candidates);
}
function calcCost(m, required, output5, output3) {
const produced = m * output5;
const remaining = Math.max(required - produced, 0);
const n = Math.ceil(remaining / output3);
return m * 5 + n * 3;
}
handleEnhancedCalculate = function() {
const m = parseInt(document.getElementById('m4').value);
const n = parseInt(document.getElementById('n4').value);
const prob = parseFloat(document.getElementById('prob4').value);
const useAltRule = document.getElementById('altRule4').checked;
if (m < 1 || n < 1 || prob < 0 || prob > 100) {
document.getElementById('result2').innerHTML = "⚠️ 请输入有效参数";
return;
}
let currentLevel = n;
let currentCount = m;
const remainders = {};
while (canUpgrade(currentCount, useAltRule)) {
const [consumed, produced] = calculateUpgrade(
currentCount,
prob,
useAltRule
);
remainders[currentLevel] = currentCount - consumed;
currentLevel++;
currentCount = produced;
}
remainders[currentLevel] = currentCount;
showEnhancedResult(currentLevel, currentCount, remainders);
}
function canUpgrade(count, useAltRule) {
return useAltRule ?
count >= 5 || count >= 3 :
count >= 3;
}
function calculateUpgrade(currentCount, prob, useAltRule) {
let consumed = 0;
let produced = 0;
if (useAltRule) {
const m5 = Math.floor(currentCount / 5);
if (m5 > 0) {
consumed += m5 * 5;
produced += m5 * (2 + prob / 100);
}
const remaining = currentCount - consumed;
const m3 = Math.floor(remaining / 3);
if (m3 > 0) {
consumed += m3 * 3;
produced += m3 * (1 + prob / 100);
}
} else {
const m3 = Math.floor(currentCount / 3);
consumed = m3 * 3;
produced = m3 * (1 + prob / 100);
}
return [consumed, produced];
}
function showEnhancedResult(maxLevel, finalCount, remainders) {
const remainStr = Object.keys(remainders)
.filter(lv => remainders[lv] > 0)
.map(lv => {
const count = Number(remainders[lv]).toFixed(2);
return `${lv}级×${count.replace(/\.00$/, '')}`;
})
.join(",");
const formattedCount = Number(finalCount).toFixed(2).replace(/\.00$/, '');
document.getElementById('result4').innerHTML = `
<strong>最高等级:</strong>${maxLevel}级<br>
<strong>最终数量:</strong>${formattedCount}个<br>
<strong>剩余木块:</strong>${remainStr || "无"}
`;
}
function handleReverseCalculate() {
const targetLevel = parseInt(document.getElementById('targetLevel').value);
const baseLevelInput = document.getElementById('baseLevel').value;
let baseLevel = parseInt(baseLevelInput);
const resultDiv = document.getElementById('result5');
if (isNaN(targetLevel) || targetLevel < 1) {
resultDiv.innerHTML = "⚠️ 请输入有效的目标等级";
return;
}
resultDiv.innerHTML = '';
if (baseLevelInput !== '' && !isNaN(baseLevel) && baseLevel > 0) {
if (baseLevel >= targetLevel) {
resultDiv.innerHTML = "⚠️ 起始等级必须小于目标等级";
return;
}
const required = 3 ** (targetLevel - baseLevel);
const displayNum = formatNumberWithUnits(required);
resultDiv.innerHTML =
`合成1个 <strong>${targetLevel}级</strong> 木块需要` +
`<br><strong>${displayNum}</strong> 个 <strong>${baseLevel}级</strong> 木块`;
}
else {
let resultHTML = `<strong>合成1个 ${targetLevel}级木块,各等级所需数量:</strong><br><ul>`;
for (let level = targetLevel - 1; level >= 1; level--) {
const required = 3 ** (targetLevel - level);
const displayNum = formatNumberWithUnits(required);
resultHTML += `<li><strong>${level}级</strong>: 需要 ${displayNum} 个</li>`;
}
resultHTML += '</ul>';
resultDiv.innerHTML = resultHTML;
}
}
function handleNeutralize() {
const levelA = parseInt(document.getElementById('levelA').value);
const countA = parseInt(document.getElementById('countA').value);
const levelB = parseInt(document.getElementById('levelB').value);
const countB = parseInt(document.getElementById('countB').value);
if (isNaN(levelA) || levelA < 1 || isNaN(countA) || countA < 0 ||
isNaN(levelB) || levelB < 1 || isNaN(countB) || countB < 0) {
document.getElementById('result6').innerHTML = "⚠️ 请输入有效的木块信息";
return;
}
const totalBaseCount =
countA * (3 ** (levelA - 1)) +
countB * (3 ** (levelB - 1));
let currentCount = totalBaseCount;
let currentLevel = 1;
while (currentCount >= 3) {
currentCount = Math.floor(currentCount / 3);
currentLevel++;
}
if (totalBaseCount === 0) {
document.getElementById('result6').innerHTML =
`<strong>结果:</strong>没有可用的木块!`;
return;
}
const baseCountA = countA * (3 ** (levelA - 1));
const baseCountB = countB * (3 ** (levelB - 1));
const percentA = (baseCountA / totalBaseCount * 100).toFixed(1);
const percentB = (baseCountB / totalBaseCount * 100).toFixed(1);
document.getElementById('result6').innerHTML = `
<strong>木块组合结果:</strong><br>
<ul>
<li>总木块价值:<strong>${formatNumberWithUnits(totalBaseCount)}</strong> 个1级木块</li>
<li>可合成最高等级:<strong>${currentLevel}级</strong>木块</li>
<li>最终数量:<strong>${currentCount}个</strong></li>
</ul>
<strong>详细组成:</strong><br>
<ul>
<li>${countA}个${levelA}级木块 ≈ ${formatNumberWithUnits(baseCountA)}个1级 (${percentA}%)</li>
<li>${countB}个${levelB}级木块 ≈ ${formatNumberWithUnits(baseCountB)}个1级 (${percentB}%)</li>
</ul>
`;
}
</script>
</body>
</html>