WT Calculate Optimal Stone for Enchanting

by gdarussian

HTML

<p>
    <h1>Calculate Optimal Stone for Enchanting</h1>
    <hr />
</p>

<p>
    <label>Enchanting Cost:</label>
    <input id="cost" size=10 value ="" maxlength=9 onChange="calc()">
</p>

<p>
    <label>Success %:</label>
    <select id="success" size="1" onChange="calc()">
        <option value=".1" selected="selected">10%</option>
        <option value=".2">20%</option>
        <option value=".3">30%</option>
        <option value=".4">40%</option>
        <option value=".5">50%</option>
        <option value=".6">60%</option>
        <option value=".7">70%</option>
        <option value=".8">80%</option>
        <option value=".9">90%</option>
    </select>
</p>

<p>
    <label>Best stone in shop:</label>
    <select id="bestStone" size="1" onChange="calc()">
        <option value="1">Level 1</option>
        <option value="2">Level 2</option>
        <option value="3">Level 3</option>
        <option value="4">Level 4</option>
        <option value="5">Level 5</option>
        <option value="6">Level 6</option>
        <option value="7">Level 7</option>
        <option value="8" selected="selected">Level 8</option>
        <option value="9">Level 9</option>
    </select>
    <hr />
</p>
 
<p>
    Stone to use:
    <div id="answer"></div>
</p>

<p>        
    <hr />
    <table id="output"></table>
</p>

CSS

body { 
    margin: 1em; 
    font-size: 85%;
}

* {
    font-family:arial, helvetica, sans-serif;
    margin:0;
    padding:0;
}

p {
    font-size:1em;
    margin: 0 0 .8em 0;
}

.result {
    font-weight: bold;
    font-size: 100%;
}
.result0 { color: black; }
.result1 { color: black; }
.result2 { color: green; }
.result3 { color: deepskyblue; }
.result4 { color: lime; }
.result5 { color: blue; }
.result6 { color: red; }
.result7 { color: purple; }
.result8 { color: orange; }
.result9 { color: fuchsia; }

table {
    margin: 1em 0 0 0
}

html>body {
    font-size: 12px;
}
h1 {
    font-weight: bold;
    font-size: big;
    margin: 0 1em 1em 0;
}

label {
    display: inline-block; 
    width: 110px; 
}

select {
    width: 105px;
}
input {
    width: 100px;
}

JavaScript

// *** Calculate Optimal Stone for Enchanting *** //
// By Myrkr... no wait, by Asaka. Fix this when more costs are known for guild shop.
    
var stoneCosts =
[
    0,
    2000,
    3000,
    5000,
    10000,
    20000,
    40000,
    80000,
    150000,
    300000
]
    
var stoneSynthCosts =
[
    0,
    0,
    200,
    400,
    600,
    800,
    1000,
    1400,
    1800,
    2000,
]

var tableFormat = 'Lvl {0} stone costs {1}, has {2}% success, with avg cost of {3}. {4}<br/>'
var answerFormat = '<span class="result result{0}">{1} stone</span> with an average cost of {2} gold'

function calc()
{
    var successRate = parseFloat($('success').value)
    var cost = parseInt($('cost').value)
    var bestStoneInShop = parseInt($('bestStone').value)
    var outputTable = $('output')
    outputTable.innerHTML = ''
    
    if (isNaN(successRate) || isNaN(cost) || isNaN(bestStoneInShop))
    {
        answer = 'NaN'
    }
    else if (cost < 1)
    {
        answer='Invalid cost'
    }
    else
    {
        var bestStone = 0
        var minCost = Number.MAX_VALUE
        var prevCostOfStone = 0
        for (var stone = 0; stone <= 9; stone++)
        {
            var costOfStone = 0
            if (stone <= bestStoneInShop)
                costOfStone = stoneCosts[stone]
            else
                costOfStone = prevCostOfStone * 2 + stoneSynthCosts[stone]
            prevCostOfStone = costOfStone
    
            var successRateWithStone = successRate + stone / 10.0
            var costWithStone = cost + costOfStone
            var avgCostWithStone = costWithStone / successRateWithStone
            var isNewBest = false
            if (avgCostWithStone < minCost)
            {
                isNewBest = true
                minCost = avgCostWithStone
                bestStone = stone
            }
    
            var outputLine = tableFormat.format(stone, costOfStone,
                        Math.round(successRateWithStone * 100),
                       ...