我正在创建一个连接四游戏,我正在使用递归来检查所做的移动是否是一个成功的举动。 x和y是7x6网格上移动的坐标。
我还没有实现检查点的方向是否正确匹配(所以现在如果4个部分以任何方式接触,它仍应检测到胜利)。但在我这样做之前,我遇到了一个问题。即使所做的移动应该导致获胜,如果存在连续不存在四个的另一个路径,则该函数返回false。
函数示例错误地未检测到胜利(绿线是应该检测到的,红线是我认为该函数提前返回假的路径):https://prnt.sc/fjhia1
这是我的代码:
function isVisited(x,y,visited){
var pointStr = x + "," + y;
var result = visited.some(function(e){
return e.join() == pointStr;
});
return result;
}
function checkWin(x, y, color, visited, count) {
if(count==3) return true;
for(i=-1; i<2; i++) {
for (j=-1; j<2; j++) {
if(!(i==0 && j==0) && (x+i)<7 && (y+j)<6 && (x+i)>-1 && (y+j)>-1 && grid[x+i][y+j] != null) {
if (grid[x+i][y+j] == color && !isVisited(x+i,y+j,visited)) {
visited.push([x, y]);
if(checkWin(x+i, y+j, color, visited, count+1)) return true;
}
}
}
}
return false;
}
为了澄清,i和j是用于检查起点周围所有点的偏移量。
颜色参数是&#34;黑色&#34;或&#34;红色&#34;。网格是一个7x6 2D阵列,用于存储哪些玩家棋子在哪里,并在玩家移动时更新。整个checkWin()函数在每次移动后调用,x和y参数是刚刚播放的移动的坐标。数组中的颜色示例显示在图片链接中。
来自图像的网格样本,当在x = 5,y = 3,color =&#34; black&#34;中传递给checkWin()时应返回true,但它不会:
[[null,null,null,null,null,null],[null,null,null,null,null,null],[null,null,null,null,null,null],[null,null,null,null,null,"black"],[null,null,null,null,"black","red"],[null,null,null,"black","black","black"],[null,null,null,"red","red","red"]]
答案 0 :(得分:1)
这是一些有效的代码。我试图将grid
放入代码中。
您的代码存在一些问题,但我认为主要的问题是您没有正确地总结计数。在您的代码中,您将遇到这种情况:
starting here
|
v
R R R R
您将首先探索此节点的左侧,并且您会发现连续没有四个红色。然后你会向右探索,发现连续没有四个红色。但你需要做的是 sum 这些。你需要计算起始节点,然后是左边的两个,然后是右边的两个,以便连续获得正确的四个。
以下代码采用该策略。这是一个重写,但我试图保持它有点类似于您的原始代码。如果不清楚,请告诉我。 (这个代码与你的代码一样,并不真正关心“连续”,而只是“触摸”。)
const N = null, B = "black", R = "red";
const grid = [
// 0 1 2 3 4 5 6
[N, N, N, N, N, N, N], // 0
[N, N, N, N, N, N, N], // 1
[N, N, N, N, N, N, N], // 2
[N, N, N, N, N, B, R], // 3
[N, N, N, N, B, B, R], // 4
[N, N, N, B, R, B, R], // 5
];
function isVisited(x, y, visited) {
var pointStr = [x, y].join();
return visited.some(function (e) {
return e.join() == pointStr;
});
}
function checkWin(x, y) {
function countNeighbors(x, y, color, visited) {
if (y > 5 || x > 6) { // out of bounds
return 0;
}
if (isVisited(x, y, visited)) { // already visited
return 0;
}
visited.push([x, y]);
if (grid[y][x] !== color) { // wrong color
return 0;
}
var count = 1; // Count ourselves first.
// For each neighbor,
for (var i = -1; i < 2; i++) {
for (var j = -1; j < 2; j++) {
// add the count starting at that neighbor.
count += countNeighbors(x+i, y+j, color, visited);
}
}
// Return the total found.
return count;
}
// There's a win if the count is at least four.
return countNeighbors(x, y, grid[y][x], []) >= 4;
}
console.log(checkWin(3, 5)); // true
console.log(checkWin(5, 3)); // true
console.log(checkWin(6, 3)); // false
答案 1 :(得分:0)
您将错误的网格单元索引推送到visited
列表。它应该是[x + i, y + j]
。
或者,您可以将语句移动到函数顶部并保持原样,这在我看来更好。函数本身会检查一个单元格,将该单元格标记为已检查或在开始时访问它更有意义。