Thursday, May 15, 2014

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;
    }

}



No comments: