You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
6.1 KiB
Python

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import json
from igraph import Graph, plot
with open('data.json', 'r', encoding='utf-8') as file:
data_raw = json.load(file)
data = json.loads(json.dumps(data_raw))
#数据补充
for node_name in data_raw:
node_info_raw = data_raw[node_name]
node_info = data[node_name]
for path_to in node_info_raw['path_to']:
is_key_need = 'key_need' in path_to
key_need = path_to['key_need'] if is_key_need else ''
is_one_way_door = key_need == '单向门'
is_one_way = not is_one_way_door and 'is_one_way' in path_to
if is_one_way_door:
if not 'key_get' in node_info:
node_info['key_get'] = []
is_key_need = True
key_need = f'单向门-{node_name}-{path_to['name']}'
node_info['key_get'].append(key_need)
node_info['path_to']
if not is_one_way:
target_node_info = data[path_to['name']]
append_path = {'name':node_name}
if is_key_need:
append_path['key_need'] = key_need
target_node_info['path_to'].append(append_path)
#多余数据删除
for node_name in data:
node_info = data[node_name]
for path_to in node_info['path_to']:
is_key_need = 'key_need' in path_to
key_need = path_to['key_need'] if is_key_need else ''
is_one_way_door = key_need == '单向门'
is_one_way = not is_one_way_door and 'is_one_way' in path_to
if is_one_way_door:
key_need = f'单向门-{node_name}-{path_to['name']}'
path_to['key_need'] = key_need
path_to.pop('is_one_way', None)
#BFS
start_node_name = '破碎遗迹'
end_node_name = '战斗-魂魄妖忌'
start_node = (start_node_name,set(),set(),[start_node_name],'') #namekey_get, key_usepathportal
stack = [start_node]
close_set = set()
useless_node_list = []
useless_key_list = []
while True:
if len(stack)==0:
break
current = stack.pop(0)
current_name = current[0]
current_key_get = current[1]
current_key_use = current[2]
current_path = current[3]
current_portal = current[4]
if current_name == '白玉楼' and current_portal == '':
current_portal = current_name
if current_name == end_node_name:
useless_node = []
useless_key = []
for node_name in data:
if not node_name in current_path:
useless_node.append(node_name)
if 'key_get' in data[node_name]:
for key_get in data[node_name]['key_get']:
if not key_get in current_key_use:
useless_key.append(key_get)
useless_node_list.append(useless_node)
useless_key_list.append(useless_key)
continue
if 'key_get' in data[current_name]:
for key_get in data[current_name]['key_get']:
if not key_get in current_key_get:
current_key_get.add(key_get)
current_path.append(f'获取({key_get})')
for path_to in data[current_name]['path_to']:
is_key_need = 'key_need' in path_to
if is_key_need and not path_to['key_need'] in current_key_get:
continue
next_name = path_to['name']
current_key_list = list(current_key_get)
current_key_list.sort()
next_name_with_key = next_name + ':' + ','.join(current_key_list)
if next_name_with_key in close_set:
continue
close_set.add(next_name_with_key)
next_path = current_path.copy()
next_path.append(next_name)
next_key_use = current_key_use.copy()
if is_key_need and path_to['key_need'] in current_key_get:
next_key_use.add(path_to['key_need'])
next_node = (next_name, current_key_get.copy(), next_key_use, next_path, current_portal)
stack.insert(-1,next_node)
#传送
if current_name == '白玉楼' and not current_portal == '':
next_name = current_portal
current_key_list = list(current_key_get)
current_key_list.sort()
next_name_with_key = next_name + ':' + ','.join(current_key_list)
if next_name_with_key in close_set:
continue
close_set.add(next_name_with_key)
next_path = current_path.copy()
next_path.append(f'传送({next_name})')
next_node = (next_name, current_key_get.copy(), current_key_use.copy(), next_path, current_portal)
stack.insert(-1,next_node)
if not current_name == '白玉楼' and not current_portal == '':
next_name = '白玉楼'
current_key_list = list(current_key_get)
current_key_list.sort()
next_name_with_key = next_name + ':' + ','.join(current_key_list)
if next_name_with_key in close_set:
continue
close_set.add(next_name_with_key)
next_path = current_path.copy()
next_path.append(f'传送({next_name})')
next_node = (next_name, current_key_get.copy(), current_key_use.copy(), next_path, current_name)
stack.insert(-1,next_node)
success_count = len(useless_node_list)
key_set = set()
useless_node_dict = {}
useless_key_dict = {}
for node_name in data:
useless_node_dict[node_name] = 0
if 'key_get' in data[node_name]:
for key_get in data[node_name]['key_get']:
if not key_get in key_set:
key_set.add(key_get)
useless_key_dict[key_get] = 0
node_max = len(data)
key_max = len(key_set)
for useless_node in useless_node_list:
for key in useless_node:
useless_node_dict[key] += 1
for useless_key in useless_key_list:
for key in useless_key:
useless_key_dict[key] += 1
useless_node_count_sum = sum(map(lambda x: len(x), useless_node_list))
print('success_count:', success_count)
print('useless_node_avg:', "{:.2f}%".format(useless_node_count_sum / success_count / node_max * 100))
for useless_node in useless_node_dict:
print("{} {:.2f}%".format(useless_node,useless_node_dict[useless_node] / success_count * 100))
print("-"*20)
for useless_key in useless_key_dict:
print("{} {:.2f}%".format(useless_key,useless_key_dict[useless_key] / success_count * 100))