添加 'find_my_luckycolor.py'

This commit is contained in:
mingyang 2022-06-22 14:07:26 +08:00
parent 661d8d08a1
commit abbab157fd

156
find_my_luckycolor.py Normal file
View 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('=================================')