繁体   English   中英

使用Java中的循环回溯?

[英]Backtracking using loops in java?

这是我的代码的要旨,它的功能。 这是一个随处可见的游戏,可以选择您的路线。 例如,如果在开始时选择路径a,则可以在路径d和e之间进行选择,如果选择d,则可以移至f和g,依此类推。

我想添加回溯。 例如,如果我从头开始选择a并一直到f,那么我希望能够回到d并再次在f和g之间进行选择,或者一路回到起点并选择湾

我最初的想法是在需要回溯时使用某种方法告诉代码回到特定的代码行,但是据我所知,java中没有goto。 我有点想使用循环。 (我特别在考虑while循环。)我不知道如何构造循环以回溯。

这是我的代码:

public class PathGame {

public static void main (String[] args) {

String name = JOptionPane.showInputDialog("Hello! Welcome to my paths! What is your name, adventurer?");
JOptionPane.showMessageDialog(null, "Well then " + name + ", here's how this works...some generic instructions");

String startingChoice = JOptionPane.showInputDialog("Choose your path, a, b, or c.");

if (startingChoice.equals("a")){
String aChoice = JOptionPane.showInputDialog("Choose path d or path e");

if (aChoice.equals("d")) {
    String dExamineChoice = JOptionPane.showInputDialog("path f or g?");
   if (dExamineChoice.equals("f")) {
    JOptionPane.showMessageDialog(null, name + "...!");
   }
   else if (dExamineChoice.equals("g")) {
    JOptionPane.showMessageDialog(null, "Stuff g");
   }
}
else if (aChoice.equals("e")) {
   JOptionPane.showMessageDialog(null, "Stuff e");
}
else if (aChoice.equals("goBack")) {
    ///Backtrack back to start
}
}
else if (startingChoice.equals("b")) {
String bChoice = JOptionPane.showInputDialog("Path h or i?");
if (bChoice.equals("h")) {
    String hChoice = JOptionPane.showInputDialog("Path j, k, or l?");
    if (hChoice.equals("j")) {
        String jExamine = JOptionPane.showInputDialog("m or n?");
        if (jExamine.equals("m")) {
            JOptionPane.showMessageDialog(null,"Stuff m");
        }
        else if (jExamine.equals("n")) {
           JOptionPane.showMessageDialog(null,"Stuff n");
        }
    }
    else if (hChoice.equals("k")) {
        JOptionPane.showMessageDialog(null,"Stuff k");
    }
    else if (hChoice.equals("l")) {
        JOptionPane.showMessageDialog(null,"Stuff l");
    }
    }
else if (bChoice.equals("i")) {
    JOptionPane.showMessageDialog(null,"Stuff i");
}
    }
}
}

可以通过递归实现回溯。 但是,由于您需要迭代方法。 您可以使用堆栈来应用相同的概念。 每次您访问新广场时,请将当前状态推入堆栈。 当您需要回溯时(例如,您处于死胡同),请从堆栈中弹出。

如果您打算创建类似迷宫赛跑者的游戏,则可能需要记录访问的正方形。

是的,您应该使用while循环来做到这一点。

为每个开始选项重新选择一个选项,以便当用户选择该选项时,startingChoice设置为您要返回的字母。

您可以通过两种方式执行此操作。

可扩展的方式将是使用图形数据结构。 您可以使用JGraphTTinkerPop之类的东西。 但这是假设您要真正花哨的东西。 图形可以让您非常通用地对待整个路径选择(遍历)。 它可以让您设计各种路径,而回溯将仅跟踪您的来源。

更快的方法是使用Stack数据结构。 每次做出选择时,都会将该选择添加到堆栈中。 因此,您当前的位置始终存储在堆栈的顶部。 当您回溯时,只需弹出堆栈顶部,然后重试。 例如:

public static void main(String []){
    Stack<String> myPath = new Stack<>();
    while(detinationNotReached){
        myPath = goSomewhere(myPath);
    }
}
public Stack goSomewhere(Stack<String> myPath){
    String currentPosition = myPath.peek();
    String choice = getChoice(currentPosition);
    switch(choice){
        case "a":
            myPath.push("a");
        break;
        ... //Other choices
        case "back":
            myPath.pop(); // This effectively backtracks.
        break;
    }
    return myPath
}

这是一个如何在图形数据结构(即半边数据结构 )中存储可能性的示例:

class Edge {
    public final Node end;
    public Edge(Node end) { this.end = end; }
}

class Node {
    public final int id;
    public final List<Edge> edges;
    public Node(int id, List<Edge> edges) { this.id = id; this.edges = Collections.unmodifiableList(edges); }
}

class Graph {
    private final ArrayList<ArrayList<Edge>> halfEdges = new ArrayList<>();
    private final ArrayList<Node> nodes = new ArrayList<>();

    public Node addNode() {
        ArrayList<Edge> edges = new ArrayList<>();
        Node node = new Node(nodes.size(), edges);
        halfEdges.add(edges);
        nodes.add(node);
        return node;
    }

    public Edge addEdge(Node from, Node to) {
        assert nodes.contains(from) && nodes.contains(to);
        Edge edge = new Edge(to);
        halfEdges.get(from.id).add(edge);
        return edge;
    }
}

您可以这样使用它:

class Game
{
    public static void main (String[] args)
    {
        Graph graph = new Graph();
        Node root = graph.addNode();
        Node a = graph.addNode();
        graph.addEdge(root, a);
        Node b = graph.addNode();
        graph.addEdge(root, b);
        Node c = graph.addNode();
        graph.addEdge(root, c);
        Node d = graph.addNode();
        graph.addEdge(a, d);
        Node e = graph.addNode();
        graph.addEdge(a, e);
        // ...

        // main loop
        ArrayList<Node> path = new ArrayList<>();
        StringBuilder builder = new StringBuilder();
        while(true) {
            if(path.isEmpty())
                path.add(root);
            Node pos = path.get(path.size() - 1);
            builder.setLength(0);
            builder.append("At ").append(pos.id).append(", choices: back");
            for(Edge out : pos.edges)
                builder.append(", ").append(out.end.id);
            System.out.println(builder.toString());
            // handle input: add chosen node to path or remove last entry if "back"
            // ...
        }
    }
}

您可以将任何类型的数据添加到NodeEdge ,例如可以选择显示的实际名称(而不是id )等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM