在Scala中使用array.exists()

Kev*_*vin 1 functional-programming scala

我是Scala和函数式编程的新手.我正在创建一个井字游戏(七周七种语言的第一天(书)),我想知道如何以功能的方式"检查是否赢得"方法.

我想把'checkrow'部分(第一部分)作为'checkcolumn'(第二部分)部分,但我正在尝试的是不起作用.

这是我的(工作)代码:

def checkGame() {
    for (y <- board.indices) {
      // checks a row
      checkRow(y)
    }
    for (x <- board(0).indices) {
      // checks a column
      if(!board.exists(y => y(x) != 'x')){
        println("You have won mate! (column: " + x + ")")
      }
    }
  }

def checkRow(y: Integer) {
var isWon = true
for (x <- board(y).indices) {

  if (board(y)(x) != 'x') {
    isWon = false
  }
}
if (isWon) println("You have won mate! (row: " + y + ")")
}
Run Code Online (Sandbox Code Playgroud)

注意:board是一个二维数组.

到目前为止我得到了什么(不起作用):

if(!board.exists(x => x(y) != 'x')){
        println("You have won mate! (row: " + x + ")")
}
Run Code Online (Sandbox Code Playgroud)

Cyr*_*pet 7

拥有高阶函数的重点exists是避免必须遍历Array使用索引.

我是这样做的:

def wonRow(row: Array[Char]): Boolean = row.forall(c => c == 'x')
Run Code Online (Sandbox Code Playgroud)

这使用了该forall方法,该方法检查数组的所有元素是否满足谓词(此处,所有元素必须是'x').

def wonSomeRow(board: Array[Array[Char]]: Boolean = board.exists(row => wonRow(row))
Run Code Online (Sandbox Code Playgroud)

在这里,我们认为如果数组的任何元素(因此任何行)满足谓词(这里是获胜行),某些行会获胜

对于列,这在某种程度上更复杂,所以最简单的方法是在开始时执行:

def wonColumn(board: Array[Array[Char]], col: Int) = board.forall(row => row(i) == 'x')

def wonSomeColumn(board: Array[Array[Char]]) = (0 until board(0).size).exists(i => wonColumn(board, i))
Run Code Online (Sandbox Code Playgroud)

但是,我强烈建议您board(0).size在代码顶部替换一些常量,以避免出现错误.实际上,这是假设的

  • 1)board有第一行
  • 2)所有行board都有列表大小board(0).size

当然,这两个假设在Tic-Tac-Toe中是可以的,但在函数式编程中,这种编译时假设应该放在类型系统中,以便在编译时进行验证.然而,这将使用这种东西(只知道它们存在)开始函数式编程迈出了一大步.

编辑

我只记得transpose数组上有一个方法,所以你可以这样做(对于列)

def wonSomeCol(board: Array[Array[Char]]) = wonSomeRow(board.transpose)
Run Code Online (Sandbox Code Playgroud)