在网格中找到特定形状

时间:2018-07-18 15:28:08

标签: java algorithm grid shape

我有一个二维数组作为网格(大小为9x9),并希望在其中找到几个特定的​​形状:

XXX XXX  X
 X  X   XXX
 X  X    X

之后,我搜索了这些并将它们从要搜索3/4/5长的直线的网格中删除。注意:此形状的所有元素必须具有相同的颜色。

很显然,我可以用硬编码或用暴力破解的方式找到这些形状,但是我正在寻找一种算法,可以在可行的时间内找到这些形状。

这是我用于查找和删除直线的代码。作为输出,我期望在此过程中已删除的元素数量。它有效(大多数情况下……如果您能告诉我如何将水平/垂直组合在一起,则可以得到加分,但这是另一天的主题):

private Cell[][] field;

/**
 * Removes a given list of stones from the field and 
 * fills the slots with empty ones.
 * 
 * @param list 
 */
private void removeStones(ArrayList<int[]> list) {
    for(int i = 0; i < list.size(); i++) {
        field[list.get(i)[1]][list.get(i)[0]] = new Cell(Color.NONE, Attribute.NONE);
    }
}

/**
 * Check the gamefield for valid straight structures and remove them.
 * 
 * @return The amount of stones removed.
 */
private int checkStraight() {
    Color curr = Color.NONE;
    int counter = 0;
    int total = 0;
    /* Holds the coordinates of the shape being processed currently */
    ArrayList<int[]> stones = new ArrayList<>();

    // Horizontal 
    for(int y = 0; y < getSize(); y++) {
        for(int x = 0; x < getSize(); x++) {
            if(curr == getCell(x, y).getBlock().getColor() 
                    && getCell(x, y).isGem()) {
                counter++;
                stones.add(new int[] {x, y});
            }             
            else {
                if(counter > 2) {
                    total += counter;
                    removeStones(stones);
                    /* Debugging Info */
                    stones.forEach((a)->System.out.println("[" + a[0] + "," + a[1] + "]"));
                    System.out.println("");
                }
                counter = 1;
                curr = getCell(x, y).getBlock().getColor();
                stones = new ArrayList<>();
                stones.add(new int[] {x, y});
            }
        }
        curr = Color.NONE;
        counter = 0;
    }

    // Vertical
    for(int x = 0; x < getSize(); x++) {
        for(int y = 0; y < getSize(); y++) {
            if(curr == getCell(x, y).getBlock().getColor() 
                    && getCell(x, y).isGem()) {
                counter++;
                stones.add(new int[] {x, y});
            }             
            else {
                if(counter > 2) {
                    total += counter;
                    removeStones(stones);
                    /* Debugging Info */
                    stones.forEach((a)->System.out.println("[" + a[0] + "," + a[1] + "]"));
                    System.out.println("");
                }
                counter = 1;
                curr = getCell(x, y).getBlock().getColor();
                stones = new ArrayList<>();
                stones.add(new int[] {x, y});
            }
        }
        curr = Color.NONE;
        counter = 0;
    }

    return total;
}

/**
 * Return cell at col/row.
 *
 * @param col
 * @param row
 * @return The cell at position col/row.
 */
public Cell getCell( int col, int row ) {
    return field[row][col];
}

/**
 * Return the grid size.
 *
 * @return The size of the grid.
 */
public int getSize() {
    return field.length;
}

如果您需要有关细胞结构的其他信息,或者需要澄清某些事物应该如何工作的信息,请询问,我会提供更多信息。

1 个答案:

答案 0 :(得分:0)

以防万一有人偶然发现与我相同的问题,我想分享一下我如何最终解决这个问题。

我制作了一个寻找给定形状的函数(在我的情况下,我总是需要检查3x3正方形中的5个位置,但是您可以根据需要进行调整),然后将结果图案与对象的内容进行比较。网格并返回找到的位置

然后通过调用任意旋转输入基本L形以在给定位置找到该L形来调用此函数4次以找到“ L形”。

/**
* Find the structure specified in p1, p2, p3, p4 and p5 rotated by 90
* degrees rot times
*
* @param x   X-Position of the structure
* @param y   Y-Position of the structure
* @param rot How many times to rotate by 90 degrees
* @param p1  A piece of the structure
* @param p2  A piece of the structure
* @param p3  A piece of the structure
* @param p4  A piece of the structure
* @param p5  A piece of the structure
* @return The ArrayList containing all found stones
*/
private ArrayList<int[]> findStructure( int x, int y, int rot, int[] p1, int[] p2, int[] p3, int[] p4, int[] p5 ) {
    ArrayList<int[]> stones = new ArrayList<>();

    /* Rotate shape by 90 degrees rot times */
    for( int i = 1; i <= rot; i++ ) {
        /* Rotate 90 degress */
        p1 = new int[]{-p1[1], p1[0]};
        p2 = new int[]{-p2[1], p2[0]};
        p3 = new int[]{-p3[1], p3[0]};
        p4 = new int[]{-p4[1], p4[0]};
        p5 = new int[]{-p5[1], p5[0]};
    }

    // Do stuff and see if your pattern matches the actual grid content
    // ...

    return stones;
}