添加 'find_my_luckycolor.py'
This commit is contained in:
parent
661d8d08a1
commit
abbab157fd
156
find_my_luckycolor.py
Normal file
156
find_my_luckycolor.py
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
import math
|
||||||
|
|
||||||
|
mc_colors = [
|
||||||
|
['红色染料', '#B02E26', 'red'],
|
||||||
|
['绿色染料', '#5E7C16', 'green'],
|
||||||
|
['紫色染料', '#8932B8', 'purple'],
|
||||||
|
['青色染料', '#169C9C', 'cyan'],
|
||||||
|
['淡灰色染料', '#9D9D97', 'silver'],
|
||||||
|
['灰色染料', '#474F52', 'gray'],
|
||||||
|
['粉红色染料', '#F38BAA', 'pink'],
|
||||||
|
['黄绿色染料', '#80C71F', 'lime'],
|
||||||
|
['黄色染料', '#FED83D', 'yellow'],
|
||||||
|
['淡蓝色染料', '#3AB3DA', 'lightBlue'],
|
||||||
|
['品红色染料', '#C74EBD', 'magenta'],
|
||||||
|
['橙色染料', '#F9801D', 'orange'],
|
||||||
|
['黑色染料', '#1D1D21', 'black'],
|
||||||
|
['棕色染料', '#835432', 'brown'],
|
||||||
|
['蓝色染料', '#3C44AA', 'blue'],
|
||||||
|
['白色染料', '#F9FFFE', 'white']
|
||||||
|
]
|
||||||
|
|
||||||
|
def parse_mc_color(colors):
|
||||||
|
parsed_color = {}
|
||||||
|
for color in colors:
|
||||||
|
name, value, key = color
|
||||||
|
value = value.strip('#')
|
||||||
|
assert len(value) == 6
|
||||||
|
r = int(value[:2], base=16)
|
||||||
|
g = int(value[2:4], base=16)
|
||||||
|
b = int(value[4:], base=16)
|
||||||
|
parsed_color[key] = {
|
||||||
|
"name": name,
|
||||||
|
"key": key,
|
||||||
|
"value": [r, g, b]
|
||||||
|
}
|
||||||
|
return parsed_color
|
||||||
|
|
||||||
|
mc_colors = parse_mc_color(mc_colors)
|
||||||
|
|
||||||
|
def calculate_fused_color(counts):
|
||||||
|
num_colors = sum(counts.values())
|
||||||
|
if num_colors == 0:
|
||||||
|
return [160, 101, 64]
|
||||||
|
avg_color = []
|
||||||
|
# calculate total color.
|
||||||
|
for i in range(3):
|
||||||
|
this_total_color = sum([mc_colors[key]['value'][i]*count for key, count in counts.items()])
|
||||||
|
avg_color.append(this_total_color//num_colors)
|
||||||
|
# calculate average maximum.
|
||||||
|
average_maximum = 0
|
||||||
|
for key, count in counts.items():
|
||||||
|
average_maximum += max(mc_colors[key]['value']) * count
|
||||||
|
average_maximum //= num_colors
|
||||||
|
# calculate gain factor.
|
||||||
|
maximum_of_average = max(avg_color)
|
||||||
|
gain_factor = average_maximum / maximum_of_average
|
||||||
|
# generate result.
|
||||||
|
fused = [int(x * gain_factor) for x in avg_color]
|
||||||
|
return fused
|
||||||
|
|
||||||
|
def calculate_diff_color(c1, c2):
|
||||||
|
return sum([abs(x - y) for x, y in zip(c1, c2)])
|
||||||
|
|
||||||
|
def calculate_multipler(diff):
|
||||||
|
diff = 256 if diff > 256 else diff
|
||||||
|
multiplier = (1 - (0.50) * (256.0 - diff) / 256.0);
|
||||||
|
return multiplier * math.log(80) / math.log(125)
|
||||||
|
|
||||||
|
def export_recipe(recipe):
|
||||||
|
return ', '.join(['{0}:{1}'.format(mc_colors[key]['name'], recipe[key]) for key in recipe if recipe[key] > 0])
|
||||||
|
|
||||||
|
def find_best_color(luckycolor, limit=1):
|
||||||
|
min_diff = 10000
|
||||||
|
best_recipe = None
|
||||||
|
best_color = None
|
||||||
|
avaliable_colors = list(mc_colors.keys())
|
||||||
|
current_stat = [0] * len(avaliable_colors)
|
||||||
|
search_space = (limit+1)**len(current_stat)
|
||||||
|
print('正在搜索 {0} 种可能的组合'.format(search_space))
|
||||||
|
def get_next_stat(curent_stat):
|
||||||
|
digit = limit + 1
|
||||||
|
multipiler = 1
|
||||||
|
value = 0
|
||||||
|
# encode
|
||||||
|
for stat in current_stat[::-1]:
|
||||||
|
value += stat * multipiler
|
||||||
|
multipiler *= digit
|
||||||
|
# add
|
||||||
|
value += 1
|
||||||
|
# decode.
|
||||||
|
if value >= digit**len(current_stat):
|
||||||
|
return None
|
||||||
|
next_stat = []
|
||||||
|
while value > 0:
|
||||||
|
this_digit = value % digit
|
||||||
|
value = value // digit
|
||||||
|
next_stat.append(this_digit)
|
||||||
|
next_stat += [0] * (len(current_stat) - len(next_stat))
|
||||||
|
return next_stat[::-1]
|
||||||
|
searched = 0
|
||||||
|
while current_stat is not None:
|
||||||
|
this_color = {key:value for key, value in zip(avaliable_colors, current_stat)}
|
||||||
|
fused_color = calculate_fused_color(this_color)
|
||||||
|
diff_color = calculate_diff_color(luckycolor, fused_color)
|
||||||
|
if diff_color < min_diff:
|
||||||
|
min_diff = diff_color
|
||||||
|
best_recipe = this_color
|
||||||
|
best_color = fused_color
|
||||||
|
current_stat = get_next_stat(current_stat)
|
||||||
|
searched += 1
|
||||||
|
if searched % 10000 == 0:
|
||||||
|
print('[进度:{0}%]{1}/{2} 已完成, 当前最小误差为: {3}, 此时配方为: {4}'.format(
|
||||||
|
"%.2f"%(searched*100/search_space),
|
||||||
|
searched, search_space, min_diff,
|
||||||
|
export_recipe(best_recipe)
|
||||||
|
))
|
||||||
|
return min_diff, best_recipe, best_color
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
luckycolor = None
|
||||||
|
limit = 1
|
||||||
|
while luckycolor is None:
|
||||||
|
note = '\n'.join(
|
||||||
|
[
|
||||||
|
'请输入你的幸运色,用空格分隔。',
|
||||||
|
'如你的幸运色为100, 200, 100, 请输入 100 200 100。',
|
||||||
|
'默认每一种颜色采用的最大数量为1,若你希望用更多的颜色,可以在幸运色后追加一个数字表示每种颜色最大使用的颜色数量,如 100 200 100 2 表示每种颜色最多使用两个',
|
||||||
|
'不建议指定超过两个以上的颜色,所需的搜索空间可能过大导致无法在可接受的时间范围内计算完成,如一种颜色搜索空间为2^16=65536种组合,两种为3^16=43046721种组合。'
|
||||||
|
|
||||||
|
])
|
||||||
|
print(note)
|
||||||
|
try:
|
||||||
|
luckycolor_str = input('>>> ')
|
||||||
|
luckycolor = luckycolor_str.split()
|
||||||
|
luckycolor = [int(x) for x in luckycolor]
|
||||||
|
if len(luckycolor) < 3 or len(luckycolor) > 4:
|
||||||
|
raise ValueError
|
||||||
|
if len(luckycolor) == 4:
|
||||||
|
limit = luckycolor[3]
|
||||||
|
except Exception:
|
||||||
|
print('幸运色颜色格式错误qwq')
|
||||||
|
|
||||||
|
min_diff, best_recipe, best_color = find_best_color(luckycolor, limit=limit)
|
||||||
|
print('搜索完成!')
|
||||||
|
print('=================================')
|
||||||
|
print('你的幸运色为:', luckycolor)
|
||||||
|
print('最小颜色误差:', min_diff)
|
||||||
|
print('最佳配方:', export_recipe(best_recipe))
|
||||||
|
print('由此配方获得的幸运色:', best_color)
|
||||||
|
print('当穿着单件衣服时伤害减免为:', calculate_multipler(min_diff))
|
||||||
|
print('当穿着全套衣服时伤害减免为:', calculate_multipler(min_diff)**4)
|
||||||
|
print('=================================')
|
||||||
Loading…
Reference in New Issue
Block a user