val board = Array.ofDim[Int](3,3) def printBoard() { println( board.map(_.map { case 1 => 'X' case -1 => 'O' case 0 => '.' }.mkString).mkString("\n") ) } def isFullRow(elems: Int*) = elems.head != 0 && elems.forall(_ == elems.head) def threeInRow() = { isFullRow(board(0)(0), board(0)(1), board(0)(2)) || isFullRow(board(1)(0), board(1)(1), board(1)(2)) || isFullRow(board(2)(0), board(2)(1), board(2)(2)) || isFullRow(board(0)(0), board(1)(0), board(2)(0)) || isFullRow(board(0)(1), board(1)(1), board(2)(1)) || isFullRow(board(0)(2), board(1)(2), board(2)(2)) || isFullRow(board(0)(0), board(1)(1), board(2)(2)) || isFullRow(board(0)(2), board(1)(1), board(2)(0)) } def boardIsFull() = board.forall(_.forall(_ != 0)) //determines if player a wins for sure if he plays perfectly //b - player who's turn it is def win(a: Int, b: Int, yPos: Int, xPos: Int): Boolean = { var result = if(a == b) true else false board(yPos)(xPos) = b if(threeInRow()) { if(a == b) result = true else result = false } else if(boardIsFull()) { result = false } else { for(y <- 0 until 3; x <- 0 until 3) { if(board(y)(x) == 0) { if(a == b) result = result && win(a, -b, y, x) else result = result || win(a, -b, y, x) } } } board(yPos)(xPos) = 0 result } val rand = new util.Random printBoard() println() while(!threeInRow() && !boardIsFull()) { println("make your move") var (x,y) = (-1,-1) do { try { print("x: ") x = readInt() print("y: ") y = readInt() } catch { case _: NumberFormatException => x = -1; y = -1 } } while(x < 0 || x > 2 || y < 0 || y > 2 || board(y)(x) != 0) board(y)(x) = 1 if(!threeInRow() && !boardIsFull()) { val possibleMoves = for(y <- 0 until 3; x <- 0 until 3 if(board(y)(x) == 0)) yield (y,x) val moveNotLoose = possibleMoves.filterNot(coord => win(1, -1, coord._1, coord._2)) val moveWin = possibleMoves.filter(coord => win(-1, -1, coord._1, coord._2)) val move = rand.shuffle(if(moveWin.isEmpty) moveNotLoose else moveWin).head board(move._1)(move._2) = -1 } println() printBoard() println() }