【问题标题】:How to get the next object in a list of objects?如何获取对象列表中的下一个对象?
【发布时间】:2015-06-17 12:25:09
【问题描述】:

我在我的应用程序中使用地图将每个位置存储在虚构的游戏地图中。当前的实现允许我获取起始节点,即Tiberius

但我不确定如何才能到达地图上相对于玩家当前位置的下一个location。例如,当我创建地图时,我默认位于“Tiberius”,所以我想知道如何创建一个迭代到下一个位置的方法,即“Desert”,而随后对move() 的调用将将玩家带到“耶路撒冷”。

图表如下所示,每个位置都有一个子位置。

通过快速搜索,我发现可以通过 ID 中的字段迭代列表,例如 get element by ID ,但在此实现中,我需要获取相对于当前位置的下一个位置。

有谁知道这个方法是怎么实现的?

这就是我目前在主课中设置地图的方式:

public class Main implements Commands{


    public static void main(String[] args)  {

        //Boolean to signify game state 
        boolean gameNotOver = true;

        //main game loop
        while (gameNotOver) {

            GameMap playerMap = new GameMap();
            playerMap.getStartNode();

            Main mainObj = new Main();

            //Take in user commands here
            //and parse commands
            String input = Input.getInput();
            if (input.equals("description")) {
                System.out.println("Description: " );
            } else if (input.equals("move")) {
                System.out.println("Moving to the next location in map.. " );
                mainObj.move();     
        }

        //Game over 
        System.out.println("Game Over!");
        System.exit(0);
    }

    //Game player commands inherited from GameCharacterInterface:

    public String move() {
         //want to create a method here that will call the next 
         //location based on the current location that the player is in.
        // TODO Auto-generated method stub
        return null;
    }

}

这是用于对位置进行建模的 Location 类:

public class Location {

    private Location[] location;

    private int id;

    private String description;

    private String weight;

    private String name;

    private Item item;

    private Exit[] exit;

    private boolean visited = false;
    private boolean goalLocation;
    private int approximateDistanceFromGoal = 0;
    private Location parent;

    private Map<Location, Integer> children = new HashMap<Location, Integer>();

    public Location() {
        super();
    }

    public Location(String name){
        this.name = name;
    }

    public Location(String name, int goalDistance){
        this.name = name;
        this.approximateDistanceFromGoal = goalDistance;
    }



    public Location[] children(){
        return (Location[]) children.keySet().toArray(new Location[children.size()]);
    }

    public int getDistance(Location loc){
        if(children.get(loc) == null) System.out.println(this.name + ": " + loc.getName());
        return children.get(loc);
    }


    public int getChildLocationCount(){
        return children.size();
    }

    public void addChildLocation(Location child, int distance){
        children.put(child, distance);
    }

    public boolean isLeaf(){
        if (children.size() > 0){
            return false;
        }else{
            return true;
        }
    }


    public void removeChild(Location child){
        children.remove(child);
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getDescription ()
    {
        return description;
    }

    public void setDescription (String description)
    {
        this.description = description;
    }


    public String getWeight() {
        return weight;
    }

    public void setWeight(String weight) {
        this.weight = weight;
    }

    public String getName ()
    {
        return name;
    }

    public void setName (String name)
    {
        this.name = name;
    }

    public Exit[] getExit() {
        return exit;
    }

    public void setExit(Exit[] exit) {
        this.exit = exit;
    }


    public Location[] getLocation() {
        return location;
    }

    public void setLocation(Location[] location) {
        this.location = location;
    }

    public boolean isVisited() {
        return visited;
    }

    public void setVisited(boolean visited) {
        this.visited = visited;
    }

    public boolean isGoalLocation() {
        return goalLocation;
    }

    public void setGoalLocation(boolean goalLocation) {
        this.goalLocation = goalLocation;
    }

    public int getApproximateDistanceFromGoal() {
        return approximateDistanceFromGoal;
    }

    public void setApproximateDistanceFromGoal(int approximateDistanceFromGoal) {
        this.approximateDistanceFromGoal = approximateDistanceFromGoal;
    }

    public Location getParent() {
        return parent;
    }

    public void setParent(Location parent) {
        this.parent = parent;
    }

    public Item getItem() {
        return item;
    }

    public void setItem(Item item) {
        this.item = item;
    }


    @Override
    public String toString() {
        return "Location [location=" + Arrays.toString(location) + ", id=" + id
                + ", description=" + description + ", name=" + name + ", item="
                + item + ", exit=" + Arrays.toString(exit) + "]";
    }


}

这是显示每个位置的 GameMap 和 getStartNode():

public class GameMap {


private Location tiberius;

    public GameMap() {

        //Creating Locations
        tiberius = new Location("Tiberius", 200);
        tiberius.setDescription("You are in the city of Tiberius. There is a sword on the ground in front of you. You see a long street with high buildings and a castle.You see an exit to the south.");

        Location desert = new Location("Desert", 170);
        desert.setDescription("You are in hot dreary desert, surrounded by sand dunes and nothingness, you see an exit to the south.");
        Location jerusalem = new Location("Jerusalem", 270);
        jerusalem.setDescription("You are at battlefield of Jerusalem. You are in awe of your surroundings, you see an exit to the west.");
        Location hattin = new Location("Hattin", 120);
        hattin.setDescription("You are at battlefield of Hattin. You see the ruination of the battle and fallen comrades...You see an exit to the north.");
        Location damascus = new Location("Damascus", 130);
        damascus.setDescription("You are in Damascus. You see the some shady characters...you see an exit to the west.");
        Location tripoli = new Location("Tripoli", 80); 
        tripoli.setDescription("You are in Tripoli. You see the some more shady characters...you see an exit to the north.");
        Location antioch = new Location("Antioch", 60);
        antioch.setDescription("You are in the city of Antioch. You see a long street with high buildings and a castle.. You see the some more shady characters...you see an exit to the north.");
        Location sis = new Location("Sis", 100);
        sis.setDescription("You are in the city of Sis....exit ahead in the west.");
        Location tarsus = new Location("Tarsus", 20);
        tarsus.setDescription("You are in the city of Tarsus. ...you see an exit to the south.");
        Location cyprus = new Location("Cyprus", 0);
        cyprus.setDescription("You have reached the Byzantine Empire, your quest has finished!");
        cyprus.setGoalLocation(true);

        //Adding child locations
        tiberius.addChildLocation(desert, 105);
        desert.addChildLocation(jerusalem, 105);
        jerusalem.addChildLocation(hattin, 323);
        hattin.addChildLocation(damascus, 121);
        damascus.addChildLocation(tripoli, 121);
        tripoli.addChildLocation(antioch, 220);
        antioch.addChildLocation(sis, 126);
        sis.addChildLocation(tarsus, 121);  
        tarsus.addChildLocation(cyprus, 126);



    }



    public Location getStartNode(){
        System.out.println(tiberius.toString());
        return tiberius;

    }

}

【问题讨论】:

  • 似乎每个位置都有多个“下一个”位置。那么你怎么知道接下来要去哪个地点呢?
  • "next" 是什么意思?每个Location 都有一张儿童地图,但您只能将一个儿童放入每个Location 的地图中。 children 地图是否有可能拥有多个孩子?如果没有,我会摆脱地图,将孩子存储为Location,并添加一个返回孩子的方法。
  • 在这个实现中,每个位置只有一个孩子,我需要将其保存为地图,因为我在代码中的其他位置对其执行深度优先搜索。
  • 如果您想要一张可能有多个孩子的孩子地图,但顺序很重要(即添加孩子的顺序),请查看LinkedHashMap。跨度>
  • @satnam 在这个应用程序中,每个位置只有一个下一个位置,所以我想知道如何创建一个迭代到当前位置子节点的方法。然后当它在下一个位置时,迭代到该位置的子节点,以此类推,直到到达目标位置。

标签: java arrays dictionary collections iteration


【解决方案1】:

我想你是说你想要一个名为 next() 的 Location 类上的方法,它将返回下一个位置。那么为什么不这样做呢?

public Location next() {
    Location nextLocation = null;
    for (Location child : children.keySet()) {
        nextLocation = child;
        break;
    }
    return nextLocation;
}

这是基于您的断言,当然,children Map 中只会有一个条目。如果将来这种情况发生变化,您可以添加一个测试(此时设计未知),以证明孩子是您想要的:

public Location next() {
    Location nextLocation = null;
    for (Location child : children.keySet()) {
        if (isCorrectChild(child)) {
            nextLocation = child;
            break;
        }
    }
    return nextLocation;
}

【讨论】:

  • 尝试了第一种方法,抛出这个错误:“can only iterate over an array or an instance of java.lang.iterable”
  • 那个让我大吃一惊!显示你没有先尝试的结果......现在应该可以工作了。 :-)
  • 好的,我现在就试试,不是 100% 知道应该如何调用它?你看我是如何在上面的主类中创建图表的,我是否只是创建一个 Location 对象并在其上调用 next 方法?如果我这样称呼它,则不会打印出下一个位置,GameMap playerMap = new GameMap(); playerMap.getStartNode(); Location locObj = new Location(); locObj.next();
  • 您可能想要执行 Location startNode = playerMap.getStartNode() 然后执行 Location nextLocation = startNode.next() 等等。除非您明确告诉它,否则不会打印任何内容,例如 System.out.println(nextLocation.getName())。
  • 所以我终于让它工作了,但它只迭代到下一个位置,即沙漠,当我调用 move 时,下一次它仍然加载沙漠作为下一个,尽管下一个应该是耶路撒冷,任何想法为什么会这样?这是目前的主要课程:hastebin.com/ayadixudev.avrasm 我认为 next() 在从上一个位置移动后没有将下一个位置设置为当前位置。
【解决方案2】:

Brian,从 Location 中删除这个字段:

Map<Location,Integer> children;

用两个字段替换它。

Location next;
int goalDistance;

然后,在您的游戏控制器中,保留对角色当前位置的引用。

例如:

位置 currentLoc = tiberius;

然后,每次调用 move() 时,只需说

currentLoc = currentLoc.next;

【讨论】:

  • 当我尝试这个时,Location currentLoc = tiberius; 我得到 tiberius 无法解析为变量,我猜上面的不正确?
猜你喜欢
  • 2021-10-25
  • 2019-08-24
  • 2019-02-06
  • 2021-11-09
  • 2022-07-06
  • 1970-01-01
  • 1970-01-01
  • 2021-01-13
  • 1970-01-01
相关资源
最近更新 更多