Peg Solitaire回溯无限循环

时间:2015-10-24 10:30:19

标签: java backtracking

我正在使用java中的回溯制作一个peg solitaire resolver。

这是我做过的方法:

private void solve(Board board, ArrayList<Movement> solution, Boolean result) {
    ArrayList<Movement> movs = board.getMovements();
    for (Movement movement : movs) {
        if (board.isMovementValid(movement)) {
            board.doMovement(movement);
            if(!board.isSolution()) {
                solution.add(movement);
                solve(board, solution, result);
                result.setValue(false);
            } else {
                result.setValue(true);
            }

        }
    }
    result.setValue(false);
}

问题是我找不到解决方案。以下是代码的输出:http://pastebin.com/raw.php?i=BhkLu3qr。如您所见,解决方案数组不完整。

感谢。

2 个答案:

答案 0 :(得分:0)

不是那么优雅,但为了追溯并重试替代方案,必须采取措施:

ArrayList<Movement> movs = board.getMovements();
for (Movement movement : movs) {
    if (board.isMovementValid(movement)) {
        board.doMovement(movement);
        solution.add(movement);
        if(!board.isSolution()) {
            solve(board, solution, result);
            // Initialized to result.setValue(false);
            if (result.getValue()) { return; }
        } else {
            result.setValue(true);
            return;
        }
        solution.remove(movement);
        board.undoMovement(movement);
    }
}
result.setValue(false);

另外,对于您对第一个解决方案感到满意的更一般的解决方案,我已添加了回报。

答案 1 :(得分:0)

假设您的board.getMovements()方法为您提供了游戏中此点所有可能移动的列表,那么您几乎就在那里。你只需要在胜利时停下来。我为了清晰起见而进行了重构。

private boolean solve(Board board, ArrayList<Movement> solution) {
    // The base case: if it's already solved, we're done
    if (board.isSolution())
        return true;

    // Get all possible moves from this point
    ArrayList<Movement> movs = board.getMovements();
    for (Movement movement : movs) {
        if (board.isMovementValid(movement)) {
            board.doMovement(movement);
            solution.add(movement);
            if (solve(board, solution))
                // That move led to success :-)
                return true;
            else
                // That move led to failure :-(
                solution.remove(movement);
        }
    }
    return false;
}