Skip to main content

Hoardomatic Code: Hoard Class

I've decided to start making available the code I've written for my treasure generator in a leisurely fashion. I won't be posting the XML files containing the data (that'd basically be posting the contents of DF8), but I will be putting up some sample files to demonstrate how the raw data is shaped.

This code is very rough, having been composed...let's say, organically, rather than according to a well thought-out plan and good programming principles. It contains much which is incomplete or inefficient. However, it ultimately gives me lists of useful treasures, which is more or less as far as I'm inclined to take things without it turning into something tediously like my day job. However, it may help those who want to pursue something similar.

Briefly, then, I've assembled a mess of Java code to represent bunches of items. The intended entry point is a Hoard object. A hoard contains a bunch of items, which in turn has a number of simple properties (base weight, base cost, name, etc.) and more complex properties representing lists of enchantments, lists of decorative embellishments, and containers, which are themselves items. Going from the top down, I'm starting with the Hoard class.

Hoard


ArrayList<Item> items: A list of items
Double remaining_val: Portion of the hoard's value not made up in items.

The hoard is a pretty simple construct containing a batch of items. The main usage I've implemented for it is a constructor which takes a Double value indicating the desired value of the hoard. Given that, it sets an approximate threshold for the maximum value of the items and randomly adds items to the list until it passes that value. I left some wiggle room in the value of the items so that the hoard-generator wouldn't get itself into an excessively long loop trying to find an item of just the right value to round out the desired total value of the hoard. There's a secondary constructor which takes a target value, a list of required attributes and a list of forbidden attributes. It acts much like the first constructor, but it tests prospective items by making sure they have an attribute on the required list and don't have any attributes on the forbidden list. This is the way to get, say, "the contents of the armory" (by requiring weapons and armor) or "the contents of the giant adventurer-eater's stomach" (by forbidding organic items).

Beyond that, the Hoard class just has a few functions bundling up the total value (necessary to check running progress) and concatenating descriptions of its component items. Here's the code:


package hoardomatic;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;

public class Hoard {

    private ArrayList<Item> items = new ArrayList<Item>(); // item attributes
    private Double remaining_val = 0.0;
   
    public Hoard() {
        // TODO Auto-generated constructor stub
    }
   
    public void setRemaining(Double inval){
        remaining_val = inval;
    }
   
    public Hoard(Double max_value){
       
        Double ceiling_val = max_value * .9;
        while(getHoardValue() < ceiling_val){
            Item test_item = new Item();
            if ((test_item.getFinalCost() + getHoardValue()) < max_value ){
                items.add(test_item);
            }
        }
        remaining_val = max_value - getHoardValue();
    }
   
   
    public void addItem (Item the_item){
        items.add(the_item);
    }
   
    public Hoard(Double max_value, ArrayList<String> req_list, ArrayList<String> forb_list){
       
        Double ceiling_val = max_value * .9;
        while(getHoardValue() < ceiling_val){
            Item test_item = new Item();
            boolean do_add = false;
            if ((test_item.getFinalCost() + getHoardValue()) < max_value ){
                // required attributes
                if (req_list.size() < 1){
                    do_add = true;
                }
               
                for(int a = 0; a < req_list.size() ; a++){
                    if (test_item.isAttribute(req_list.get(a))){
                        do_add = true;
                    }
                   
                    if (req_list.get(a).contentEquals("Shiny")){
                        if (test_item.isAttribute("Jewelry") | test_item.isAttribute("Iron") | test_item.isAttribute("Steel") | test_item.getGems().size() > 0 ){
                            do_add = true;
                        }
                    }
                   
                    if (req_list.get(a).contentEquals("Enchanted")){
                        if (test_item.getEnchantments().length() > 0 ){
                            do_add = true;
                        }
                    }
                }
               
                // forbidden attributes
                for(int b = 0; b < forb_list.size() ; b++){
                    if (test_item.isAttribute(forb_list.get(b))){
                        do_add = false;
                    }
                   
                    if (forb_list.get(b).contentEquals("Shiny")){
                        if (test_item.isAttribute("Jewelry") | test_item.isAttribute("Iron") | test_item.isAttribute("Steel") | test_item.getGems().size() > 0 ){
                            do_add = false;
                        }
                    }
                   
                    if (forb_list.get(b).contentEquals("Enchanted")){
                        if (test_item.getEnchantments().length() > 0 ){
                            do_add = false;
                        }
                    }
                }
            }

            if(do_add){
                items.add(test_item);
            }
           
        }
        remaining_val = max_value - getHoardValue();
    }

   
    public String hoardReport(){
        String full_report = "";
       
        for (Item iLine : items) {
            full_report = full_report + iLine.report() + "\n" ;
        }
       
        NumberFormat fmt = NumberFormat.getCurrencyInstance();
        full_report = full_report + fmt.format(remaining_val) + " in coins.";
       
        return full_report;
       
    }
   
   
    public Double getHoardValue(){
       
        Double total_val = 0.0;
       
        if(items.size() > 0){
            for (Item iLine : items) {
                total_val = total_val + iLine.getFinalCost();
            }
        }
        return total_val;
    }

}



Comments

Popular posts from this blog

More Nattering About Writing Historical RPGs

omeone made the mistake of asking me to expand on some things I'd said about writing historical rpg material, so you all must suffer for it. I write a lot of historical rpg stuff as well as entirely fictional setting material. So why make historically themed games rather than just making stuff up? Well, because it's an effective way of achieving the purpose of writing settings and adventures in general. The purpose of settings and adventures, I would aver, is to give players things to do in a convincing context. Convincing context doesn't necessarily mean realism. Players have different levels of understanding of what's "realistic" in different situations and are more or less sensitive to how closely those situations adhere to reality. For example, I'm a history and culture guy. Put me in SF campaigns (which happens with some regularity) and the specifics of how reaction drives, orbital mechanics, and subatomic physics work entirely escape me. I don't,

Stuff I Wouldn't Do With Purchased Minis

One of the great things about the advent of 3d printing, when it comes to gaming, is that it allows me to take more risks and try stuff I wouldn't do otherwise. Take, for example, experimenting with painting techniques. Maybe I want to see what an unusual color scheme would look like or try doing an odd way of achieving an effect. Factory-made miniatures are expensive. Too expensive for me to risk it. Which, as someone who's not very good at painting minis and needs lots of practice, is one reason I've never gotten into them. I don't feel like I can afford the implied expense of getting better. Enter 3d printing. With the right files, I can print as many minis as I can like and mess around with them to my heart's content. Mess one up? That's fine. Resin isn't cheap , but it doesn't cost nearly as much as pre-made molded plastic. I can take it as a learning experience and move on. Which brings me to messing around with some Car Wars minis. I'd been m

Ferrous Metal Food Fighting Guy!

(This is something I wrote up some years back. I'm putting it here so I can find it more easily when I want to. Though it's rather silly, it's also where I came up with the idea of high-quality materials which don't provide a bonus to the craftsman's skill, but do add to the margin of success, a mechanism which later appeared in the crafting rules in GURPS Low-Tech Companion 3 .) One of the things not to be found in GURPS 4e is extensive rules for competitive cooking. If two cooks of steely resolve rise up to face one another across a cooking coliseum, the GM can only fall back on hand-waving and contests of skill. This article fills that much-needed gap. GURPS chefs can now stage furious contests wherein they construct fanciful dishes, the more elaborate the better, and prove whose cooking rules the day. To the kitchen! Procedure These rules provide guidance for attempting to cook complex dishes and comparing their quality when the cooking is done. A che