Created
March 11, 2012 16:48
-
-
Save fab1an/2017105 to your computer and use it in GitHub Desktop.
Minecraft Enchantments simulator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DEBUG = false | |
ROUNDS = 100000 | |
DUMP_FILE = "stats_enchantment.marshal" | |
# # | |
# # | |
# ##### DATA # | |
# # | |
# # | |
# Combos: | |
@combos = [] | |
@combos = [:fortune, :efficiency] | |
@combos = [:fortune, :efficiency] | |
# Items | |
@items = {} | |
@items[:tool] = [:sword,:bow,:pickaxe_shovel_axe] | |
@items[:armor] = [:helmet,:chestplate_leggins,:boots] | |
# Enchantability | |
@enchantabilites = {} | |
@enchantabilites[:wooden] = {:tool => 15} | |
@enchantabilites[:leather] = {:armor => 15} | |
@enchantabilites[:stone] = {:tool => 5} | |
@enchantabilites[:iron] = {:armor => 9, :tool => 14} | |
@enchantabilites[:chain] = {:armor => 12} | |
@enchantabilites[:diamond] = {:armor => 10, :tool => 10} | |
@enchantabilites[:gold] = {:armor => 25, :tool => 22} | |
# conflicting enchantments | |
@conflicts = [] | |
@conflicts << [:protection,:fire_protection,:blast_protection,:projectile_protection] | |
@conflicts << [:sharpness,:smite,:bane_of_arthropods] | |
@conflicts << [:silk_touch,:fortune] | |
# possible enchantments: armor | |
@enchantments = {} | |
@enchantments[:protection] = [:helmet,:chestplate_leggins,:boots] | |
@enchantments[:fire_protection] = [:helmet,:chestplate_leggins,:boots] | |
@enchantments[:feather_fall] = [:boots] | |
@enchantments[:blast_protection] = [:helmet,:chestplate_leggins,:boots] | |
@enchantments[:projectile_protection] =[:helmet,:chestplate_leggins,:boots] | |
@enchantments[:respiration] = [:helmet] | |
@enchantments[:aqua_affinity] = [:helmet] | |
# possible enchantments: sword | |
@enchantments[:sharpness] = [:sword] | |
@enchantments[:smite] = [:sword] | |
@enchantments[:bane_of_arthropods] = [:sword] | |
@enchantments[:knockback] = [:sword] | |
@enchantments[:fire_aspect] = [:sword] | |
@enchantments[:looting] = [:sword] | |
# epossible enchantments: bow | |
@enchantments[:power] = [:bow] | |
@enchantments[:punch] = [:bow] | |
@enchantments[:flame] = [:bow] | |
@enchantments[:infinity] = [:bow] | |
# possible enchantments: tool | |
@enchantments[:efficiency] = [:pickaxe_shovel_axe] | |
@enchantments[:silk_touch] = [:pickaxe_shovel_axe] | |
@enchantments[:unbreaking] = [:pickaxe_shovel_axe] | |
@enchantments[:fortune] = [:pickaxe_shovel_axe] | |
# enchantmentlevels: armor | |
@enchantmentsLevels = {} | |
@enchantmentsLevels[:protection] = [[1,21],[17,37],[33,53],[49,69],[]] | |
@enchantmentsLevels[:fire_protection] = [[10,22],[18,30],[26,38],[34,46],[]] | |
@enchantmentsLevels[:feather_fall] = [[5,15],[11,21],[17,27],[23,33],[]] | |
@enchantmentsLevels[:blast_protection] = [[5,17],[13,25],[21,33],[29,41],[]] | |
@enchantmentsLevels[:projectile_protection] = [[3,18],[9,24],[15,30],[21,36],[]] | |
@enchantmentsLevels[:respiration] = [[10,40],[20,50],[30,60],[],[]] | |
@enchantmentsLevels[:aqua_affinity] = [[1,41],[],[],[],[]] | |
# enchantmentlevels: sword | |
@enchantmentsLevels[:sharpness] = [[1,21],[17,37],[33,53],[49,69],[65,85]] | |
@enchantmentsLevels[:smite] = [[5,25],[13,33],[21,41],[29,49],[37,57]] | |
@enchantmentsLevels[:bane_of_arthropods] = [[5,25],[13,33],[21,41],[29,49],[37,57]] | |
@enchantmentsLevels[:knockback] = [[5,55],[25,75],[],[],[]] | |
@enchantmentsLevels[:fire_aspect] = [[10,60],[30,80],[],[],[]] | |
@enchantmentsLevels[:looting] = [[20,70],[32,82],[44,94],[],[]] | |
# enchantmentlevels: bow | |
@enchantmentsLevels[:power] = [[1,16],[11,26],[21,36],[31,46],[41,56]] | |
@enchantmentsLevels[:punch] = [[12,37],[32,57],[],[],[]] | |
@enchantmentsLevels[:flame] = [[20,50],[],[],[],[]] | |
@enchantmentsLevels[:infinity] = [[20,50],[],[],[],[]] | |
# enchantmentlevels: tool | |
@enchantmentsLevels[:efficiency] = [[1,51],[16,66],[31,81],[46,96],[61,111]] | |
@enchantmentsLevels[:silk_touch] = [[25,75],[],[],[],[]] | |
@enchantmentsLevels[:unbreaking] = [[5,55],[15,65],[25,75],[],[]] | |
@enchantmentsLevels[:fortune] = [[20,70],[32,82],[44,94],[],[]] | |
# enchantmentsWeights: armor | |
@enchantmentWeights = {} | |
@enchantmentWeights[:protection] = 10 | |
@enchantmentWeights[:fire_protection] = 5 | |
@enchantmentWeights[:feather_fall] = 5 | |
@enchantmentWeights[:blast_protection] = 2 | |
@enchantmentWeights[:projectile_protection] = 5 | |
@enchantmentWeights[:respiration] = 2 | |
@enchantmentWeights[:aqua_affinity] = 2 | |
# enchantmentWeights: sword | |
@enchantmentWeights[:sharpness] = 10 | |
@enchantmentWeights[:smite] = 5 | |
@enchantmentWeights[:bane_of_arthropods] = 5 | |
@enchantmentWeights[:knockback] = 5 | |
@enchantmentWeights[:fire_aspect] = 2 | |
@enchantmentWeights[:looting] = 2 | |
# enchantmentWeights: bow | |
@enchantmentWeights[:power] = 10 | |
@enchantmentWeights[:punch] = 2 | |
@enchantmentWeights[:flame] = 2 | |
@enchantmentWeights[:infinity] = 1 | |
# enchantmentWeights: tool | |
@enchantmentWeights[:efficiency] = 10 | |
@enchantmentWeights[:silk_touch] = 1 | |
@enchantmentWeights[:unbreaking] = 5 | |
@enchantmentWeights[:fortune] = 2 | |
# # | |
# # | |
# ##### CLASSES # | |
# # | |
# # | |
class Stats | |
def initialize | |
@levels = [] | |
end | |
def add(level, enchantments) | |
@levels[level - 1] = {} if @levels[level - 1].nil? | |
names = enchantments.map{ |e| e[:name]} | |
names.sort {|a,b| a.to_s <=> b.to_s} | |
oldCount = @levels[level - 1][names]; | |
oldCount = 0 if oldCount.nil? | |
@levels[level - 1][names] = oldCount + 1 | |
end | |
def highestChanceOf(enchantmentNames, min) | |
bestWeightedPercentage = 0 | |
bestLevel = 0 | |
percentAtBestLevel = 0 | |
bestOccurences = 0 | |
heighestPercentage = 0 | |
heighestPercentageLevel = 0 | |
heighestPercentageOccurences = 0 | |
puts "want #{enchantmentNames.inspect} #{min}" if DEBUG | |
1.upto(50) do |level| | |
occurences = @levels[level - 1] | |
occurences = {} if occurences.nil? | |
occurencesOfCountAtLevel = 0 | |
occurences.each do |eList,occ| | |
matchingNames = false | |
if (!enchantmentNames.empty?) | |
if (enchantmentNames.all? {|name| eList.include? name}) | |
matchingNames = true | |
end | |
else | |
matchingNames = true | |
end | |
if (matchingNames && (eList.length >= min)) | |
puts "#{level} matches #{eList.inspect} #{occ}" if DEBUG | |
occurencesOfCountAtLevel = occurencesOfCountAtLevel + occ | |
else | |
puts "no match #{eList.inspect} #{occ}" if DEBUG | |
end | |
end | |
next if occurencesOfCountAtLevel == 0 | |
percent = (100 * occurencesOfCountAtLevel.to_f) / (ROUNDS.to_f) | |
neededEnchants = (100 / percent) | |
# weight percentage by dividing it through the xp needed | |
weightedPercentage = percent / xpForLevel(level) | |
# weight percentage by diving it through the enchants needed | |
weightedPercentage = weightedPercentage / neededEnchants | |
puts "L #{level} percent #{percent} weighted #{weightedPercentage}" if DEBUG | |
if (weightedPercentage > bestWeightedPercentage) | |
bestWeightedPercentage = weightedPercentage | |
percentAtBestLevel = percent | |
bestLevel = level | |
bestOccurences = occurencesOfCountAtLevel | |
end | |
if (percent > heighestPercentage) | |
heighestPercentage = percent | |
heighestPercentageLevel = level | |
heighestPercentageOccurences = occurencesOfCountAtLevel | |
end | |
end | |
puts "highest %: #{heighestPercentage} @ L #{heighestPercentageLevel} (#{heighestPercentageOccurences}), chosen %: #{percentAtBestLevel} @ L #{bestLevel} (#{bestOccurences})" if DEBUG | |
{:percentage => percentAtBestLevel, :level => bestLevel} | |
end | |
end | |
# # | |
# # | |
# ##### ALGORITHMS # | |
# # | |
# # | |
def xpForLevel(level) | |
xp = 0 | |
1.upto(level) do |l| | |
if (level == 1) | |
xp = xp + 7 | |
else | |
if (l % 2 == 0) | |
# even | |
xp = xp + 7 + l / 2 * 3 + (l / 2 - 1) * 4 | |
else | |
# odd | |
xp = xp + 7 + (l - 1) / 2 * 3 + (l - 1) / 2 *4 | |
end | |
end | |
end | |
xp | |
end | |
def prettify(enchantment) | |
return prettyString(enchantment[:name]) + " " + enchantment[:level].to_s | |
end | |
def prettyString(s) | |
s.to_s.downcase.gsub(/_/," ").gsub(/\b[a-z]/) { |a| a.upcase } | |
end | |
# two dice | |
def triangularRandom(limit) | |
(rand(limit).to_f/2 + rand(limit).to_f/2) | |
end | |
def getAllCombinations | |
# tools,armors | |
allCombinations = [] | |
@items.keys.each do |type| | |
# run through all enchantable items | |
items = @items[type] | |
items.each do |item| | |
# valid materials | |
materials = [] | |
if item == :bow | |
materials << :wooden | |
else | |
materials = @enchantabilites.keys.select {|material| @enchantabilites[material].include?(type)} | |
end | |
materials.each do |material| | |
allCombinations << {:material => material, :item => item} | |
end | |
end | |
end | |
allCombinations | |
end | |
def modifiedEnchantLevel(level,enchantability) | |
puts "calculating modification for level #{level}, enchantability #{enchantability}" if DEBUG | |
modifiedLevel = level.to_f + triangularRandom(enchantability+1) + 1 | |
modifier = triangularRandom(0)*0.5 + 0.75 | |
finalLevel = (modifiedLevel * modifier).round | |
finalLevel | |
end | |
@cache = {} | |
def possibleEnchantments(item, modifiedlevel) | |
#cachedResult = @cache[{:item => item, :modLevel => modifiedlevel}] | |
#if !cachedResult.nil? | |
# cachedResult = Array.new(cachedResult) | |
#end | |
matchingEs = @enchantments.keys.select {|key| @enchantments[key].include?(item)} | |
withLevels = [] | |
matchingEs.each do |e| | |
level = 5 | |
@enchantmentsLevels[e].reverse.each do |rangeMin,rangeMax| | |
if !rangeMin.nil? | |
if (modifiedlevel >= rangeMin && modifiedlevel <= rangeMax) | |
break | |
end | |
end | |
level = level - 1 | |
end | |
if (level != 0) | |
enchantment = {} | |
enchantment[:name] = e | |
enchantment[:level] = level | |
withLevels << enchantment | |
end | |
end | |
#@cache[{:item => item, :modLevel => modifiedlevel}] = Array.new(withLevels) | |
withLevels | |
end | |
def chooseE(enchantments) | |
pool = [] | |
enchantments.each do |e| | |
@enchantmentWeights[e[:name]].times {pool << e} | |
end | |
pool[rand(pool.size)] | |
end | |
def conflictsFor(enchantment_name) | |
conflicts = @conflicts.select {|c| c.include?(enchantment_name)} | |
conflicts = conflicts.flatten.uniq - [enchantment_name] | |
conflicts | |
end | |
def enchant(item,enchantability,level) | |
chosenEnchantments = [] | |
# get modified level | |
modifiedLevel = modifiedEnchantLevel(level, enchantability) | |
# get possible enchantments | |
possibleEs = possibleEnchantments(item, modifiedLevel) | |
while(!possibleEs.empty?) do | |
# 1. pick an enchantment | |
puts "possible Es: #{possibleEs.inspect}" if DEBUG | |
chosenE = chooseE(possibleEs) | |
puts "chosen #{chosenE.inspect}" if DEBUG | |
chosenEnchantments << chosenE | |
# 2. remove this and conflicting | |
possibleEs.delete(chosenE) | |
possibleEs = possibleEs.reject do |e| | |
conflictsFor(chosenE[:name]).include?(e[:name]) | |
end | |
puts "after removal of conflicting: #{possibleEs.inspect}" if DEBUG | |
# 3. divide mod-level in half, rounded down | |
modifiedLevel = (modifiedLevel / 2.0).floor | |
# 4. With probability (modified level + 1) / 50, keep going | |
r = rand() | |
p = (modifiedLevel + 1)/50.0 | |
break if r > p | |
puts "could pick another one" if DEBUG | |
end | |
chosenEnchantments | |
end | |
def enchantAll | |
allCombinations = getAllCombinations() | |
puts "calculating #{allCombinations.size} material/item combinations, using #{ROUNDS} runs for each level," | |
total = allCombinations.size * 50 * ROUNDS | |
finished = 0 | |
puts "totaling #{total} enchants:" | |
lastStr = nil | |
# per combination[level]: enchantmentNames => count | |
allStats = {} | |
allCombinations.each do |c| | |
# create Stats for material/item combination | |
allStats[c] = Stats.new | |
type = @items.keys.find {|t| @items[t].include?(c[:item])} | |
enchantability = @enchantabilites[c[:material]][type] | |
puts "* enchanting #{50*ROUNDS} #{prettyString(c[:material])} #{prettyString(c[:item])}, enchantability: #{enchantability}" | |
1.upto(50).each do |level| | |
ROUNDS.times do | |
enchantments = [] | |
# redo value falls out of range for everything | |
while (enchantments.empty?) | |
enchantments = enchant(c[:item], enchantability, level) | |
end | |
# debug: output enchantment | |
pretty = enchantments.map {|e| prettify(e)}.sort if DEBUG | |
puts " * enchanted Level #{level} #{prettyString(c[:material])} #{prettyString(c[:item])}: #{pretty.join(", ")}" if DEBUG | |
# statistics/counting: | |
allStats[c].add(level, enchantments) | |
# result percentage | |
finished = finished + 1 | |
promille = (1000 * finished.to_f) / total / 10 | |
percentageStr = ("%3.1f" % promille).to_s | |
if (percentageStr != lastStr) | |
puts "* #{percentageStr}% done" | |
lastStr = percentageStr | |
STDOUT.flush | |
end | |
end | |
end | |
end | |
allStats | |
end | |
def showStats(stats) | |
allCombinations = getAllCombinations() | |
# output statistics: | |
puts "calculated #{allCombinations.size} material/item combinations, using #{ROUNDS} runs for each level," | |
puts "totaling #{ROUNDS * 50 * allCombinations.size} enchants:" | |
puts "" | |
# tools,armors | |
@items.keys.each do |type| | |
# run through all enchantable items | |
items = @items[type] | |
items.each do |item| | |
# valid materials | |
materials = [] | |
if item == :bow | |
materials << :wooden | |
else | |
materials = @enchantabilites.keys.select {|material| @enchantabilites[material].include?(type)} | |
end | |
materials.sort! {|a,b| a.to_s <=> b.to_s} | |
puts " * #{prettyString(item)}:" | |
puts "" | |
puts " highest chances of getting <count> or more enchantments: (% at / optimal level)" | |
puts "" | |
puts "".ljust(39) + materials.map{|m| m.to_s.center(20," ") }.join() | |
puts "".ljust(39) + "".ljust(20*materials.size,"_") | |
1.upto(4) do |count| | |
# map materials to the stats of the combination (1 item, many materials) | |
temp = materials.map{|m| stats[{:material => m,:item => item}]} | |
temp = temp.map do |stat| | |
chance = stat.highestChanceOf([], count) | |
percentString = "%3.1f" % chance[:percentage] + "% / L " | |
percentString = percentString.rjust(10) | |
percentString + ("%2d" % chance[:level]).rjust(2) | |
end | |
puts "#{count.to_s} (or more) |".rjust(39) + temp.map{|c| c.center(20, " ")}.join() | |
end | |
puts "" | |
puts "" | |
puts " highest chances of getting specific enchantments: (% at / optimal level)" | |
puts "" | |
puts "".ljust(39) + materials.map{|m| m.to_s.center(20," ") }.join() | |
puts "".ljust(39) + "".ljust(20*materials.size,"_") | |
matchingEs = @enchantments.keys.select {|key| @enchantments[key].include?(item)} | |
matchingEs.sort {|a,b| a.to_s <=> b.to_s} | |
matchingEs.each do |e| | |
temp = materials.map{|m| stats[{:material => m,:item => item}]} | |
temp = temp.map do |stat| | |
chance = stat.highestChanceOf([e],1) | |
percentString = "%3.1f" % chance[:percentage] + "% / L " | |
percentString = percentString.rjust(10) | |
percentString + ("%2d" % chance[:level]).rjust(2) | |
end | |
eString = " " + prettyString(e.to_s) | |
puts eString.ljust(37) + " |" + temp.map{|c| c.center(20, " ")}.join() | |
end | |
puts "" | |
puts "" | |
puts "" | |
end | |
end | |
end | |
stats = nil | |
if File.exist?(DUMP_FILE) | |
File.open(DUMP_FILE,'r') do|file| | |
stats = Marshal.load(file) | |
end | |
else | |
stats = enchantAll() | |
File.open(DUMP_FILE,'w') do|file| | |
Marshal.dump(stats, file) | |
end | |
end | |
showStats(stats) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Marshalled Ruby Data for 100.000 runs: http://dl.dropbox.com/u/168982/stats_enchantment.marshal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
optimal level is chosen by | |
1. dividing the percentage through the XP needed for the level | |
2. dividing the result through the numbers of enchants needed with this percentage to gain a 100% chance. (5 for 22% for example) | |
calculated 26 material/item combinations, using 100000 runs for each level, | |
totaling 130000000 enchants: | |
* Helmet: | |
highest chances of getting <count> or more enchantments: (% at / optimal level) | |
chain diamond gold iron leather | |
____________________________________________________________________________________________________ | |
1 (or more) | 100.0% / L 1 100.0% / L 1 100.0% / L 1 100.0% / L 1 100.0% / L 1 | |
2 (or more) | 9.5% / L 1 8.5% / L 1 16.2% / L 1 7.9% / L 1 10.9% / L 1 | |
3 (or more) | 6.0% / L 26 5.6% / L 25 1.5% / L 1 6.1% / L 28 0.5% / L 1 | |
4 (or more) | 0.0% / L 0 0.0% / L 0 0.0% / L 0 0.0% / L 0 0.0% / L 0 | |
highest chances of getting specific enchantments: (% at / optimal level) | |
chain diamond gold iron leather | |
____________________________________________________________________________________________________ | |
Fire Protection | 5.8% / L 1 16.3% / L 6 16.0% / L 1 15.5% / L 6 9.8% / L 1 | |
Blast Protection | 8.5% / L 1 8.6% / L 1 8.1% / L 1 8.4% / L 1 8.5% / L 1 | |
Projectile Protection | 24.4% / L 1 25.5% / L 1 21.3% / L 1 25.9% / L 1 23.4% / L 1 | |
Respiration | 4.1% / L 1 11.9% / L 6 13.3% / L 1 13.1% / L 7 7.0% / L 1 | |
Aqua Affinity | 16.6% / L 1 17.2% / L 1 16.6% / L 1 17.2% / L 1 16.0% / L 1 | |
Protection | 50.3% / L 1 52.3% / L 1 42.2% / L 1 53.4% / L 1 46.8% / L 1 | |
* Chestplate Leggins: | |
highest chances of getting <count> or more enchantments: (% at / optimal level) | |
chain diamond gold iron leather | |
____________________________________________________________________________________________________ | |
1 (or more) | 100.0% / L 1 100.0% / L 1 100.0% / L 1 100.0% / L 1 100.0% / L 1 | |
2 (or more) | 0.0% / L 0 0.0% / L 0 0.0% / L 0 0.0% / L 0 0.0% / L 0 | |
3 (or more) | 0.0% / L 0 0.0% / L 0 0.0% / L 0 0.0% / L 0 0.0% / L 0 | |
4 (or more) | 0.0% / L 0 0.0% / L 0 0.0% / L 0 0.0% / L 0 0.0% / L 0 | |
highest chances of getting specific enchantments: (% at / optimal level) | |
chain diamond gold iron leather | |
____________________________________________________________________________________________________ | |
Fire Protection | 6.6% / L 1 16.2% / L 5 18.2% / L 1 17.9% / L 6 11.0% / L 1 | |
Blast Protection | 9.5% / L 1 9.6% / L 1 9.2% / L 1 9.4% / L 1 9.6% / L 1 | |
Projectile Protection | 27.6% / L 1 28.4% / L 1 24.1% / L 1 28.8% / L 1 26.0% / L 1 | |
Protection | 56.3% / L 1 58.4% / L 1 48.5% / L 1 59.8% / L 1 53.4% / L 1 | |
* Boots: | |
highest chances of getting <count> or more enchantments: (% at / optimal level) | |
chain diamond gold iron leather | |
____________________________________________________________________________________________________ | |
1 (or more) | 100.0% / L 1 100.0% / L 1 100.0% / L 1 100.0% / L 1 100.0% / L 1 | |
2 (or more) | 9.0% / L 1 7.9% / L 1 15.8% / L 1 7.0% / L 1 10.4% / L 1 | |
3 (or more) | 0.0% / L 0 0.0% / L 0 0.0% / L 0 0.0% / L 0 0.0% / L 0 | |
4 (or more) | 0.0% / L 0 0.0% / L 0 0.0% / L 0 0.0% / L 0 0.0% / L 0 | |
highest chances of getting specific enchantments: (% at / optimal level) | |
chain diamond gold iron leather | |
____________________________________________________________________________________________________ | |
Fire Protection | 5.5% / L 1 15.8% / L 6 15.4% / L 1 15.3% / L 6 9.3% / L 1 | |
Blast Protection | 7.7% / L 1 7.6% / L 1 7.9% / L 1 7.4% / L 1 7.7% / L 1 | |
Projectile Protection | 22.8% / L 1 23.5% / L 1 20.3% / L 1 24.1% / L 1 21.9% / L 1 | |
Feather Fall | 25.8% / L 1 24.7% / L 1 31.4% / L 1 23.6% / L 1 27.4% / L 1 | |
Protection | 47.1% / L 1 49.1% / L 1 40.8% / L 1 50.1% / L 1 44.0% / L 1 | |
* Sword: | |
highest chances of getting <count> or more enchantments: (% at / optimal level) | |
diamond gold iron stone wooden | |
____________________________________________________________________________________________________ | |
1 (or more) | 100.0% / L 1 100.0% / L 1 100.0% / L 1 100.0% / L 1 100.0% / L 1 | |
2 (or more) | 7.6% / L 1 14.5% / L 1 10.2% / L 1 5.8% / L 2 10.7% / L 1 | |
3 (or more) | 17.1% / L 50 1.1% / L 1 18.2% / L 50 15.3% / L 49 18.5% / L 50 | |
4 (or more) | 2.6% / L 50 3.3% / L 49 2.8% / L 49 2.2% / L 49 3.0% / L 50 | |
highest chances of getting specific enchantments: (% at / optimal level) | |
diamond gold iron stone wooden | |
____________________________________________________________________________________________________ | |
Bane Of Arthropods | 17.0% / L 1 18.8% / L 1 18.1% / L 1 10.1% / L 1 18.5% / L 1 | |
Knockback | 22.3% / L 1 26.3% / L 1 24.3% / L 1 19.7% / L 2 24.7% / L 1 | |
Fire Aspect | 9.5% / L 6 8.9% / L 1 5.0% / L 1 11.0% / L 9 5.5% / L 1 | |
Looting | 12.4% / L 19 10.4% / L 12 11.9% / L 17 12.4% / L 21 11.6% / L 16 | |
Sharpness | 49.6% / L 1 41.5% / L 1 45.1% / L 1 70.7% / L 1 44.2% / L 1 | |
Smite | 17.1% / L 1 18.8% / L 1 18.2% / L 1 10.0% / L 1 18.3% / L 1 | |
* Bow: | |
highest chances of getting <count> or more enchantments: (% at / optimal level) | |
wooden | |
____________________ | |
1 (or more) | 100.0% / L 1 | |
2 (or more) | 4.3% / L 1 | |
3 (or more) | 8.8% / L 32 | |
4 (or more) | 1.1% / L 35 | |
highest chances of getting specific enchantments: (% at / optimal level) | |
wooden | |
____________________ | |
Flame | 20.1% / L 16 | |
Infinity | 11.9% / L 18 | |
Power | 96.1% / L 1 | |
Punch | 8.2% / L 1 | |
* Pickaxe Shovel Axe: | |
highest chances of getting <count> or more enchantments: (% at / optimal level) | |
diamond gold iron stone wooden | |
____________________________________________________________________________________________________ | |
1 (or more) | 100.0% / L 1 100.0% / L 1 100.0% / L 1 100.0% / L 1 100.0% / L 1 | |
2 (or more) | 7.7% / L 1 14.4% / L 1 10.3% / L 1 5.6% / L 2 10.7% / L 1 | |
3 (or more) | 16.9% / L 50 18.5% / L 47 18.1% / L 50 15.6% / L 50 18.3% / L 50 | |
4 (or more) | 0.0% / L 0 0.0% / L 0 0.0% / L 0 0.0% / L 0 0.0% / L 0 | |
highest chances of getting specific enchantments: (% at / optimal level) | |
diamond gold iron stone wooden | |
____________________________________________________________________________________________________ | |
Silk Touch | 9.2% / L 25 9.0% / L 20 9.0% / L 23 9.4% / L 27 9.5% / L 24 | |
Fortune | 17.0% / L 18 14.7% / L 12 16.2% / L 16 17.2% / L 20 16.5% / L 16 | |
Unbreaking | 33.5% / L 1 40.9% / L 1 37.1% / L 1 18.7% / L 1 38.0% / L 1 | |
Efficiency | 74.3% / L 1 71.7% / L 1 73.2% / L 1 84.6% / L 1 72.7% / L 1 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment