这是一个关于thiscodefirt callenge的问题。
参赛者被要求检查一个扫雷场,表示为一个二维数组是否有效。
细节:
扫雷游戏板的每个单元可以是:
一个地雷(显示为9)
或者是一个数字,代表着周围牢房里的地雷数量
(当一个单元格在至少一个角上与另一个单元格相交时,该单元格被视为包围另一个单元格)(显示为0-8)
我的方法(有效):
循环浏览所有项目
检查邻居是否有地雷(如果有地雷,则计算地雷数量)
将已发现的地雷数量与瓷砖上的数量进行比较
返回false,如果数字不相等,则继续
有人能给我解释一下这种方法是如何工作的吗?

minesweeper1 = g =>
!g.some((r,i) =>
      r.some((c,j) =>
            c < 9 && (f = d => d-- ? f(d) - ((g[i + ~-(d/3)] || 0)[j + d%3 - 1] > 8) : c)(9)
           )
     )

我了解多少:
g是2d数组,表示字段
.some将测试,如果数组中的元素将通过测试
r是字段中的单个行
c是每行中的每个元素
我和J是什么?柜台?
什么是d?
编写如此神秘的代码有什么好处?

最佳答案

minesweeper1 = mainarray => // an arrow function, that gets the two d array passed
!mainarray.some((row,rownumber) =>
  row.some((field,columnumber) =>//checking the 2d array if some of the fields
        field < 9 && (//is not a mine
          recursive = d => //and the magic recursive function is true
            d--
            ? recursive(d) /* get the value of one lower d*/ - ((mainarray[rownumber + ~-(d/3)] || 0)[columnnumber + d%3 - 1] > 8) /* subtract one if this magic is true */
             : field//if d=-1 it returns field
         )(9)//the starting point of the recursive function d=9
   ))

所以它基本上检查,如果某些字段不是地雷(字段
field //the current value as start value

//d=0
- (mainarray[rownumber - Math.floor(d/3)-1][columnnumber + d%3 ] >8)
//d=1
 - (mainarray[rownumber - Math.floor(d/3)-1][columnnumber + d%3 ] >8)
//...
//repeat until d=9

(如果你想知道~(d/3),它会做以下事情:
0-2: ~-([0,1,2]/3) = ~-0 = -(-0)-1 = -1
3-5: ~-([3,4,5]/3) = ~-1 = -(-1)-1 = 0
6-8: ~-([6,7,8]/3) = ~-2 = -(-2)-1 = 1


所以基本上,函数将经历这个模式(0是字段,x是当前选中的位置)
d=0
X - -
- 0 -
- - -

d=1
- X -
- 0 -
- - -

d=2
- - X
- 0 -
- - -

d=3
- - -
X 0 -
- - -

...

然后如果有地雷(>8),它从字段中减去1(真)。所以如果场是4,周围有4个地雷,它会做4-1-1-1-1,所以整件事是0,这是错误的:
两个示例(字段位于中间):
9 9 9
9 4 1
1 1 0

所以递归函数将返回0(falsy)(4-1-1-1-1)
9 9 9
2 4 1
0 0 0

这将返回1(truthy)(4-1-1-1)
所以这个递归函数可以重命名为countaroundiswrong:
!mainarray.some((row,rownumber) =>
  row.some((field,columnumber) =>
    fieldismine() && countaroundiswrong(mainarray,field,rownumber,columnumber)
  )
)

所以,如果有地雷,周围的计数是错误的,找到了某个区域,整件事都是真的,倒过来,结果是假的不神秘的方式:
function countaroundiswrong(mainarray,field,col,row){
 for(var x=-1;x<2;x++){
  for(var y=-1;y<2;y++){
    if(mainarray[row+x] && mainarray[row+x][col+y]){
      if(mainarray[row+x][col+y] >8){
         field--;
      }
    }
   }
  }
  return field;
}

关于javascript - 扫雷算法解决方案,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45344810/

10-09 13:45