如何正确检测邻居小区

时间:2016-04-04 14:06:48

标签: javascript html canvas

作为一个学习项目,我正在编写一个简单的逻辑游戏,其中用户拥有html画布网格,他需要连接相同颜色的方块。

我坚持检测相邻单元格的属性(颜色),如果条件匹配(邻居颜色与我的不同),则不应填充单元格。

我的问题是: 1)有没有更好的方法来检查目标方块是否适用于填充颜色?

2)如果有,我如何正确处理新单元格的点击?

function checkNeighbourTiles(aX, aY) {
  var coords = [
    [(aX - 1), (aY - 1)],
    [(aX - 1), (aY)],
    [(aX - 1), (aY + 1)],
    [(aX), (aY - 1)],
    [(aX), (aY + 1)],
    [(aX + 1), (aY - 1)],
    [(aX + 1), (aY - 1)],
    [(aX + 1), (aY + 1)]
  ]

  for (i = 0; i < coords.length; i++) {
    var x = coords[i][0]
    var y = coords[i][1]
    var b = cells[x][y]
  }
}

到目前为止我的代码 - jsfiddle

2 个答案:

答案 0 :(得分:1)

选择方块的更简洁方法可能是使用循环:

function (x, y){
    var coords = [];
    for(i = (x-1); i < (x+2); i++){
        for(j = (y-1); j < j (y+2); j++){
            coords.push([i, j]);
        }
    }

    //rest of the code
}

如果检查[0,0]处的方块,此代码将在[-1,-1]处搜索一个方块。你需要一些严肃的if语句来过滤掉正确的方块。

同样,如果你有一个9x9网格并且你搜索[8,8],代码最终将寻找[9,9]方格并超出范围。

答案 1 :(得分:1)

It depends on the complexity and performance constraints. As you have done a direct lookup table is about as efficient as can be for a simple grid lookup, though instead of creating the lookup array each time just create an offsets array once.

// an array of offset coordinates in pairs x,y 8 pairs skipping the center
const NEIGHBOURS = [-1, -1, 0, -1, 1, -1, -1, 0, 1, 0, -1, 1, 0, 1, 1, 1];

const GIRD_SIZE = 10; // 10 by ten grid
function checkNeighbourTiles(x,y){
    var lx, ly, cellResult;
    var i = 0;
    while(i < 16){  // check for each offset
        lx = x + NEIGHBOURS[i++]; // get the x offset
        ly = y + NEIGHBOURS[i++]; // get the y offset
        // ensure you are inside the grid
        if( ly >= 0 && ly < GRID_SIZE && lx >= 0 && lx < GRID_SIZE ){
             cellResult = cell[lx][ly];
             // do what is needed with the result;
        }
    }
}

For the type of 2D array that is about simplest way to do it.

The alternative is a linked array were each cell holds and array of references to the neighbouring cells. Thus (and with simplicity in mind) just the top left right and bottom. Then each cell would look like

cell = {
    top : undefined,
    left : undefined,
    right : undefined,
    bottom : undefined,
    ... other data
}

Then when you add the cell you set the references to the appropriate cells

// first add all the cells to the array 
// then for each cell call this
function AddCell(cell,x,y){
    cell.top = cells[x][y-1];
    cell.left = cells[x-1][y];
    cell.right = cells[x+1][y];
    cell.bottom = cells[x][y+1];
    // also the cells you just reference should also reference back
    // where top refs botton and left refs right and so fourth.
    cells.top.bottom = cell;
    cells.bottom.top = cell;
    cells.left.right = cell;
    cells.right.left = cell;

}

Then at any point if you want to find which cell is above

//x and y are the cell
var cellAbove = cell[x][y].top;

This method has many advantages when you start getting complex linking, like dead cells, or skipping cells, or even inserting cells so that you change the topology of the grid.

You can also do complex searches like two left one down

resultCall = cell[x][y].left.left.bottom; // returns the cell two left one down

But it is a pain to maintain the links as there is a lot of extra code involved so for a simple 2D grid your method is the best.