summaryrefslogtreecommitdiff
path: root/examples/scala-js/examples/reversi/Reversi.scala
diff options
context:
space:
mode:
Diffstat (limited to 'examples/scala-js/examples/reversi/Reversi.scala')
-rw-r--r--examples/scala-js/examples/reversi/Reversi.scala266
1 files changed, 0 insertions, 266 deletions
diff --git a/examples/scala-js/examples/reversi/Reversi.scala b/examples/scala-js/examples/reversi/Reversi.scala
deleted file mode 100644
index b4a34a4..0000000
--- a/examples/scala-js/examples/reversi/Reversi.scala
+++ /dev/null
@@ -1,266 +0,0 @@
-/* Scala.js example code
- * Public domain
- * @author Sébastien Doeraene
- */
-
-package reversi
-
-import scala.annotation.tailrec
-import scala.scalajs.js
-import scala.scalajs.js.annotation.JSExport
-
-sealed abstract class OptPlayer
-
-sealed abstract class Player extends OptPlayer {
- val opponent: Player
-}
-
-case object NoPlayer extends OptPlayer
-
-case object White extends Player {
- val opponent = Black
-}
-
-case object Black extends Player {
- val opponent = White
-}
-
-@JSExport("Reversi")
-class Reversi(jQuery: JQueryStatic, playground: JQuery) {
-
- // The Model -----------------------------------------------------------------
-
- val BoardSize = 8 // size of a Reversi board
-
- def inBounds(index: Int): Boolean = index >= 0 && index < BoardSize
- def inBounds(x: Int, y: Int): Boolean = inBounds(x) && inBounds(y)
-
- class Square(val x: Int, val y: Int) {
- private var _owner: OptPlayer = NoPlayer
-
- var onOwnerChange: (OptPlayer, OptPlayer) => Unit = (oldP, newP) => ()
-
- def owner = _owner
- def owner_=(value: OptPlayer) {
- val previous = _owner
- if (value != previous) {
- _owner = value
- onOwnerChange(previous, value)
- }
- }
-
- override def toString() = "Square("+x+", "+y+", "+owner+")"
- }
-
- val board = Array.tabulate[Square](BoardSize, BoardSize)(new Square(_, _))
- val allSquares = board.flatten
- var currentPlayer: Player = White // Irrelevant, set again in startGame()
-
- // The GUI -------------------------------------------------------------------
-
- val resetButton = createResetButton()
- val passButton = createPassButton()
- val status = createStatus()
- buildUI()
-
- def createResetButton() = {
- jQuery("<input>", js.Dynamic.literal(
- `type` = "button", value = "Reset"
- )).click(reset _)
- }
-
- def createPassButton() = {
- jQuery("<input>", js.Dynamic.literal(
- `type` = "button", value = "Pass"
- )).click(pass _)
- }
-
- def createStatus() = {
- jQuery("<span>")
- }
-
- def buildUI() {
- // Some dimensions
- val SquareSizePx = 48
- val HalfSquareSizePx = SquareSizePx/2
- val PawnRadiusPx = HalfSquareSizePx-4
- val BoardSizePx = BoardSize*SquareSizePx + 3
-
- // Creat the board canvas
- val boardCanvas = jQuery(
- "<canvas width='"+BoardSizePx+"' height='"+BoardSizePx+"'></canvas>")
- val domCanvas = boardCanvas.get(0).asInstanceOf[HTMLCanvasElement]
- val context = domCanvas.getContext("2d").asInstanceOf[CanvasRenderingContext2D]
-
- playground.append(jQuery("<div>").append(boardCanvas))
-
- /** Draw the specified square on the board canvas */
- def drawSquare(square: Square) {
- val x = square.x * SquareSizePx
- val y = square.y * SquareSizePx
-
- // Background
- context.fillStyle = "green"
- context.fillRect(x, y, SquareSizePx, SquareSizePx)
-
- // Border
- context.fillStyle = "black"
- context.lineWidth = 3
- context.strokeRect(x, y, SquareSizePx, SquareSizePx)
-
- // Pawn
- if (square.owner != NoPlayer) {
- context.fillStyle = if (square.owner == White) "white" else "black"
- context.beginPath()
- context.arc(x+HalfSquareSizePx, y+HalfSquareSizePx, PawnRadiusPx,
- 0, 2*Math.PI, true)
- context.fill()
- }
- }
-
- // Draw squares now, and everytime they change ownership
- for (square <- allSquares) {
- drawSquare(square)
- square.onOwnerChange = { (prevOwner, newOwner) =>
- drawSquare(square)
- }
- }
-
- // Configure clicks on the board
- boardCanvas.click { (event: JQueryEvent) =>
- val offsetX = event.pageX - boardCanvas.offset().left
- val offsetY = event.pageY - boardCanvas.offset().top
- val x = offsetX.toInt / SquareSizePx
- val y = offsetY.toInt / SquareSizePx
-
- if (inBounds(x, y))
- clickSquare(board(x)(y))
- }
-
- // Build the status bar
- val statusBar = jQuery("<p>")
- 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()
- }
-}