以迭代复杂的方式检查ArrayList

时间:2014-05-27 17:06:18

标签: java

我现在已经在这个功能上工作了5个小时,我无法让它工作。这有点复杂,所以让我先解释一下这是什么:

  1. 作为我学习中的一个小考试,我必须用KI编写一个halma控制台游戏。
  2. 除了移动计算外,一切都已完成并且有效。
  3. 移动是从场a移动到场b,玩家可以根据游戏规则在一轮中执行(注意:我们没有使用标准的halma规则,我们使用不同的规则)。
  4. “班级移动”包括“移动前的图形”所在的“起始单元格”和“移动结束时图形将保持打开的目标单元格”。它可以包括几个单元的阵列,该图从开始经过的停止单元 - >目标,因为可以在一次移动中执行多次跳转。
  5. 移动的有效示例: a - > b(从字段a到字段b) d - > f到g,h,i(从场d到场f到场g,h,i

    我的移动计算,其中为给定数字计算所有可能的移动由2个部分组成。一个expand()函数,它将生成所有可能的移动(完美地工作)和一个无法正常工作的jumpFix()函数。例如:

    在expand()之后我得到了类似的东西:

    a -> b
    b -> c
    c -> d
    s -> t
    

    然而这还没有完成,因为前3个Move实际上是1 Move。因为玩家可以从 - >移动d转一圈,因为那3个是连续的Move。固定的Move看起来像这样:

    a -> d through b,c
    s -> t
    

    jumpFix()也完全适用于这种情况,但是当它不起作用时有一个特定的情况。假设我们遇到这种情况。

    a -> b
    b -> c
    c -> d
    b -> e
    e -> f
    f -> g
    s -> t
    

    然后唯一有效的jumpFix()输出是:

    a -> d through b,c
    a -> g through b,e,f
    s -> t
    

    然而,我无法让它工作。有人有个主意吗?注意:它肯定需要迭代,而不是rekursive,否则我会得到StackoverflowError。

    这是我目前的jumpFix()代码:

    /**
     * Takes a look into all calculated moves and finds those which should be seen as one move, but are still
     * considered to be more than one move (several jumps in one move)
     */
    public static List<Move> jumpFix(List<Move> moves) {    
    
        Set<Move> result = new HashSet<Move>();
        Set<Move> remove = new HashSet<Move>();
    
        int lastSize = -1;
    
        // repeat action until no moves could be merged
        while (lastSize != remove.size()) {
    
            lastSize = remove.size();
    
            for (Move m : moves) {
    
                if (remove.contains(m)) {
                    // move already in delete list, skip
                    continue;
                }
    
                for (Move n : moves) {
    
                    if (m == n) {
                        // don't chain yourself, skip
                        continue;                       
                    }
    
                    if (remove.contains(n)) {
                        // move already in delete list, skip
                        continue;
                    }
    
    
                    if (m.contigious(n) && !m.contains(n)) {    
                        // Consecutive Move found
                        result.remove(m); // remove from set to avoid hashing conflicts
                        m.chain(n); // chain moves
                        result.add(m); // add to result
                        remove.add(n); // remove chained node
                    }
                }
    
                if (!result.contains(m)) {
                    // sole move, add to results
                    result.add(m);
                }               
            } 
        }
    
        // remove deleted nodes that made it into the result list (due to 
        // arbitrary ordering)
        result.removeAll(remove);
    
        return new ArrayList<Move>(result);
    }
    

    如果有人知道如何实现Move分裂为2个或更多分支的特殊情况以及能够处理这种情况的jumpFix(),我将非常高兴。我花了5个小时就完成了这一点,并且无法在瞬间解决这个问题。

    编辑:添加了有条不紊的代码:

    public boolean contigious(Move other) {
        return this.target.equals(other.start);
    }
    

1 个答案:

答案 0 :(得分:0)

经过一番思考,这是一个完美无缺的解决方案。如果有人需要它,请输入以下代码:

public static List<Move> jumpFix(List<Move> moves) {   

            List<Move> result = new ArrayList<Move>();
            List<Move> remove = new ArrayList<Move>();

                    for (Move m : moves) {

                            if (remove.contains(m)) {
                                    // move already in delete list, skip
                                    continue;
                            }

                            boolean hasConsecutives = false;
                            for (Move n : moves) {
                                    List<Cell> branches = new ArrayList<Cell>();
                                    if (m == n) {
                                            // don't chain yourself, skip
                                            continue;                                              
                                    }

                                    if (remove.contains(n)) {
                                            // move already in delete list, skip
                                            continue;
                                    }


                                    if (m.contigious(n)     && !m.contains(n)) {   
                                            hasConsecutives = true;
                                            n.setChanged(true);
                                            if(branches.contains(m.getTarget())) {
                                                    // Mehrfachverzweigung
                                                    n.setStart(m.getStart());
                                                    result.add(n);
                                                    branches.add(m.getTarget());
                                                    n.addStop(m.getTarget());
                                            }
                                            else {
                                                    // Consecutive Move found keine Mehrfachverzweigung (bisher)
                                                    result.remove(n); // remove from set to avoid hashing conflicts
                                                    branches.add(m.getTarget());
                                                    n.addStop(m.getTarget());
                                                    n.setStart(m.getStart());
                                                    result.add(n); // add to result
                                            }
                                    }                                              
                            }

                            if(hasConsecutives == true) {
                                    remove.add(m);
                            }
                            else {
                                    if(!m.isChanged()) {
                                            result.add(m);
                                    }                                      
                            }              
                    }

            return result;
    }