简体   繁体   English

从嵌套的dict中选择一个随机值,并在另一个嵌套的dict中更新它

[英]Choosing a random value from a nested dict and updating it in another nested dict

I'm currently coding an RPG Text Game in python and I'm trying create random encounter system on every boot. 我正在编写python中的RPG文本游戏,我正在尝试在每次启动时创建随机遇到系统。 I have a dict with multiple encounters and their corresponding categories and another nested dict which contains the information about the area of the game. 我有一个有多个遭遇的词典及其相应的类别和另一个嵌套的词典,其中包含有关游戏区域的信息。 I can create a random selection and have it printed out, but how do I get that random selection to update in every "interact" in the area nested table. 我可以创建一个随机选择并将其打印出来,但是如何在区域嵌套表中的每个“交互”中更新随机选择。 I want a new random value from the encounters table for each "interact" key in the area nested dict. 我想从区域嵌套字典中的每个“交互”键的遇到表中获得一个新的随机值。

Also I only need the values to be updated so "interact" : "zombie" for example, categories are just for the weighted random selection as I want them to be "random-ish" with most of them being nothing ("") or enemy 此外,我只需要更新值以便"interact" : "zombie" ,例如,类别仅用于加权随机选择,因为我希望它们是“随机的”,其中大部分都不是(“”)或敌人

Though this is the latest version as I've tried lots of different approaches and they all fail - Also this code below errors out and I have no idea how to solve this problem. 虽然这是最新版本,因为我尝试了很多不同的方法,它们都失败了 - 下面的代码也出错了,我不知道如何解决这个问题。 If needed I can also post all my other attempts. 如果需要,我也可以发布所有其他尝试。

Here is my failed attempt: 这是我失败的尝试:

import random

encounters = {
    "enemy" : {
        1 : "zombie",
        2 : "wolf",
        3 : "wraith"
    },

    "chest" : {
        1 : "chest",
        2 : "weapons_chest",
    },

    "npc"   : {
        1 : "villager",
    },

    "furniture" : {
        1 : "bed"
    },

    "nothing"   : {
        1 : ""
    }
}

area = {

    "spawner" : {

        "spawn" : {
            "name"      : "Spawn",
            "interact"  : "",
            "solved"    : False,
            "connects"  : {
                1   : "alleyway_1"
            }
        }
    },

    "alley" : {

        "alleyway_1"   : {
            "name"      : "Alleyway 1",
            "interact"  : "",
            "solved"    : False,
            "connects"  : {
                1   : "spawn",
                2   : "alleyway_2",
                3   : "hall"
            }
        },

        "alleyway_2"   : {
            "name"      : "Alleyway 2",
            "interact"  : "",
            "solved"    : False,
            "connects"  : {
                1   : "alleyway_1"
            }
        }
    }
}

def random_encounters():
    print("random encounters")

    weights_a = [0.3, 0.1, 0.05, 0.05, 0.5]

    encounter_a = random.choices(encounters, weights_a)
    encounter_b = random.choice(list(encounter_a.values()))

    for q, w in area.items():
        for a, s in area[w].items():
            area[w][s]["interact"] = encounter_b

random_encounters()

EDIT: 编辑:

Expected result would be: 预期结果将是:

 area = {

    "spawner" : {

        "spawn" : {
            "name"      : "Spawn",
            "interact"  : "bed",
            "solved"    : False,
            "connects"  : {
                1   : "alleyway_1"
            }
        }
    },

    "alley" : {

        "alleyway_1"   : {
            "name"      : "Alleyway 1",
            "interact"  : "zombie",
            "solved"    : False,
            "connects"  : {
                1   : "spawn",
                2   : "alleyway_2",
                3   : "hall"
            }
        },

        "alleyway_2"   : {
            "name"      : "Alleyway 2",
            "interact"  : "chest",
            "solved"    : False,
            "connects"  : {
                1   : "alleyway_1"
            }
        }
    }
}

Where "interact" : "zombie" zombie is the output from random_encounters() "interact" : "zombie"僵尸是random_encounters()的输出

Since random.choices and random.choice only works with list type, you can get the list of object keys and pick one of them randomly instead. 由于random.choicesrandom.choice仅适用于列表类型,因此您可以获取对象键列表并随机选择其中一个。 The resulting key selected will be used to access the sub dictionary items. 选择的结果密钥将用于访问子字典项。 One more thing, when iterating through the dictionary using for key, values in dictionary.items() , the first variable will be the dictionary key and the other one will be the value corresponding to that key. 还有一件事,当for key, values in dictionary.items()使用for key, values in dictionary.items()迭代字典时,第一个变量将是字典键,另一个变量将是与该键对应的值。 I think you're confusing the order of the two so I also fixed that for you. 我认为你混淆了两者的顺序所以我也为你解决了这个问题。

I also added the import json and print(json.dumps(area, indent=2)) so you can verify that it is what you want. 我还添加了import jsonprint(json.dumps(area, indent=2))这样你就可以验证它是你想要的。 You can delete it after you're done testing. 您可以在完成测试后将其删除。

Edit: In order to set unique encounters for different area, you put the random encounter generating code inside the 2 for loops so that each area will have its own random encounter. 编辑:为了设置不同区域的唯一遭遇,您将随机遭遇生成代码放在2 for循环内,以便每个区域都有自己的随机遭遇。 Also, since you want to set the each items have a certain probability to occur and using list(encounters.keys()) will give a list of dictionary's keys in random order, I decided to change from using list(encounters.keys()) to using encounters_keys=["enemy", "chest", "npc", "furniture", "nothing"] that have the encounters ' keys in the same order of the weights_a so that each type of encounter have a correct probability. 另外,既然你想设置每个项目都有一定的概率发生,并且使用list(encounters.keys())会以随机顺序给出一个字典键的列表,我决定从使用list(encounters.keys())更改list(encounters.keys())使用encounters_keys=["enemy", "chest", "npc", "furniture", "nothing"]具有在encounters '键在相同的顺序weights_a使得每种类型的遭遇的有一个正确的概率。

import random
import json

encounters = {
    "enemy" : {
        1 : "zombie",
        2 : "wolf",
        3 : "wraith"
    },

    "chest" : {
        1 : "chest",
        2 : "weapons_chest",
    },

    "npc"   : {
        1 : "villager",
    },

    "furniture" : {
        1 : "bed"
    },

    "nothing"   : {
        1 : ""
    }
}

area = {

    "spawner" : {

        "spawn" : {
            "name"      : "Spawn",
            "interact"  : "",
            "solved"    : False,
            "connects"  : {
                1   : "alleyway_1"
            }
        }
    },

    "alley" : {

        "alleyway_1"   : {
            "name"      : "Alleyway 1",
            "interact"  : "",
            "solved"    : False,
            "connects"  : {
                1   : "spawn",
                2   : "alleyway_2",
                3   : "hall"
            }
        },

        "alleyway_2"   : {
            "name"      : "Alleyway 2",
            "interact"  : "",
            "solved"    : False,
            "connects"  : {
                1   : "alleyway_1"
            }
        }
    }
}
def random_encounters():
    print("random encounters")
    encounters_keys = ["enemy", "chest", "npc", "furniture", "nothing"]
    weights_a = [0.3, 0.1, 0.05, 0.05, 0.5]

    for q, w in area.items():
        for a, s in area[q].items():
            encounter_a = random.choices(encounters_keys, weights_a)[0]
            encounter_b = random.choice(list(encounters[encounter_a].keys()))
            area[q][a]["interact"] = encounters[encounter_a][encounter_b]

    print(json.dumps(area, indent=2))

random_encounters()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM