1. val board = Array.ofDim[Int](3,3)
  2.  
  3. def printBoard() {
  4.   println(
  5.     board.map(_.map {
  6.       case 1 => 'X'
  7.       case -1 => 'O'
  8.       case 0 => '.'
  9.     }.mkString).mkString("\n")
  10.   )
  11. }
  12.  
  13. def isFullRow(elems: Int*) = elems.head != 0 && elems.forall(_ == elems.head)
  14.  
  15. def threeInRow() = {
  16.   isFullRow(board(0)(0), board(0)(1), board(0)(2)) ||
  17.   isFullRow(board(1)(0), board(1)(1), board(1)(2)) ||
  18.   isFullRow(board(2)(0), board(2)(1), board(2)(2)) ||
  19.   isFullRow(board(0)(0), board(1)(0), board(2)(0)) ||
  20.   isFullRow(board(0)(1), board(1)(1), board(2)(1)) ||
  21.   isFullRow(board(0)(2), board(1)(2), board(2)(2)) ||
  22.   isFullRow(board(0)(0), board(1)(1), board(2)(2)) ||
  23.   isFullRow(board(0)(2), board(1)(1), board(2)(0))
  24. }
  25.  
  26. def boardIsFull() = board.forall(_.forall(_ != 0))
  27.  
  28. //determines if player a wins for sure if he plays perfectly
  29. //b - player who's turn it is
  30. def win(a: Int, b: Int, yPos: Int, xPos: Int): Boolean = {
  31.   var result = if(a == b) true else false
  32.   board(yPos)(xPos) = b
  33.   if(threeInRow()) {
  34.     if(a == b) result = true
  35.     else result = false
  36.   } else if(boardIsFull()) {
  37.     result = false
  38.   } else {
  39.     for(y <- 0 until 3; x <- 0 until 3) {
  40.       if(board(y)(x) == 0) {
  41.         if(a == b) result = result && win(a, -b, y, x)
  42.         else result = result || win(a, -b, y, x)
  43.       }
  44.     }
  45.   }
  46.   board(yPos)(xPos) = 0
  47.   result
  48. }
  49.  
  50. val rand = new util.Random
  51.  
  52. printBoard()
  53. println()
  54.  
  55. while(!threeInRow() && !boardIsFull()) {
  56.   println("make your move")
  57.   var (x,y) = (-1,-1)
  58.   do {
  59.     try {
  60.       print("x: ")
  61.       x = readInt()
  62.       print("y: ")
  63.       y = readInt()
  64.     } catch {
  65.       case _: NumberFormatException => x = -1; y = -1
  66.     }
  67.   } while(x < 0 || x > 2 || y < 0 || y > 2 || board(y)(x) != 0)
  68.  
  69.   board(y)(x) = 1
  70.   if(!threeInRow() && !boardIsFull()) {
  71.     val possibleMoves = for(y <- 0 until 3; x <- 0 until 3 if(board(y)(x) == 0)) yield (y,x)
  72.     val moveNotLoose = possibleMoves.filterNot(coord => win(1, -1, coord._1, coord._2))
  73.     val moveWin = possibleMoves.filter(coord => win(-1, -1, coord._1, coord._2))
  74.     val move = rand.shuffle(if(moveWin.isEmpty) moveNotLoose else moveWin).head
  75.    
  76.     board(move._1)(move._2) = -1
  77.   }
  78.   println()
  79.   printBoard()
  80.   println()
  81. }