Esempio n. 1
0
static void
generate_treasure_type(struct rnd *rnd, FILE *out, char letter)
{
    struct treasure treasure;
    int individual_count;
    
    fprintf(out, "Treasure type %c: ", letter);
    
    if (letter >= 'J' && letter <= 'N') {
        individual_count = roll("1d10", rnd);
    } else {
        individual_count = 0;
    }
    
    treasure_initialize(&treasure);
    treasure_type_generate(treasure_type_by_letter(letter), rnd, individual_count, &treasure);
    
    char *description = treasure_alloc_description(&treasure);
    int value_cp = treasure_value_in_cp(&treasure);
    char *value_gp = coins_alloc_gp_cp_description(value_cp);
    fprintf(out, "%s (total %s)\n", description, value_gp);
    free_or_die(value_gp);
    free_or_die(description);
    enumerate_treasure_items(&treasure, out);
    
    treasure_finalize(&treasure);
}
static void
treasure_create_json_object_for_type_A_test(void)
{
    struct rnd *rnd = rnd_alloc_fake_min();
    struct treasure treasure;
    treasure_initialize(&treasure);
    struct treasure_type *treasure_type = treasure_type_by_letter('A');
    treasure_type_generate(treasure_type, rnd, &treasure);
    struct cJSON *json_object = treasure_create_json_object(&treasure);

    assert(cJSON_IsObject(json_object));

    char *json_string = cJSON_PrintUnformatted(json_object);
    char const *expected = "{"
                           "\"struct\":\"treasure\","
                           "\"rev\":0,"
                           "\"type\":\"A\","
                           "\"coins\":{"
                               "\"struct\":\"coins\","
                               "\"rev\":0,"
                               "\"pp\":100,"
                               "\"gp\":1000,"
                               "\"ep\":1000,"
                               "\"sp\":1000,"
                               "\"cp\":1000"
                           "},"
                           "\"gems\":["
                               "{\"struct\":\"gem\",\"rev\":0,\"size\":\"very small\",\"type\":\"ornamental\",\"kind\":\"azurite\",\"colors\":\"mottled deep blue\",\"value_percent_modifier\":0,\"value_rank_modifier\":7},"
                               "{\"struct\":\"gem\",\"rev\":0,\"size\":\"very small\",\"type\":\"ornamental\",\"kind\":\"azurite\",\"colors\":\"mottled deep blue\",\"value_percent_modifier\":0,\"value_rank_modifier\":7},"
                               "{\"struct\":\"gem\",\"rev\":0,\"size\":\"very small\",\"type\":\"ornamental\",\"kind\":\"azurite\",\"colors\":\"mottled deep blue\",\"value_percent_modifier\":0,\"value_rank_modifier\":7},"
                               "{\"struct\":\"gem\",\"rev\":0,\"size\":\"very small\",\"type\":\"ornamental\",\"kind\":\"azurite\",\"colors\":\"mottled deep blue\",\"value_percent_modifier\":0,\"value_rank_modifier\":7}"
                           "],"
                           "\"jewelry\":["
                               "{\"struct\":\"jewelry\",\"rev\":0,\"has_gems\":false,\"form\":\"anklet\",\"material\":\"ivory\",\"workmanship_bonus\":12,\"exceptional_stone_bonus\":0,\"value_in_cp\":400000},"
                               "{\"struct\":\"jewelry\",\"rev\":0,\"has_gems\":false,\"form\":\"anklet\",\"material\":\"ivory\",\"workmanship_bonus\":12,\"exceptional_stone_bonus\":0,\"value_in_cp\":400000},"
                               "{\"struct\":\"jewelry\",\"rev\":0,\"has_gems\":false,\"form\":\"anklet\",\"material\":\"ivory\",\"workmanship_bonus\":12,\"exceptional_stone_bonus\":0,\"value_in_cp\":400000}"
                           "],"
                           "\"maps\":["
                               "{\"struct\":\"treasure_map\",\"rev\":0,\"is_false\":true,\"treasure\":{\"struct\":\"treasure\",\"rev\":0,\"type\":null,\"coins\":{\"struct\":\"coins\",\"rev\":0,\"pp\":0,\"gp\":0,\"ep\":0,\"sp\":0,\"cp\":0},\"gems\":[],\"jewelry\":[],\"maps\":[],\"magic_items\":[]},\"true_description\":\"false map to treasure of (no treasure) in nearby labyrinth to the north\"},"
                               "{\"struct\":\"treasure_map\",\"rev\":0,\"is_false\":true,\"treasure\":{\"struct\":\"treasure\",\"rev\":0,\"type\":null,\"coins\":{\"struct\":\"coins\",\"rev\":0,\"pp\":0,\"gp\":0,\"ep\":0,\"sp\":0,\"cp\":0},\"gems\":[],\"jewelry\":[],\"maps\":[],\"magic_items\":[]},\"true_description\":\"false map to treasure of (no treasure) in nearby labyrinth to the north\"},"
                               "{\"struct\":\"treasure_map\",\"rev\":0,\"is_false\":true,\"treasure\":{\"struct\":\"treasure\",\"rev\":0,\"type\":null,\"coins\":{\"struct\":\"coins\",\"rev\":0,\"pp\":0,\"gp\":0,\"ep\":0,\"sp\":0,\"cp\":0},\"gems\":[],\"jewelry\":[],\"maps\":[],\"magic_items\":[]},\"true_description\":\"false map to treasure of (no treasure) in nearby labyrinth to the north\"}"
                           "],"
                           "\"magic_items\":[]"
                           "}";
    assert(str_eq(expected, json_string));

    free(json_string);
    cJSON_Delete(json_object);

    treasure_finalize(&treasure);
    rnd_free(rnd);
}
static void
treasure_initialize_test(void)
{
    struct treasure treasure;
    treasure_initialize(&treasure);

    assert(NULL == treasure.type);
    assert(coins_is_zero(treasure.coins));
    assert(NULL == treasure.gems);
    assert(0 == treasure.gems_count);
    assert(NULL == treasure.jewelry);
    assert(0 == treasure.jewelry_count);
    assert(NULL == treasure.maps);
    assert(0 == treasure.maps_count);
    assert(NULL == treasure.magic_items);
    assert(0 == treasure.magic_items_count);

    treasure_finalize(&treasure);
}
static void
treasure_initialize_from_json_object_for_empty_array_test(void)
{
    char const *json_string = "[]";
    struct cJSON *json_object = cJSON_Parse(json_string);
    struct treasure treasure;
    treasure_initialize_from_json_object(&treasure, json_object);

    assert(NULL == treasure.type);
    assert(coins_is_zero(treasure.coins));
    assert(NULL == treasure.gems);
    assert(0 == treasure.gems_count);
    assert(NULL == treasure.jewelry);
    assert(0 == treasure.jewelry_count);
    assert(NULL == treasure.maps);
    assert(0 == treasure.maps_count);
    assert(NULL == treasure.magic_items);
    assert(0 == treasure.magic_items_count);

    treasure_finalize(&treasure);
}
static void
treasure_generate_magic_items_test(void)
{
    struct rnd *rnd = rnd_alloc_fake_min();
    struct treasure treasure;
    treasure_initialize(&treasure);

    treasure_generate_magic_items(&treasure, rnd, 1, ANY_MAGIC_ITEM);

    assert(NULL == treasure.type);
    assert(coins_is_zero(treasure.coins));
    assert(NULL == treasure.gems);
    assert(0 == treasure.gems_count);
    assert(NULL == treasure.jewelry);
    assert(0 == treasure.jewelry_count);
    assert(NULL == treasure.maps);
    assert(0 == treasure.maps_count);

    assert(NULL != treasure.magic_items);
    assert(1 == treasure.magic_items_count);

    assert(magic_item_type_potion == treasure.magic_items[0].type);
    assert(str_eq("animal control potion", treasure.magic_items[0].true_description));

    rnd_free(rnd);
    rnd = rnd_alloc_fake_median();

    treasure_generate_magic_items(&treasure, rnd, 1, ANY_MAGIC_ITEM);

    assert(NULL != treasure.magic_items);
    assert(2 == treasure.magic_items_count);

    assert(magic_item_type_potion == treasure.magic_items[0].type);
    assert(str_eq("animal control potion", treasure.magic_items[0].true_description));
    assert(magic_item_type_misc == treasure.magic_items[1].type);
    assert(str_eq("cloak of protection +2", treasure.magic_items[1].true_description));

    treasure_finalize(&treasure);
    rnd_free(rnd);
}
static void
treasure_type_generate_for_A_with_fake_fixed_test(void)
{
    struct rnd *rnd = rnd_alloc_fake_fixed(25);
    struct treasure treasure;
    treasure_initialize(&treasure);
    struct treasure_type *treasure_type = treasure_type_by_letter('A');

    treasure_type_generate(treasure_type, rnd, &treasure);

    assert(0 == treasure.coins.cp);
    assert(2000 == treasure.coins.sp);
    assert(2000 == treasure.coins.ep);
    assert(6000 == treasure.coins.gp);
    assert(0 == treasure.coins.pp);
    assert(24 == treasure.gems_count);
    assert(18 == treasure.jewelry_count);
    assert(3 == treasure.magic_items_count);
    assert(0 == treasure.maps_count);

    treasure_finalize(&treasure);
    rnd_free(rnd);
}
void
treasure_map_finalize(struct treasure_map *treasure_map)
{
    treasure_finalize(&treasure_map->treasure);
    free_or_die(treasure_map->true_description);
}
static void
treasure_initialize_from_json_object_with_magic_items_test(void)
{
    char const *json_string = "{\n"
                              "  \"struct\": \"treasure\",\n"
                              "  \"rev\": 0,\n"
                              "  \"type\": null,\n"
                              "  \"coins\": {\n"
                              "    \"struct\": \"coins\",\n"
                              "    \"rev\": 0,\n"
                              "    \"pp\": 0,\n"
                              "    \"gp\": 0,\n"
                              "    \"ep\": 0,\n"
                              "    \"sp\": 0,\n"
                              "    \"cp\": 0\n"
                              "  },\n"
                              "  \"gems\": [],\n"
                              "  \"jewelry\": [],\n"
                              "  \"maps\": [],\n"
                              "  \"magic_items\": [\n"
                              "    {\n"
                              "      \"struct\": \"magic_item\",\n"
                              "      \"rev\": 0,\n"
                              "      \"experience_points\": 2000,\n"
                              "      \"true_description\": \"cloak of protection +2\",\n"
                              "      \"true_details\": [],\n"
                              "      \"true_value_in_cp\": 4000000,\n"
                              "      \"type\": \"miscellaneous\"\n"
                              "    },\n"
                              "    {\n"
                              "      \"struct\": \"magic_item\",\n"
                              "      \"rev\": 0,\n"
                              "      \"experience_points\": 5000,\n"
                              "      \"true_description\": \"broadsword of life stealing (unusual)\",\n"
                              "      \"true_details\": [\n"
                              "        \"intelligence 12 (semi-empathy)\",\n"
                              "        \"neutral good alignment\",\n"
                              "        \"detect invisible objects in a 1\\\" radius\",\n"
                              "        \"personality strength 17 (ego 5)\"\n"
                              "      ],\n"
                              "      \"true_value_in_cp\": 5000000,\n"
                              "      \"type\": \"sword\"\n"
                              "    }\n"
                              "  ]\n"
                              "}";
    struct cJSON *json_object = cJSON_Parse(json_string);
    struct treasure treasure;
    treasure_initialize_from_json_object(&treasure, json_object);

    assert(NULL == treasure.type);
    assert(coins_is_zero(treasure.coins));
    assert(NULL == treasure.gems);
    assert(0 == treasure.gems_count);
    assert(NULL == treasure.jewelry);
    assert(0 == treasure.jewelry_count);
    assert(NULL == treasure.maps);
    assert(0 == treasure.maps_count);
    assert(NULL != treasure.magic_items);
    assert(2 == treasure.magic_items_count);

    assert(2000 == treasure.magic_items[0].experience_points);
    assert(str_eq("cloak of protection +2", treasure.magic_items[0].true_description));
    assert(NULL == treasure.magic_items[0].true_details);
    assert(4000000 == treasure.magic_items[0].true_value_in_cp);
    assert(magic_item_type_misc == treasure.magic_items[0].type);

    assert(5000 == treasure.magic_items[1].experience_points);
    assert(str_eq("broadsword of life stealing (unusual)", treasure.magic_items[1].true_description));
    assert(treasure.magic_items[1].true_details);
    assert(str_eq("intelligence 12 (semi-empathy)", treasure.magic_items[1].true_details[0]));
    assert(str_eq("neutral good alignment", treasure.magic_items[1].true_details[1]));
    assert(str_eq("detect invisible objects in a 1\" radius", treasure.magic_items[1].true_details[2]));
    assert(str_eq("personality strength 17 (ego 5)", treasure.magic_items[1].true_details[3]));
    assert(NULL == treasure.magic_items[1].true_details[4]);
    assert(5000000 == treasure.magic_items[1].true_value_in_cp);
    assert(magic_item_type_sword == treasure.magic_items[1].type);

    treasure_finalize(&treasure);
}
static void
treasure_initialize_from_json_object_with_maps_test(void)
{
    char const *json_string = "{\n"
                              "  \"struct\": \"treasure\",\n"
                              "  \"rev\": 0,\n"
                              "  \"type\": null,\n"
                              "  \"coins\": {\n"
                              "    \"struct\": \"coins\",\n"
                              "    \"rev\": 0,\n"
                              "    \"pp\": 0,\n"
                              "    \"gp\": 0,\n"
                              "    \"ep\": 0,\n"
                              "    \"sp\": 0,\n"
                              "    \"cp\": 0\n"
                              "  },\n"
                              "  \"gems\": [],\n"
                              "  \"jewelry\": [],\n"
                              "  \"maps\": [\n"
                              "    {\n"
                              "      \"struct\": \"treasure_map\",\n"
                              "      \"rev\": 0,\n"
                              "      \"is_false\": false,\n"
                              "      \"treasure\": {\n"
                              "        \"struct\": \"treasure\",\n"
                              "        \"rev\": 0,\n"
                              "        \"type\": null,\n"
                              "        \"coins\": {\n"
                              "          \"struct\": \"coins\",\n"
                              "          \"rev\": 0,\n"
                              "          \"pp\": 1500,\n"
                              "          \"gp\": 0,\n"
                              "          \"ep\": 0,\n"
                              "          \"sp\": 0,\n"
                              "          \"cp\": 0\n"
                              "        },\n"
                              "        \"gems\": [],\n"
                              "        \"jewelry\": [],\n"
                              "        \"maps\": [],\n"
                              "        \"magic_items\": []\n"
                              "      },\n"
                              "      \"true_description\": \"map to monetary treasure of 1500 platinum 7 miles to the south, guarded in a lair\""
                              "    },\n"
                              "    {\n"
                              "      \"struct\": \"treasure_map\",\n"
                              "      \"rev\": 0,\n"
                              "      \"is_false\": false,\n"
                              "      \"treasure\": {\n"
                              "        \"struct\": \"treasure\",\n"
                              "        \"rev\": 0,\n"
                              "        \"type\": null,\n"
                              "        \"coins\": {\n"
                              "          \"struct\": \"coins\",\n"
                              "          \"rev\": 0,\n"
                              "          \"pp\": 0,\n"
                              "          \"gp\": 0,\n"
                              "          \"ep\": 0,\n"
                              "          \"sp\": 0,\n"
                              "          \"cp\": 0\n"
                              "        },\n"
                              "        \"gems\": [],\n"
                              "        \"jewelry\": [],\n"
                              "        \"maps\": [],\n"
                              "        \"magic_items\": []\n"
                              "      },\n"
                              "      \"true_description\": \"false map to treasure of (no treasure) in nearby labyrinth to the north\""
                              "    }\n"
                              "  ],\n"
                              "  \"magic_items\": []\n"
                              "}";
    struct cJSON *json_object = cJSON_Parse(json_string);
    struct treasure treasure;
    treasure_initialize_from_json_object(&treasure, json_object);

    assert(NULL == treasure.type);
    assert(coins_is_zero(treasure.coins));
    assert(NULL == treasure.gems);
    assert(0 == treasure.gems_count);
    assert(NULL == treasure.jewelry);
    assert(0 == treasure.jewelry_count);

    assert(NULL != treasure.maps);
    assert(2 == treasure.maps_count);

    assert( ! treasure.maps[0].is_false);
    assert(1500 == treasure.maps[0].treasure.coins.pp);
    assert(0 == treasure.maps[0].treasure.coins.gp);
    assert(0 == treasure.maps[0].treasure.coins.ep);
    assert(0 == treasure.maps[0].treasure.coins.sp);
    assert(0 == treasure.maps[0].treasure.coins.cp);
    assert(0 == treasure.maps[0].treasure.gems_count);
    assert(0 == treasure.maps[0].treasure.jewelry_count);
    assert(0 == treasure.maps[0].treasure.maps_count);
    assert(0 == treasure.maps[0].treasure.magic_items_count);
    assert(str_eq("false map to treasure of (no treasure) in nearby labyrinth to the north",
                  treasure.maps[0].true_description));

    assert(treasure.maps[1].is_false);
    assert(coins_is_zero(treasure.maps[1].treasure.coins));
    assert(0 == treasure.maps[1].treasure.gems_count);
    assert(0 == treasure.maps[1].treasure.jewelry_count);
    assert(0 == treasure.maps[1].treasure.maps_count);
    assert(0 == treasure.maps[1].treasure.magic_items_count);
    assert(str_eq("map to monetary treasure of 1500 platinum 7 miles to the south, guarded in a lair",
                  treasure.maps[1].true_description));

    assert(NULL == treasure.magic_items);
    assert(0 == treasure.magic_items_count);

    treasure_finalize(&treasure);
}
static void
treasure_initialize_from_json_object_with_jewelry_test(void)
{
    char const *json_string = "{\n"
                              "  \"struct\": \"treasure\",\n"
                              "  \"rev\": 0,\n"
                              "  \"type\": null,\n"
                              "  \"coins\": {\n"
                              "    \"struct\": \"coins\",\n"
                              "    \"rev\": 0,\n"
                              "    \"pp\": 0,\n"
                              "    \"gp\": 0,\n"
                              "    \"ep\": 0,\n"
                              "    \"sp\": 0,\n"
                              "    \"cp\": 0\n"
                              "  },\n"
                              "  \"gems\": [],\n"
                              "  \"jewelry\": [\n"
                              "    {\n"
                              "      \"struct\": \"jewelry\",\n"
                              "      \"rev\": 0,\n"
                              "      \"has_gems\": true,\n"
                              "      \"form\": \"goblet\",\n"
                              "      \"material\": \"silver with gems\",\n"
                              "      \"workmanship_bonus\": 0,\n"
                              "      \"exceptional_stone_bonus\": 0,\n"
                              "      \"value_in_cp\": 800000\n"
                              "    },\n"
                              "    {\n"
                              "      \"struct\": \"jewelry\",\n"
                              "      \"rev\": 0,\n"
                              "      \"has_gems\": true,\n"
                              "      \"form\": \"necklace\",\n"
                              "      \"material\": \"gold with gems\",\n"
                              "      \"workmanship_bonus\": 0,\n"
                              "      \"exceptional_stone_bonus\": 128,\n"
                              "      \"value_in_cp\": 128400000\n"
                              "    }\n"
                              "  ],\n"
                              "  \"maps\": [],\n"
                              "  \"magic_items\": []\n"
                              "}";
    struct cJSON *json_object = cJSON_Parse(json_string);
    struct treasure treasure;
    treasure_initialize_from_json_object(&treasure, json_object);

    assert(NULL == treasure.type);
    assert(coins_is_zero(treasure.coins));
    assert(NULL == treasure.gems);
    assert(0 == treasure.gems_count);

    assert(NULL != treasure.jewelry);
    assert(2 == treasure.jewelry_count);

    assert(true == treasure.jewelry[0].has_gems);
    assert(jewelry_form_goblet == treasure.jewelry[0].form);
    assert(jewelry_material_silver_with_gems == treasure.jewelry[0].material);
    assert(0 == treasure.jewelry[0].workmanship_bonus);
    assert(0 == treasure.jewelry[0].exceptional_stone_bonus);
    assert(gp_to_cp(4000) == treasure.jewelry[0].value_in_cp);
    assert(str_eq("silver goblet with gems (4000 gp)", treasure.jewelry[0].true_description));

    assert(true == treasure.jewelry[1].has_gems);
    assert(jewelry_form_necklace == treasure.jewelry[1].form);
    assert(jewelry_material_gold_with_gems == treasure.jewelry[1].material);
    assert(0 == treasure.jewelry[1].workmanship_bonus);
    assert(128 == treasure.jewelry[1].exceptional_stone_bonus);
    assert(gp_to_cp(642000) == treasure.jewelry[1].value_in_cp);
    assert(str_eq("gold necklace with gems (exceptional stone +128: 642000 gp)", treasure.jewelry[1].true_description));

    assert(NULL == treasure.maps);
    assert(0 == treasure.maps_count);
    assert(NULL == treasure.magic_items);
    assert(0 == treasure.magic_items_count);

    treasure_finalize(&treasure);
}
static void
treasure_initialize_from_json_object_with_gems_test(void)
{
    char const *json_string = "{\n"
                              "  \"struct\": \"treasure\",\n"
                              "  \"rev\": 0,\n"
                              "  \"type\": null,\n"
                              "  \"coins\": {\n"
                              "    \"struct\": \"coins\",\n"
                              "    \"rev\": 0,\n"
                              "    \"pp\": 0,\n"
                              "    \"gp\": 0,\n"
                              "    \"ep\": 0,\n"
                              "    \"sp\": 0,\n"
                              "    \"cp\": 0\n"
                              "  },\n"
                              "  \"gems\": [\n"
                              "    {\n"
                              "      \"struct\": \"gem\",\n"
                              "      \"rev\": 0,\n"
                              "      \"size\": \"large\",\n"
                              "      \"type\": \"precious\",\n"
                              "      \"kind\": \"moonstone\",\n"
                              "      \"colors\": \"white with pale blue glow\",\n"
                              "      \"value_percent_modifier\": 90,\n"
                              "      \"value_rank_modifier\": 2\n"
                              "    },\n"
                              "    {\n"
                              "      \"struct\": \"gem\",\n"
                              "      \"rev\": 0,\n"
                              "      \"size\": \"very small\",\n"
                              "      \"type\": \"ornamental\",\n"
                              "      \"kind\": \"azurite\",\n"
                              "      \"colors\": \"mottled deep blue\",\n"
                              "      \"value_percent_modifier\": 0,\n"
                              "      \"value_rank_modifier\": 7\n"
                              "    }\n"
                              "  ],\n"
                              "  \"jewelry\": [],\n"
                              "  \"maps\": [],\n"
                              "  \"magic_items\": []\n"
                              "}";
    struct cJSON *json_object = cJSON_Parse(json_string);
    struct treasure treasure;
    treasure_initialize_from_json_object(&treasure, json_object);

    assert(NULL == treasure.type);
    assert(coins_is_zero(treasure.coins));

    assert(NULL != treasure.gems);
    assert(2 == treasure.gems_count);

    assert(gem_size_large == treasure.gems[0].size);
    assert(gem_type_precious_stone == treasure.gems[0].type);
    assert(gem_kind_moonstone == treasure.gems[0].kind);
    assert(str_eq("white with pale blue glow", treasure.gems[0].colors));
    assert(90 == treasure.gems[0].value_percent_modifier);
    assert(2 == treasure.gems[0].value_rank_modifier);
    assert(str_eq("large moonstone (precious, rank +2, -10%: 9000 gp)", treasure.gems[0].true_description));
    assert(str_eq("large translucent white with pale blue glow stone", treasure.gems[0].visible_description));

    assert(gem_size_very_small == treasure.gems[1].size);
    assert(gem_type_ornamental_stone == treasure.gems[1].type);
    assert(gem_kind_azurite == treasure.gems[1].kind);
    assert(str_eq("mottled deep blue", treasure.gems[1].colors));
    assert(0 == treasure.gems[1].value_percent_modifier);
    assert(7 == treasure.gems[1].value_rank_modifier);
    assert(str_eq("very small azurite (ornamental, rank +7: 5000 gp)", treasure.gems[1].true_description));
    assert(str_eq("very small opaque mottled deep blue stone", treasure.gems[1].visible_description));

    assert(NULL == treasure.jewelry);
    assert(0 == treasure.jewelry_count);
    assert(NULL == treasure.maps);
    assert(0 == treasure.maps_count);
    assert(NULL == treasure.magic_items);
    assert(0 == treasure.magic_items_count);

    treasure_finalize(&treasure);
}
static void
treasure_create_json_object_test(void)
{
    struct rnd *rnd = rnd_alloc_fake_median();
    struct treasure treasure;
    treasure_initialize(&treasure);
    treasure_generate_magic_items(&treasure, rnd, 3, ANY_MAGIC_ITEM);
    struct cJSON *json_object = treasure_create_json_object(&treasure);

    assert(cJSON_IsObject(json_object));

    char *json_string = cJSON_PrintUnformatted(json_object);
    char const *expected = "{"
                           "\"struct\":\"treasure\","
                           "\"rev\":0,"
                           "\"type\":null,"
                           "\"coins\":{"
                               "\"struct\":\"coins\","
                               "\"rev\":0,"
                               "\"pp\":0,"
                               "\"gp\":0,"
                               "\"ep\":0,"
                               "\"sp\":0,"
                               "\"cp\":0"
                           "},"
                           "\"gems\":[],"
                           "\"jewelry\":[],"
                           "\"maps\":[],"
                           "\"magic_items\":["
                               "{"
                                   "\"struct\":\"magic_item\","
                                   "\"rev\":0,"
                                   "\"experience_points\":2000,"
                                   "\"true_description\":\"cloak of protection +2\","
                                   "\"true_details\":[],"
                                   "\"true_value_in_cp\":4000000,"
                                   "\"type\":\"miscellaneous\""
                               "},"
                               "{"
                                   "\"struct\":\"magic_item\","
                                   "\"rev\":0,"
                                   "\"experience_points\":2000,"
                                   "\"true_description\":\"cloak of protection +2\","
                                   "\"true_details\":[],"
                                   "\"true_value_in_cp\":4000000,"
                                   "\"type\":\"miscellaneous\""
                               "},"
                               "{"
                                   "\"struct\":\"magic_item\","
                                   "\"rev\":0,"
                                   "\"experience_points\":2000,"
                                   "\"true_description\":\"cloak of protection +2\","
                                   "\"true_details\":[],"
                                   "\"true_value_in_cp\":4000000,"
                                   "\"type\":\"miscellaneous\""
                               "}"
                           "]"
                           "}";
    assert(str_eq(expected, json_string));

    free(json_string);
    cJSON_Delete(json_object);

    treasure_finalize(&treasure);
    rnd_free(rnd);
}