流水线合成材料依赖表的生成算法

版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/weixin_35757704/article/details/82556266

前不久玩了一个烧脑的游戏"异星工厂",就是开局一农民,然后通过建造自动化的流水线,最后合成宇宙飞船飞回故乡的故事.其中自动化的流水线需要玩家自己规划,比如这样的:

下面的这个是游戏中的一个物品"电力机械臂"的合成配方:

可以看到,这里合成一个"电力机械臂",需要"齿轮","铁板","电路板"这三种材料,而铁板又是由铁矿直接加工而成的,但是电路板的合成就很复杂了.

纵使有一本手册大全,也是无法对游戏提供帮助的,看下游戏开局地图:

矿产的位置很固定,因此无法对生产线的规划起到作用.

但是,如果能从原材料出发,逐渐合成愈加复杂的物品,直至最后的宇宙飞船,这样就对流水线的规划有了一定的参考作用,而这个算法也是解决这个问题的.

输入:

产品,原料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来绘图.

猜你喜欢

转载自blog.csdn.net/weixin_35757704/article/details/82556266