") statusBar.append(resetButton) statusBar.append(status) statusBar.append(passButton) playground.append(statusBar) } // The Game ------------------------------------------------------------------ def reset() { startGame() } @JSExport def startGame() { // Set up the board allSquares foreach (_.owner = NoPlayer) board(3)(3).owner = White board(3)(4).owner = Black board(4)(3).owner = Black board(4)(4).owner = White // White begins currentPlayer = White // Let's go! startTurn() } def startTurn() { val (scoreWhite, scoreBlack) = computeScore() status.text(currentPlayer+"'s turn -- White: "+scoreWhite+ " -- Black: "+scoreBlack) passButton.prop("disabled", true) if (!existsValidMove()) { // Test if the other player can do something currentPlayer = currentPlayer.opponent val opponentCanDoSomething = existsValidMove() currentPlayer = currentPlayer.opponent if (opponentCanDoSomething) { passButton.prop("disabled", false) } else { // End of game val winnerText = if (scoreWhite > scoreBlack) "White won!" else if (scoreBlack > scoreWhite) "Black won!" else "Draw" status.text("Game finished -- White: "+scoreWhite+ " -- Black: "+scoreBlack+" -- "+winnerText) } } } def clickSquare(square: Square) { val toFlip = computeFlips(square) if (!toFlip.isEmpty) { (square :: toFlip) foreach (_.owner = currentPlayer) nextTurn() } } def pass() { assert(!existsValidMove()) nextTurn() } def existsValidMove(): Boolean = { allSquares.exists(isValidMove) } def isValidMove(square: Square): Boolean = { !computeFlips(square).isEmpty } def computeFlips(square: Square): List[Square] = { if (square.owner != NoPlayer) Nil else { for { i <- (-1 to 1).toList j <- -1 to 1 if i != 0 || j != 0 flip <- computeFlipsInDirection(square.x, square.y, i, j) } yield flip } } def computeFlipsInDirection(x: Int, y: Int, dirx: Int, diry: Int): List[Square] = { val allInDir = allSquaresInDirection(x, y, dirx, diry) val (toFlip, remaining) = allInDir.span(_.owner == currentPlayer.opponent) val success = remaining.headOption.exists(_.owner == currentPlayer) if (success) toFlip else Nil } def allSquaresInDirection(fromx: Int, fromy: Int, dirx: Int, diry: Int): List[Square] = { val nextx = fromx + dirx val nexty = fromy + diry if (inBounds(nextx, nexty)) board(nextx)(nexty) :: allSquaresInDirection(nextx, nexty, dirx, diry) else Nil } def computeScore(): (Int, Int) = { allSquares.foldLeft((0, 0)) { case ((white, black), square) => square.owner match { case White => (white+1, black) case Black => (white, black+1) case NoPlayer => (white, black) } } } def nextTurn() { currentPlayer = currentPlayer.opponent startTurn() } }