流水線合成材料依賴表的生成演算法
阿新 • • 發佈:2018-12-30
前不久玩了一個燒腦的遊戲"異星工廠",就是開局一農民,然後通過建造自動化的流水線,最後合成宇宙飛船飛回故鄉的故事.其中自動化的流水線需要玩家自己規劃,比如這樣的:
下面的這個是遊戲中的一個物品"電力機械臂"的合成配方:
可以看到,這裡合成一個"電力機械臂",需要"齒輪","鐵板","電路板"這三種材料,而鐵板又是由鐵礦直接加工而成的,但是電路板的合成就很複雜了.
縱使有一本手冊大全,也是無法對遊戲提供幫助的,看下游戲開局地圖:
礦產的位置很固定,因此無法對生產線的規劃起到作用.
但是,如果能從原材料出發,逐漸合成愈加複雜的物品,直至最後的宇宙飛船,這樣就對流水線的規劃有了一定的參考作用,而這個演算法也是解決這個問題的.
輸入:
產品,原料1,原料2....
(輸入資料為無限可列個,如果沒有原料,則表示產品為可以直接獲得的,無需合成)
輸出:
從原材料出發,直至合成所有的物品的依賴圖
下面是我做的一個例子:
輸入:
iron_ore, #這裡iron_ore為鐵礦,是可以從遊戲地圖上直接獲得的,無需材料合成 copper_ore, copper_cable,copper_plate #這裡銅線copper_cable,需要銅板copper_plate合成,而銅板是由下面的那個公式合成來的 copper_plate,copper_ore iron_plate,iron_ore electronic_circuit,iron_plate,copper_plate iron_gear_wheel,iron_plate inserter,electronic_circuit,iron_gear_wheel,iron_plate science_pack_1,copper_plate,iron_gear_wheel transport_belt,iron_plate,iron_gear_wheel
輸出:
類似這樣的圖:
從左下角的iron_ore(鐵礦)與copper_ore(銅礦),逐漸向右上方依次合成,直至合成全部產品.
程式碼:
import matplotlib.pyplot as plt file = open("connections.txt", 'r')#這裡的connections.txt就是一個文字,文字內容為上面輸入的資料 # 原材料,用於記錄原料與遍歷結束後的繪圖,不同層級用"##"分割 raw_material = [] # 待篩選的產品 products = [] # 繪圖中的直線記錄列表 line_plot = [] # 記錄每一層的個數 each_level_num = [] num_in_this_level = 0 for line in file: line = str(line).strip("\n").split(",") line = [i for i in line if i] print(line) if len(line) == 1: raw_material.append(",".join(line)) num_in_this_level += 1 else: products.append(line) file.close() raw_material.append("###") each_level_num.append(num_in_this_level) while len(products): num_in_this_level = 0 # pro:每一個待篩選產品,list for pro in products: # module:待篩選產品的元件,str module_in_num = 0 for module in pro[1:]: module = module.replace(" ", '') if module in raw_material: module_in_num += 1 else: break if module_in_num == len(pro) - 1: raw_material.append(pro[0]) num_in_this_level += 1 products.remove(pro) # 開始記錄繪圖的直線指向座標 line = [] for module in pro[1:]: target = raw_material.index(module) line.append(target) line_plot.append(line) raw_material.append("###") each_level_num.append(int(num_in_this_level)) # raw_material生成結束,開始繪圖 # 當前層數 level = 0 # 當前層中的位置 num_in_this_level = 0 # line_plot中應該繪製的下標 plt_num = 0 for material in raw_material: if material == "###": level += 1 num_in_this_level = 0 continue plt.text(level * 10, 10 * num_in_this_level + (level + 1) * 7, material) # print("描點" + material, level * 10, 10 * num_in_this_level + (level + 1) * 7) if level > 0: # 開始繪圖 targets = line_plot[plt_num] plt_num += 1 # target為每一個需要相連的下標 for target in targets: # target_level為目標層級 target_level = 0 for level_num in each_level_num: if target > level_num: target -= level_num target -= 1 target_level += 1 else: plt.plot([target_level * 10, level * 10], [target * 10 + (target_level + 1) * 7, 10 * num_in_this_level + 7 * (level + 1)]) # print("劃線") # print([target_level * 5, target * 10 + (target_level + 1) * 7], # [level * 10, 10 * num_in_this_level + 7 * (level + 1)]) break num_in_this_level += 1 plt.show()
這裡通過matplotlib.pyplot來繪圖.