在Java中搜索合适的数据结构

时间:2013-06-28 15:27:15

标签: java

我们正在开发一款游戏,并希望开发一种功能,让我们能够以类似“炼金术”游戏的方式混合各种物品。主要思想是我们有许多元素,可以分为三组:基本,中间和最终。基本资源可以合并在一起,形成一个中间资源,中间资源可以与中间资源和基础资源合并,制作最终资源等。

因此,我们正在考虑使用2个HashMaps:一个将指示每个资源可以与哪个组合,第二个将映射每个资源的组成。有一个更好的方法吗?我们不知道的任何数据结构?

由于

5 个答案:

答案 0 :(得分:6)

只需像这样编写自己的数据结构

public class Element {
 enum Type{BASIC, INTERMEDIATE, FINAL};
 private Type type;
 private String name;
 private List<Element> combinable;
}

答案 1 :(得分:1)

你想要的是一个包含所有元素的枚举,有几种方法。这是一个例子,如果满足您的需求,请随时使用它 如果需要,您还可以为Type创建第二个枚举(如Templar建议的那样)并将其作为Element枚举中的字段添加。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public enum Element {
    //Example instances, replace with what is appropriate for your game.
    WATER, // Basic
    WOOD, // Basic
    IRON, // Basic
    STONE, // Basic
    FIRE, // Basic
    CARBON(WOOD, FIRE), //Intermediate
    FORGE(STONE, IRON), // Intermediate
    STEEL(FORGE, IRON); // Final

    private Element[] parts;

    private Element() {
        //instantiates parts to prevent NullPointerException
        this.parts = new Element[0];
    }

    private Element(Element... parts) {
        this.parts = parts;
    }

    /**
     * return all the parts of this Element.
     * @return
     */
    public List<Element> getParts() {
        return Arrays.asList(parts);
    }

    /**
     * find all elements that have this Element listed as one of their parts.
     * 
     * @param part
     * @return
     */
    public List<Element> getComposites() {
        List<Element> composites = new ArrayList<Element>();
        // Iterate through all Elements
        for (Element composite : Element.values()) {
            // Iterate through each Element's parts
            for (Element part : composite.parts) {
                // If the element has a part equal to the argument,
                // Add the element to the list of composites.
                if (part == this) {
                    composites.add(composite);
                }
            }
        }

        return composites;
    }

}

答案 2 :(得分:0)

您应该使用复合设计模式。 在你的情况下,BasicResource是一个叶类。 中间和最后是复合材料。

答案 3 :(得分:0)

我实际上将元素及其可组合性分开 - 如果每个元素必须包含它可以组合的元素列表,每当你想要添加一个新元素时,你必须返回并将它添加到你想要它的所有旧元素结合。

我将这个概念分为“元素”和“公式” -

class Element { 
     enum Type{NULL, BASIC, INTERMEDIATE, FINAL};         
     private Type type;
     private String name;
     // ....
} 

class Formula {
    private List<Element> requires = new ArrayList<Element>();
    private Element produces;

    public Formula(List<Element> requires, Element produces) {
        Collections.copy(requires, this.requires);
        this.produces = produces;
    }

    public final List<Element> requiredElements() {
        return Collections.unmodifiableList(requires);
    }

    public final boolean applyFormula(List<Element> ingredients) {
        for (Element e : requires) {
            if (!ingredients.contains(e)) {
                // ingredients doesn't contain a required element - return early.
                return false;
            }
        }
        for (Element e : requires) {
            ingredients.remove(e);
        }
        ingredients.add(produces);
        return true;
    }
}

答案 4 :(得分:0)

如果您正在创建游戏,那么在Java源代码中对此数据进行硬编码将会让您感到痛苦。每次要添加新元素,更改关系(由什么组成)等时,您都必须重新编译。

相反,我建议将所有元素信息存储在外部源中,然后从程序中读取/访问它。你可以用数据库做到这一点,但我觉得有点矫枉过正(至少目前为止)。相反,您可以使用一个很好的可读,纯文本,标准化的格式,如JSON来定义您的元素及其关系外部,然后使用库导入所有数据(我是建议GSon)以便在您的计划中轻松访问。

至于数据结构,我认为您选择的HashMaps可以正常工作。由于JSON构建在两种基本类型的数据结构上 - 列表 []映射 {} - 这就是Gson将事物转换为反正的东西。这是一个非常简单的示例,说明我如何设想元素规范:

{
  "elements" : {
    "iron" : "basic",
    "carbon" : "basic",
    "steel" : "intermediate"
  },
  "formulae" : {
    "steel" : [ "iron", "carbon" ]
  }
}

您可以使用Gson(或您选择的任何JSON库)读取它,然后从中构建您需要的任何其他数据结构。如果你能弄清楚如何让Gson直接创建你想要的数据结构(我知道这是可能的,但我不记得做配置有多难),那就更好了。例如,如果您可以将“公式”值转换为BidiMapApache Commons双向图),那么这可能非常有用(但您还需要将组件列表转换为保持与订单无关的一套,例如铁+碳与碳+铁相同。

对于更加动态的行为,您可以在程序中添加一项功能,以便在游戏仍在运行时重新加载所有元素数据! (这可能会使调试变得更容易。)

我知道这不是你要求的,但我希望你能找到有用的建议!