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

8 months ago
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))