import itertools
import math
# ==========================================
# 1. 遊戲參數與寶石計算引擎
# ==========================================
BASE_DMG = 50
BASE_DELAY = 1.0
TIME_LIMIT = 60.0
NUM_FLOORS = 81
def calculate_weapon_stats(combo_string):
"""
根據寶石順序,計算最終的神劍屬性
combo_string: 類似 'RRES', 'EEES' 的 4 字元字串
"""
dmg = BASE_DMG
delay = BASE_DELAY
for gem in combo_string:
if gem == 'R':
dmg += 200
elif gem == 'E':
dmg *= 1.8
delay += 0.2
elif gem == 'S':
delay *= 0.6
dmg -= 50
if dmg < 10:
dmg = 10
# 避免極端情況浮點數誤差,攻速最低限制為 0.01 秒
delay = max(0.01, delay)
return dmg, delay
def can_beat_boss(dmg, delay, floor_k):
"""判斷特定的武器屬性是否能在 60 秒內擊殺第 K 層的 Boss"""
boss_hp = 5000 + (1000 * floor_k)
boss_armor = 10 * floor_k
hits
= math.
floor(TIME_LIMIT
/ delay
) + 1 actual_dmg_per_hit = max(1, dmg - boss_armor)
total_damage = hits * actual_dmg_per_hit
return total_damage >= boss_hp
# ==========================================
# 2. 模擬與建圖 (Graph Construction)
# ==========================================
def build_bipartite_graph():
# 產生 3^4 = 81 種寶石鑲嵌組合
gems = ['R', 'E', 'S']
all_combos = [''.join(c) for c in itertools.product(gems, repeat=4)]
print(f"✅ 成功生成 {len(all_combos)} 種獨特的寶石配裝方案。")
# 建立二分圖的 Adjacency List
# graph[combo] = [能擊殺的樓層 list]
graph = {}
for combo in all_combos:
dmg, delay = calculate_weapon_stats(combo)
beatable_floors = []
for floor in range
(1, NUM_FLOORS
+ 1): if can_beat_boss
(dmg
, delay
, floor): beatable_floors.
append(floor) graph[combo] = beatable_floors
return graph, all_combos
# ==========================================
# 3. 核心演算法:最大二分圖匹配 (Kuhn's Algorithm)
# ==========================================
def max_bipartite_matching(graph, combos):
"""
使用 DFS 尋找增廣路徑 (Augmenting Path)
來解出最多能通關多少層樓。
"""
# 紀錄某個樓層目前是被哪個 combo 佔用
floor_assignment = {}
def dfs_match(combo, visited):
# 遍歷這個配裝能打贏的所有樓層
for floor in graph
[combo
]: # 如果該樓層還沒有分配配裝,或者佔用該樓層的配裝可以被挪去打別層(遞迴尋找增廣路)
if floor not in floor_assignment or dfs_match
(floor_assignment
[floor], visited
): floor_assignment
[floor] = combo
return True
return False
matches = 0
# 對每一種配裝嘗試進行匹配
for combo in combos:
visited = set()
if dfs_match(combo, visited):
matches += 1
return matches, floor_assignment
# ==========================================
# 4. 執行主程式
# ==========================================
def main():
print("⚔️ 啟動 Stick Ranger 無盡之塔 81 層模擬器...\n")
# 1. 建立圖形
graph, combos = build_bipartite_graph()
# 2. 跑圖論匹配演算法
max_wins, final_assignments = max_bipartite_matching(graph, combos)
# 3. 輸出結果分析
print(f"🏆 在 81 層中,不重複使用配裝的情況下,極限能通關: 【 {max_wins} 】層!\n")
print("--- ⚔️ 部分精選通關樓層配裝報告 ⚔️ ---")
# 反轉 dict 以樓層來排序輸出
floor_to_combo = {k: v for k, v in final_assignments.items()}
# 顯示前 5 樓、中間樓層、以及挑戰成功的最高樓層
floors_to_show = [1, 2, 3, 4, 5, 40, max(floor_to_combo.keys())]
for floor in sorted
(list
(set
(floors_to_show
))): if floor in floor_to_combo
: combo
= floor_to_combo
[floor] dmg, delay = calculate_weapon_stats(combo)
boss_hp
= 5000 + (1000 * floor)
print(f"🏢 第 {floor:02d} 層 | Boss [HP:{boss_hp:6d}, 甲:{boss_armor:3d}] "
f"| 配裝: {combo} (傷:{dmg:6.1f}, 攻速:{delay:.2f}s)")
# 尋找最強破甲與最高秒傷配裝
print("\n--- 🔬 神劍資料科學分析 ---")
best_dmg_combo = max(combos, key=lambda c: calculate_weapon_stats(c)[0])
fastest_combo = min(combos, key=lambda c: calculate_weapon_stats(c)[1])
print(f"🔥 最高單發傷害配裝: {best_dmg_combo} (傷害: {calculate_weapon_stats(best_dmg_combo)[0]:.1f})")
print(f"⚡ 最高攻擊速度配裝: {fastest_combo} (間隔: {calculate_weapon_stats(fastest_combo)[1]:.3f}s)")
if __name__ == '__main__':
main()
aW1wb3J0IGl0ZXJ0b29scwppbXBvcnQgbWF0aAoKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIyAxLiDpgYrmiLLlj4PmlbjoiIflr7bnn7PoqIjnrpflvJXmk44KIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KQkFTRV9ETUcgPSA1MApCQVNFX0RFTEFZID0gMS4wClRJTUVfTElNSVQgPSA2MC4wCk5VTV9GTE9PUlMgPSA4MQoKZGVmIGNhbGN1bGF0ZV93ZWFwb25fc3RhdHMoY29tYm9fc3RyaW5nKToKICAgICIiIgogICAg5qC55pOa5a+255+z6aCG5bqP77yM6KiI566X5pyA57WC55qE56We5YqN5bGs5oCnCiAgICBjb21ib19zdHJpbmc6IOmhnuS8vCAnUlJFUycsICdFRUVTJyDnmoQgNCDlrZflhYPlrZfkuLIKICAgICIiIgogICAgZG1nID0gQkFTRV9ETUcKICAgIGRlbGF5ID0gQkFTRV9ERUxBWQogICAgCiAgICBmb3IgZ2VtIGluIGNvbWJvX3N0cmluZzoKICAgICAgICBpZiBnZW0gPT0gJ1InOgogICAgICAgICAgICBkbWcgKz0gMjAwCiAgICAgICAgZWxpZiBnZW0gPT0gJ0UnOgogICAgICAgICAgICBkbWcgKj0gMS44CiAgICAgICAgICAgIGRlbGF5ICs9IDAuMgogICAgICAgIGVsaWYgZ2VtID09ICdTJzoKICAgICAgICAgICAgZGVsYXkgKj0gMC42CiAgICAgICAgICAgIGRtZyAtPSA1MAogICAgICAgICAgICBpZiBkbWcgPCAxMDogCiAgICAgICAgICAgICAgICBkbWcgPSAxMAogICAgICAgICAgICAgICAgCiAgICAjIOmBv+WFjealteerr+aDheazgea1rum7nuaVuOiqpOW3ru+8jOaUu+mAn+acgOS9jumZkOWItueCuiAwLjAxIOenkgogICAgZGVsYXkgPSBtYXgoMC4wMSwgZGVsYXkpIAogICAgcmV0dXJuIGRtZywgZGVsYXkKCmRlZiBjYW5fYmVhdF9ib3NzKGRtZywgZGVsYXksIGZsb29yX2spOgogICAgIiIi5Yik5pa354m55a6a55qE5q2m5Zmo5bGs5oCn5piv5ZCm6IO95ZyoIDYwIOenkuWFp+aTiuauuuesrCBLIOWxpOeahCBCb3NzIiIiCiAgICBib3NzX2hwID0gNTAwMCArICgxMDAwICogZmxvb3JfaykKICAgIGJvc3NfYXJtb3IgPSAxMCAqIGZsb29yX2sKICAgIAogICAgaGl0cyA9IG1hdGguZmxvb3IoVElNRV9MSU1JVCAvIGRlbGF5KSArIDEKICAgIGFjdHVhbF9kbWdfcGVyX2hpdCA9IG1heCgxLCBkbWcgLSBib3NzX2FybW9yKQogICAgCiAgICB0b3RhbF9kYW1hZ2UgPSBoaXRzICogYWN0dWFsX2RtZ19wZXJfaGl0CiAgICByZXR1cm4gdG90YWxfZGFtYWdlID49IGJvc3NfaHAKCiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiMgMi4g5qih5pOs6IiH5bu65ZyWIChHcmFwaCBDb25zdHJ1Y3Rpb24pCiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CmRlZiBidWlsZF9iaXBhcnRpdGVfZ3JhcGgoKToKICAgICMg55Si55SfIDNeNCA9IDgxIOeoruWvtuefs+mRsuW1jOe1hOWQiAogICAgZ2VtcyA9IFsnUicsICdFJywgJ1MnXQogICAgYWxsX2NvbWJvcyA9IFsnJy5qb2luKGMpIGZvciBjIGluIGl0ZXJ0b29scy5wcm9kdWN0KGdlbXMsIHJlcGVhdD00KV0KICAgIAogICAgcHJpbnQoZiLinIUg5oiQ5Yqf55Sf5oiQIHtsZW4oYWxsX2NvbWJvcyl9IOeorueNqOeJueeahOWvtuefs+mFjeijneaWueahiOOAgiIpCiAgICAKICAgICMg5bu656uL5LqM5YiG5ZyW55qEIEFkamFjZW5jeSBMaXN0CiAgICAjIGdyYXBoW2NvbWJvXSA9IFvog73mk4rmrrrnmoTmqJPlsaQgbGlzdF0KICAgIGdyYXBoID0ge30KICAgIGZvciBjb21ibyBpbiBhbGxfY29tYm9zOgogICAgICAgIGRtZywgZGVsYXkgPSBjYWxjdWxhdGVfd2VhcG9uX3N0YXRzKGNvbWJvKQogICAgICAgIGJlYXRhYmxlX2Zsb29ycyA9IFtdCiAgICAgICAgZm9yIGZsb29yIGluIHJhbmdlKDEsIE5VTV9GTE9PUlMgKyAxKToKICAgICAgICAgICAgaWYgY2FuX2JlYXRfYm9zcyhkbWcsIGRlbGF5LCBmbG9vcik6CiAgICAgICAgICAgICAgICBiZWF0YWJsZV9mbG9vcnMuYXBwZW5kKGZsb29yKQogICAgICAgIGdyYXBoW2NvbWJvXSA9IGJlYXRhYmxlX2Zsb29ycwogICAgICAgIAogICAgcmV0dXJuIGdyYXBoLCBhbGxfY29tYm9zCgojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQojIDMuIOaguOW/g+a8lOeul+azle+8muacgOWkp+S6jOWIhuWcluWMuemFjSAoS3VobidzIEFsZ29yaXRobSkKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KZGVmIG1heF9iaXBhcnRpdGVfbWF0Y2hpbmcoZ3JhcGgsIGNvbWJvcyk6CiAgICAiIiIKICAgIOS9v+eUqCBERlMg5bCL5om+5aKe5buj6Lev5b6RIChBdWdtZW50aW5nIFBhdGgpCiAgICDkvobop6Plh7rmnIDlpJrog73pgJrpl5zlpJrlsJHlsaTmqJPjgIIKICAgICIiIgogICAgIyDntIDpjITmn5DlgIvmqJPlsaTnm67liY3mmK/ooqvlk6rlgIsgY29tYm8g5L2U55SoCiAgICBmbG9vcl9hc3NpZ25tZW50ID0ge30gCiAgICAKICAgIGRlZiBkZnNfbWF0Y2goY29tYm8sIHZpc2l0ZWQpOgogICAgICAgICMg6YGN5q236YCZ5YCL6YWN6KOd6IO95omT6LSP55qE5omA5pyJ5qiT5bGkCiAgICAgICAgZm9yIGZsb29yIGluIGdyYXBoW2NvbWJvXToKICAgICAgICAgICAgaWYgZmxvb3Igbm90IGluIHZpc2l0ZWQ6CiAgICAgICAgICAgICAgICB2aXNpdGVkLmFkZChmbG9vcikKICAgICAgICAgICAgICAgICMg5aaC5p6c6Kmy5qiT5bGk6YKE5rKS5pyJ5YiG6YWN6YWN6KOd77yM5oiW6ICF5L2U55So6Kmy5qiT5bGk55qE6YWN6KOd5Y+v5Lul6KKr5oyq5Y675omT5Yil5bGkKOmBnui/tOWwi+aJvuWinuW7o+i3rykKICAgICAgICAgICAgICAgIGlmIGZsb29yIG5vdCBpbiBmbG9vcl9hc3NpZ25tZW50IG9yIGRmc19tYXRjaChmbG9vcl9hc3NpZ25tZW50W2Zsb29yXSwgdmlzaXRlZCk6CiAgICAgICAgICAgICAgICAgICAgZmxvb3JfYXNzaWdubWVudFtmbG9vcl0gPSBjb21ibwogICAgICAgICAgICAgICAgICAgIHJldHVybiBUcnVlCiAgICAgICAgcmV0dXJuIEZhbHNlCgogICAgbWF0Y2hlcyA9IDAKICAgICMg5bCN5q+P5LiA56iu6YWN6KOd5ZiX6Kmm6YCy6KGM5Yy56YWNCiAgICBmb3IgY29tYm8gaW4gY29tYm9zOgogICAgICAgIHZpc2l0ZWQgPSBzZXQoKQogICAgICAgIGlmIGRmc19tYXRjaChjb21ibywgdmlzaXRlZCk6CiAgICAgICAgICAgIG1hdGNoZXMgKz0gMQogICAgICAgICAgICAKICAgIHJldHVybiBtYXRjaGVzLCBmbG9vcl9hc3NpZ25tZW50CgojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQojIDQuIOWft+ihjOS4u+eoi+W8jwojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpkZWYgbWFpbigpOgogICAgcHJpbnQoIuKalO+4jyDllZ/li5UgU3RpY2sgUmFuZ2VyIOeEoeeboeS5i+WhlCA4MSDlsaTmqKHmk6zlmaguLi5cbiIpCiAgICAKICAgICMgMS4g5bu656uL5ZyW5b2iCiAgICBncmFwaCwgY29tYm9zID0gYnVpbGRfYmlwYXJ0aXRlX2dyYXBoKCkKICAgIAogICAgIyAyLiDot5HlnJboq5bljLnphY3mvJTnrpfms5UKICAgIG1heF93aW5zLCBmaW5hbF9hc3NpZ25tZW50cyA9IG1heF9iaXBhcnRpdGVfbWF0Y2hpbmcoZ3JhcGgsIGNvbWJvcykKICAgIAogICAgIyAzLiDovLjlh7rntZDmnpzliIbmnpAKICAgIHByaW50KGYi8J+PhiDlnKggODEg5bGk5Lit77yM5LiN6YeN6KSH5L2/55So6YWN6KOd55qE5oOF5rOB5LiL77yM5qW16ZmQ6IO96YCa6ZecOiDjgJAge21heF93aW5zfSDjgJHlsaTvvIFcbiIpCiAgICAKICAgIHByaW50KCItLS0g4pqU77iPIOmDqOWIhueyvumBuOmAmumXnOaok+WxpOmFjeijneWgseWRiiDimpTvuI8gLS0tIikKICAgIAogICAgIyDlj43ovYkgZGljdCDku6XmqJPlsaTkvobmjpLluo/ovLjlh7oKICAgIGZsb29yX3RvX2NvbWJvID0ge2s6IHYgZm9yIGssIHYgaW4gZmluYWxfYXNzaWdubWVudHMuaXRlbXMoKX0KICAgIAogICAgIyDpoa/npLrliY0gNSDmqJPjgIHkuK3plpPmqJPlsaTjgIHku6Xlj4rmjJHmiLDmiJDlip/nmoTmnIDpq5jmqJPlsaQKICAgIGZsb29yc190b19zaG93ID0gWzEsIDIsIDMsIDQsIDUsIDQwLCBtYXgoZmxvb3JfdG9fY29tYm8ua2V5cygpKV0KICAgIAogICAgZm9yIGZsb29yIGluIHNvcnRlZChsaXN0KHNldChmbG9vcnNfdG9fc2hvdykpKToKICAgICAgICBpZiBmbG9vciBpbiBmbG9vcl90b19jb21ibzoKICAgICAgICAgICAgY29tYm8gPSBmbG9vcl90b19jb21ib1tmbG9vcl0KICAgICAgICAgICAgZG1nLCBkZWxheSA9IGNhbGN1bGF0ZV93ZWFwb25fc3RhdHMoY29tYm8pCiAgICAgICAgICAgIGJvc3NfaHAgPSA1MDAwICsgKDEwMDAgKiBmbG9vcikKICAgICAgICAgICAgYm9zc19hcm1vciA9IDEwICogZmxvb3IKICAgICAgICAgICAgCiAgICAgICAgICAgIHByaW50KGYi8J+PoiDnrKwge2Zsb29yOjAyZH0g5bGkIHwgQm9zcyBbSFA6e2Jvc3NfaHA6NmR9LCDnlLI6e2Jvc3NfYXJtb3I6M2R9XSAiCiAgICAgICAgICAgICAgICAgIGYifCDphY3oo506IHtjb21ib30gKOWCtzp7ZG1nOjYuMWZ9LCDmlLvpgJ86e2RlbGF5Oi4yZn1zKSIpCiAgICAgICAgICAgIAogICAgIyDlsIvmib7mnIDlvLfnoLTnlLLoiIfmnIDpq5jnp5LlgrfphY3oo50KICAgIHByaW50KCJcbi0tLSDwn5SsIOelnuWKjeizh+aWmeenkeWtuOWIhuaekCAtLS0iKQogICAgYmVzdF9kbWdfY29tYm8gPSBtYXgoY29tYm9zLCBrZXk9bGFtYmRhIGM6IGNhbGN1bGF0ZV93ZWFwb25fc3RhdHMoYylbMF0pCiAgICBmYXN0ZXN0X2NvbWJvID0gbWluKGNvbWJvcywga2V5PWxhbWJkYSBjOiBjYWxjdWxhdGVfd2VhcG9uX3N0YXRzKGMpWzFdKQogICAgCiAgICBwcmludChmIvCflKUg5pyA6auY5Zau55m85YK35a6z6YWN6KOdOiB7YmVzdF9kbWdfY29tYm99ICjlgrflrrM6IHtjYWxjdWxhdGVfd2VhcG9uX3N0YXRzKGJlc3RfZG1nX2NvbWJvKVswXTouMWZ9KSIpCiAgICBwcmludChmIuKaoSDmnIDpq5jmlLvmk4rpgJ/luqbphY3oo506IHtmYXN0ZXN0X2NvbWJvfSAo6ZaT6ZqUOiB7Y2FsY3VsYXRlX3dlYXBvbl9zdGF0cyhmYXN0ZXN0X2NvbWJvKVsxXTouM2Z9cykiKQoKaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKICAgIG1haW4oKQ==