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()
}