我主要是使用Pillow for Python创建一个程序,其中随机生成cat Owl 的图片.它通过为OWL Select 不同的部分来实现这一点,即从各种嵌套词典中为不同的预制艺术资源图像 Select 文件路径.这些部分包括:底座(cat Owl 的身体)、图案(覆盖在cat Owl 羽毛上的图案)和配件(如帽子、眼镜等).然后,组成这些选定部分的每个部分的文件路径被放入一个大列表中,并被放入一个for循环,该循环使用文件路径来创建每个图像,对它们进行着色,然后将完成的图像合成到最终图像中.The issue I am having is that sometimes, mainly when I have the program create multiple owls in one go as a batch, sometimes an owl will have assets on them that were not intended.我在这些不正确的cat Owl 上看到的不需要的部件类型总是不正确的图案和/或配件.下面是其中的一个示例:

The Owl that came out of the batch: The Owl that came out of the batch

现在,每个创建的OWL都有一个特殊的代码作为其文件名的一部分.这段代码基本上是一个字典键列表,当放回程序中时,它允许使用这些键在文件路径字典中筛选OWL的各个部分,然后重新创建OWL图像.

我上面展示的cat Owl 有一个代码键:BC0_PC2_CC_Orca_White_ACG15.我将仔细判断代码的每个部分,以显示每个部分的含义.BC0意味着这个cat Owl 基地应该是一个伟大的灰色cat Owl ,它确实是.PC2意味着它的图案应该是树叶,它似乎是这样的,但它也有一个棋盘图案.CC意味着它将有一个简单的配色方案.Orca意味着它的底部将按照虎鲸的配色方案着色,White意味着它的眼睛、喙和脚将被涂成白色.ACG15意味着cat Owl 将有一种特定类型的眼镜配件.

当我把这只cat Owl 的代码放回程序中时,它正确地重新创建了cat Owl ,如下所示:

The Owl after its code was put back into the program: enter image description here

我正在寻求关于如何处理这个问题的建议.作为背景,下面我将解释如何通过注释代码创建OWL图像的基本过程,特别是关于它的模式和附件.

第1部分:创建cat Owl 的代码密钥

def owl_pull():

def owl_pull():
    # for this program, when you want to generate an owl(s) it all ask you to choose the tier of probability.
    # 1 = Normal and 2 = Lucky. This tier determines the probabilities for generating parts of different rarity for th owl
    print("Please type in the number a rarity tier. This will modify the different probabilities of pulling the different rarities for each part of your owl.")
    print("Tier 1 \nTier 2 \n")
    tier = int(input("Type Tier:"))
    # This value is the number of times the program creates an owl
    pull_times = 1
    while pull_times > 0:
        # while pull times is above 0, it will generate an owl code and then create the owl before saving it into a file
        # it takes the tier your chose and puts it into the function to generate the code
        final_owl_code = create_code(tier)
        reincarnate_owl(final_owl_code)
        print(f"Your owl's Code is: {turn_code_to_string(final_owl_code)}")

        pull_times-=1

def create_code(rarity):

def create_code(rarity):
    owl_code = []

    b = create_base_code(rarity)
    owl_code.append(b)

    # Once it determines the code for the base of the owl, it will take the code and the tier of rarity requested
    # to determine the code for the owl's pattern.
    p = create_pattern_code(rarity, b)
    # Once done, it will add on the code to the final code of the owl.
    owl_code.append(p)

    c = create_color_code(rarity)
    owl_code.append(c)
    color_name = generate_color()
    owl_code.append(color_name)

    eye_color_name = generate_color()
    owl_code.append(eye_color_name)

    # For accessories, we need to determine what type of accessories, if any, the owl can have.
    # An owl can have up to 2 accessories slots filled as long as they are not of the same type
    # These types of accessories are represented by dictionary keys
    a_type1 = create_accessory_type_code(rarity)
    a_type2 = create_accessory_type_code(rarity)
    print(a_type1, a_type2)
    a1 = ""
    a2 = ""
    # Once the type of accessories is determined, it will then compare in the types are the same.
    # If they are both the same, and it didn't determine that it didn't need a first accessory
    # the program will drop the 2nd accessory and add then generate what actual accessory the owl
    # will have and add it to the code.
    if a_type1 == a_type2 and a_type1 != "N/A":
        a1 = create_accessory_code(a_type1)
        owl_code.append(a1)
    # Else it will add on any accessories of the types it rolled as long as it
    # was determined the owl would have that accessory slot filled to begin with.
    else:
        if a_type1 != "N/A":
            a1 = create_accessory_code(a_type1)
            owl_code.append(a1)
        if a_type2 != "N/A":
            a2 = create_accessory_code(a_type2)
            owl_code.append(a2)

    return owl_code

第1a部分:创建图案代码键

def create_pattern_code(rarity, base):

def create_pattern_code(rarity, base):
    # The function determines the rarity of the pattern for the owl
    whats_the_rarity_pattern = chance_decider(rarity, "pattern").lower()
    # Each pattern is tied to a specific owl's base.
    # Within the patterns list, each owl is within a dictionary based on it's rarity
    # EX: "Common" owl bases have their patterns nested in the "Common" Dictionary
    # Each owl has Commom, Uncommon, Rare, and Legendary patterns
    which_base_rarity = 0
    if "C" in base:
        which_base_rarity = 0
    elif "U" in base:
        which_base_rarity = 1
    elif "R" in base:
        which_base_rarity = 2
    elif "L" in base:
        which_base_rarity = 3

    # it takes the rarity of the owl base, finds the owl's code key within the dictionary
    # then, based on the rarity of pattern rolled, it will chose a pattern from within a dictionary represnting each rarity
    # and then randomly chose an individual pattern's dictionary key
    if whats_the_rarity_pattern == "common":
        pattern_dict = Owl_Attributes.Patterns[which_base_rarity][base]["PC"]
        pattern = random.choice((list(pattern_dict.keys())))
        return pattern

    elif whats_the_rarity_pattern == "uncommon":
        pattern_dict = Owl_Attributes.Patterns[which_base_rarity][base]["PU"]
        pattern = random.choice((list(pattern_dict.keys())))
        return pattern

    elif whats_the_rarity_pattern == "rare":
        pattern_dict = Owl_Attributes.Patterns[which_base_rarity][base]["PR"]
        pattern = random.choice((list(pattern_dict.keys())))
        return pattern

    elif whats_the_rarity_pattern == "legendary":
        pattern_dict = Owl_Attributes.Patterns[which_base_rarity][base]["PL"]
        pattern = random.choice((list(pattern_dict.keys())))
        return pattern

第1b部分:创建附件代码密钥

def create_accessory_type_code(rarity):

def create_accessory_type_code(rarity):
    # the function takes the tier you rolled and determines the rarity of the accessory
    whats_the_rarity_accessory = chance_decider(rarity, "accessory").lower()
    if whats_the_rarity_accessory == "n/a":
        accessory_type_key = "N/A"
        return accessory_type_key
    if whats_the_rarity_accessory == "common":
        accessory_type_dict = Owl_Attributes.Accessories[0]["AC"]
        accessory_type_key = random.choice(list(accessory_type_dict.keys()))
        return accessory_type_key
    elif whats_the_rarity_accessory == "uncommon":
        accessory_type_dict = Owl_Attributes.Accessories[0]["AU"]
        accessory_type_key = random.choice(list(accessory_type_dict.keys()))
        return accessory_type_key
    elif whats_the_rarity_accessory == "rare":
        accessory_type_dict = Owl_Attributes.Accessories[0]["AR"]
        accessory_type_key = random.choice(list(accessory_type_dict.keys()))
        return accessory_type_key
    elif whats_the_rarity_accessory == "legendary":
        accessory_item_dict = Owl_Attributes.Accessories[0]["AL"]
        accessory_type_key = random.choice(list(accessory_item_dict.keys()))
        return accessory_type_key

def create_accessory_code(type):

def create_accessory_code(type):
    # if the type of accessory has "AC" in its key, meaning "Common" it makes sure to draw from with the
    # "Common" dictionary. Same for "AU" for "Uncommon", "AR" for "Rare" and "AL" for "Legendary"
    # It will then take the dictionary key for the type of accessory it previously rolled and search for a random
    # key for an accessory, returning the key to be added to the owl's final code name
    if "AC" in type:
        accessory_item_dict = Owl_Attributes.Accessories[0]["AC"][type]
        accessory_item_key = random.choice(list(accessory_item_dict.keys()))
        return accessory_item_key
    elif "AU" in type:
        accessory_item_dict = Owl_Attributes.Accessories[0]["AU"][type]
        accessory_item_key = random.choice(list(accessory_item_dict.keys()))
        return accessory_item_key
    elif "AR" in type:
        accessory_item_dict = Owl_Attributes.Accessories[0]["AR"][type]
        accessory_item_key = random.choice(list(accessory_item_dict.keys()))
        return accessory_item_key
    elif "AL" in type:
        accessory_item_dict = Owl_Attributes.Accessories[0]["AL"][type]
        accessory_item_key = random.choice(list(accessory_item_dict.keys()))
        return accessory_item_key

第2部分:生成cat Owl

def reincarnate_owl(code):

def reincarnate_owl(code):

    remade_owl = Image.open("Owl_project_pictures\\_owl_blank_NC.png")
    # the code key for the base is always the first value in the code
    base_key = code[0]
    # the code key for the batter is always the second value in the code
    pat_key = code[1]
    color_key = code[3]
    color_parts = convert_colorlist_RGB(Owl_Attributes.Colors[0][color_key])
    eye_color_key = code[4]
    eye_color_parts = convert_colorlist_RGB(Owl_Attributes.Colors[0][eye_color_key])
    eye_color = eye_color_parts[0]
    common_colors = False
    uncommon_colors = False
    part_count = 0
    acc_count = 0
    # This list will soon be filled with strings representing the file paths for the art assets that will create the owl
    base_parts = []

    if "C" in base_key:
        base_parts = Owl_Attributes.Bases[0][base_key]
    elif "U" in base_key:
        base_parts = Owl_Attributes.Bases[1][base_key]
    elif "R" in base_key:
        base_parts = Owl_Attributes.Bases[2][base_key]
    elif "L" in base_key:
        base_parts = Owl_Attributes.Bases[3][base_key]

    # Patterns need to be layered properly on the owl to look right.
    # In this case, they are always layered on after the image with the file name ending in "_accents.png"
    # To make sure this happens, the pattern is generated and then, using a for loop, finds it's place within
    # the list of file path strings and inserted after the file path string that has "_accents" in it.
    # sometimes Patterns are a list of images meant to be layered on top of eachother, thus they are always treated as a
    #list when adding them.
    for parts in base_parts:
        if "_accent" in parts:
            part_count += 1
            # To add on the pattern, we need the image's file path. The base code key and it's respective pattern code key
            # are put through the generate_pattern function to retrieve the file path.
            pattern_list = generate_pattern(pat_key, base_key)
            for pat in pattern_list:
                base_parts.insert(part_count, pat)
                part_count += 1
        part_count += 1

    if "CC" in code[2]:
        common_colors = True
    elif "UC" in code[2]:
        uncommon_colors = True
    bonus_count = 0
    for b_parts in base_parts:
        if "_bonus1" in b_parts and common_colors:
            base_parts.remove(base_parts[bonus_count])
            base_parts.remove(base_parts[bonus_count])
        elif "_bonus2" in b_parts and uncommon_colors:
            base_parts.remove(base_parts[bonus_count])
        bonus_count+= 1

    # For each Accessory it uses a for loop to find each accessory code key within the code
    # it then takes each code key and runs it through the generate_accessory that returns that keys definition
    # that being a file path for an image.
    # depending on the file names within the path it will either add on the file path to the front of the list of file paths
    # or to the back of the list of file paths.
    for accessory in code:
        if "AC" in accessory or "AU" in accessory or "AR" in accessory or "AL" in accessory:
            accessory_part = generate_accessory(code[acc_count])
            if "Back Accessories" in accessory_part:
                base_parts.insert(0, accessory_part)
            elif "Front Accessories" in accessory_part:
                base_parts.append(accessory_part)
        acc_count+=1

第2a部分:生成模式

def generate_pattern(part_key, base_key):

def generate_pattern(part_key, base_key):
    # it takes the code key for the pattern and removes the numbers from it to create the key for rarity of the pattern
    # it takes the rarity of the owl, owl base code key, the code key of the rarity of the owl's pattern, and finally the patterns code key
    # to navigate the nested dictionaries to find the pattern image's list of file paths, which it then returns
    pattern = ""
    patt_rarity_key = remove_numbers(part_key)
    # print(patt_rarity_key)
    if "C" in base_key:
        pattern = Owl_Attributes.Patterns[0][base_key][patt_rarity_key][part_key]
        return pattern
    elif "U" in base_key:
        pattern = Owl_Attributes.Patterns[1][base_key][patt_rarity_key][part_key]
        return pattern
    elif "R" in base_key:
        pattern = Owl_Attributes.Patterns[2][base_key][patt_rarity_key][part_key]
        return pattern
    elif "L" in base_key:
        pattern = Owl_Attributes.Patterns[3][base_key][patt_rarity_key][part_key]
        return pattern

第2b部分:生成附件

def generate_accessory(part_key):

def generate_accessory(part_key):
    # it takes the code key for the accessory and removes the numbers from it to create the key for the type of
    # accessory it is to find it within the accessory dictionaries
    # it takes the rarity of the accessory as a key, then the type of accessory as a key
    # and then the code key of the accessory itself to find the file path of that accessory image, which it then returns
    accessory = ""
    acc_rarity_key = remove_numbers(part_key)
    if "AC" in part_key:
        accessory = Owl_Attributes.Accessories[0]["AC"][acc_rarity_key][part_key]
        return accessory
    elif "AU" in part_key:
        accessory = Owl_Attributes.Accessories[0]["AU"][acc_rarity_key][part_key]
        return accessory
    elif "AR" in part_key:
        accessory = Owl_Attributes.Accessories[0]["AR"][acc_rarity_key][part_key]
        return accessory
    elif "AL" in part_key:
        accessory = Owl_Attributes.Accessories[0]["AL"][acc_rarity_key][part_key]
        return accessory

第三部分:相关词典

下面是OWLS文件的相关词典示例 Owl Patterns

Patterns = [
    # Common Owls
    {
        # Great Grey Owl Patterns
        "BC0":
        {
            # Common Patterns
            "PC":
            {
                "PC0": ["Owl_project_pictures\\_owl_blank_NC.png"],
                "PC1": ["Owl_project_pictures\\Common\\Great Grey Owl\\patterns\\Common patterns\\_greatgrey_feathers.png"],
                "PC2": ["Owl_project_pictures\\Common\\Great Grey Owl\\patterns\\Common patterns\\_greatgrey_leaves.png"],
                "PC3": ["Owl_project_pictures\\Common\\Great Grey Owl\\patterns\\Common patterns\\_greatgrey_piebald_NC.png"],
                "PC4": ["Owl_project_pictures\\Common\\Great Grey Owl\\patterns\\Common patterns\\_greatgrey_stripes.png"],
                "PC5": ["Owl_project_pictures\\Common\\Great Grey Owl\\patterns\\Common patterns\\_greatgrey_checkerboard.png"],
                "PC6": ["Owl_project_pictures\\Common\\Great Grey Owl\\patterns\\Common patterns\\_greatgrey_raindrops.png"]
            },

Owl Accessories

Accessories = [
    {
        # Common Accessories
        "AC":
        {
                # Glasses
                "ACG":
                {
                    "ACG0": "Owl_project_pictures\\Accessories\\Common Accessories\\Front Accessories\\Glasses\\_glasses_hex1.png",
                    "ACG1": "Owl_project_pictures\\Accessories\\Common Accessories\\Front Accessories\\Glasses\\_glasses_hex2.png",
                    "ACG2": "Owl_project_pictures\\Accessories\\Common Accessories\\Front Accessories\\Glasses\\_glasses_hex3.png",
                    "ACG3": "Owl_project_pictures\\Accessories\\Common Accessories\\Front Accessories\\Glasses\\_glasses_hex4.png",
                    "ACG4": "Owl_project_pictures\\Accessories\\Common Accessories\\Front Accessories\\Glasses\\_glasses_hex5.png",
                    "ACG5": "Owl_project_pictures\\Accessories\\Common Accessories\\Front Accessories\\Glasses\\_glasses_rectangle1.png",
                    "ACG6": "Owl_project_pictures\\Accessories\\Common Accessories\\Front Accessories\\Glasses\\_glasses_rectangle2.png",
                    "ACG7": "Owl_project_pictures\\Accessories\\Common Accessories\\Front Accessories\\Glasses\\_glasses_rectangle3.png",
                    "ACG8": "Owl_project_pictures\\Accessories\\Common Accessories\\Front Accessories\\Glasses\\_glasses_rectangle4.png",
                    "ACG10": "Owl_project_pictures\\Accessories\\Common Accessories\\Front Accessories\\Glasses\\_glasses_rectangle5.png",
                    "ACG11": "Owl_project_pictures\\Accessories\\Common Accessories\\Front Accessories\\Glasses\\_glasses_smallround1.png",
                    "ACG12": "Owl_project_pictures\\Accessories\\Common Accessories\\Front Accessories\\Glasses\\_glasses_smallround2.png",
                    "ACG13": "Owl_project_pictures\\Accessories\\Common Accessories\\Front Accessories\\Glasses\\_glasses_smallround3.png",
                    "ACG14": "Owl_project_pictures\\Accessories\\Common Accessories\\Front Accessories\\Glasses\\_glasses_smallround4.png",
                    "ACG15": "Owl_project_pictures\\Accessories\\Common Accessories\\Front Accessories\\Glasses\\_glasses_smallround5.png"
                },

推荐答案

而不是这样:

    for parts in base_parts:
        if "_accent" in parts:
            part_count += 1
            # To add on the pattern, we need the image's file path. The base code key and it's respective pattern code key
            # are put through the generate_pattern function to retrieve the file path.
            pattern_list = generate_pattern(pat_key, base_key)
            for pat in pattern_list:
                base_parts.insert(part_count, pat)
                part_count += 1
        part_count += 1

执行以下操作:

    new_base = []
    for parts in base_parts:
        new_base.append( parts )
        if "_accent" in parts:
            new_base.extend( generate_pattern(pat_key, base_key) )
    base_parts = new_base

现在,您在迭代列表时不会修改它,也不会试图跟踪列表索引.

不过,现在我来看一下,既然generate_pattern调用不依赖于循环值,那么这是什么目的呢?你真的在try 多次应用这种模式吗?您所拥有的与以下内容相同:

    pattern_list = generate_pattern(pat_key, base_key)
    new_base = []
    for parts in base_parts:
        new_base.append( parts )
        if "_accent" in parts:
            new_base.extend( pattern_list )
    base_parts = new_base

Python相关问答推荐

opencv Python稳定的图标识别

Polars LazyFrame在收集后未返回指定的模式顺序

删除最后一个pip安装的包

ModuleNotFound错误:没有名为flags.State的模块; flags不是包

_repr_html_实现自定义__getattr_时未显示

Excel图表-使用openpyxl更改水平轴与Y轴相交的位置(Python)

计算组中唯一值的数量

所有列的滚动标准差,忽略NaN

在pandas中使用group_by,但有条件

将JSON对象转换为Dataframe

有没有一种ONE—LINER的方法给一个框架的每一行一个由整数和字符串组成的唯一id?

重置PD帧中的值

如何使用OpenGL使球体遵循Python中的八样路径?

ruamel.yaml dump:如何阻止map标量值被移动到一个新的缩进行?

Discord.py -

如果包含特定值,则筛选Groupby

以异步方式填充Pandas 数据帧

处理Gekko的非最优解

如何将相同组的值添加到嵌套的Pandas Maprame的倒数第二个索引级别

一维不匹配两个数组上的广义ufunc