Permalink
Browse files

Complete basic exercise

  • Loading branch information...
algas committed Jun 23, 2014
1 parent 5065575 commit 25a24e4d62364bf2793621b9f5572567447d48f4
Showing with 144 additions and 30 deletions.
  1. +144 −30 src/main/scala/com/geishatokyo/tictactoe/MainThread.scala
@@ -4,52 +4,116 @@ import android.content.Context
import android.view.SurfaceHolder
import android.graphics.{Canvas, Paint, Rect, Path}
-class AbstractUI {
- private[this] var gameTurn: Int = 0
- private[this] var pointX: Int = 0
- private[this] var pointY: Int = 0
+case object Player {
+ case object O extends Player(0)
+ case object X extends Player(1)
+ val values = Array(O, X)
+}
+
+sealed abstract class Player(val code: Int) {
+ val name = toString
+}
+
+case class Point (x: Int, y: Int)
+
+case class Piece (player: Player, point: Point)
+
+class Board {
+ private[this] var pieces: List[Piece] = List.empty
+ var hasExited: Boolean = false
+
+ def nextPlayer: Player = {
+ if (pieces.length % 2 == 0) Player.O else Player.X
+ }
+
+ def currentPlayer: Player = {
+ if (pieces.length % 2 == 1) Player.O else Player.X
+ }
+
+ def add(p: Point): Unit = {
+ pieces = (new Piece(nextPlayer, p)) :: pieces
+ }
+
+ def add(x: Int, y: Int): Unit = {
+ add(new Point(x, y))
+ }
+
+ def points: List[Point] = {
+ pieces.map(_.point)
+ }
+
+ def isAddible(x: Int, y: Int): Boolean = {
+ !points.contains(new Point(x, y))
+ }
+
+ def length: Int = {
+ pieces.length
+ }
+
+ def getPieces: List[Piece] = {
+ pieces
+ }
+
+ def getPlayerPieces(p: Player): List[Piece] = {
+ pieces.filter(x => x.player.name == p.name)
+ }
+
+ def hasWon(): Boolean = {
+ hasWon(currentPlayer)
+ }
+
+ def hasWon(player: Player): Boolean = {
+ var ps: List[Point] = getPlayerPieces(player).map(_.point)
+ checkVertical(ps) || checkHorizontal(ps) || checkDiagonal(ps)
+ }
- def turn: Int = gameTurn
- def x: Int = pointX
- def y: Int = pointY
- def setX(x: Int) {
- pointX = x
+ def checkVertical(ps: List[Point]): Boolean = {
+ (for (i <- 0 until 3) yield ps.filter(p => p.x == i).length).toList.max == 3
}
- def setY(y: Int) {
- pointY = y
+
+ def checkHorizontal(ps: List[Point]): Boolean = {
+ (for (i <- 0 until 3) yield ps.filter(p => p.y == i).length).toList.max == 3
+ }
+
+ def checkDiagonal(ps: List[Point]): Boolean = {
+ (ps.filter(p => p.x == p.y).length == 3) || (ps.filter(p => p.x + p.y == 2).length == 3)
}
- def countUp() {
- gameTurn += 1
+
+ def exit: Unit = {
+ hasExited = true
+ }
+
+ def reset: Unit = {
+ hasExited = false
+ pieces = List.empty
}
}
+
class MainThread(holder: SurfaceHolder, context: Context) extends Thread {
val quantum = 100
- var ui: Option[AbstractUI] = None
- var pieces: List[(Int,Int)] = List.empty
+ var board: Board = new Board
- val bluishSilver = new Paint
- bluishSilver.setARGB(255, 255, 255, 255)
- val bluishGray = new Paint
- bluishGray.setARGB(255, 0, 0, 0)
+ val bluishWhite = new Paint
+ bluishWhite.setARGB(255, 255, 255, 255)
+ val bluishBlack = new Paint
+ bluishBlack.setARGB(255, 0, 0, 0)
var canvasWidth: Int = _
var canvasHeight: Int = _
override def run {
- ui = Some(new AbstractUI)
var isRunning: Boolean = true
while (isRunning) {
val t0 = System.currentTimeMillis
drawViews()
val t1 = System.currentTimeMillis
if (t1 - t0 < quantum) Thread.sleep(quantum - (t1 - t0))
- else ()
}
}
def drawViews() {
withCanvas { g =>
- g drawRect (0, 0, canvasWidth, canvasHeight, bluishGray)
+ g drawRect (0, 0, canvasWidth, canvasHeight, bluishBlack)
onPaint(g)
}
}
@@ -60,11 +124,26 @@ class MainThread(holder: SurfaceHolder, context: Context) extends Thread {
}
def addTouch(x: Int, y: Int){
+ touchTile(x, y)
+ touchReset(x, y)
+ }
+
+ def touchTile (x: Int, y: Int){
val dx = (x - 0) / 200
val dy = (y - 200) / 200
if ((0 <= dx && dx < 3) && (0 <= dy && dy < 3)) {
- pieces = (dx,dy) :: pieces
- ui.get.countUp()
+ if (!board.hasExited && board.isAddible(dx, dy)){
+ board.add(dx, dy)
+ if (board.hasWon) {
+ board.exit
+ }
+ }
+ }
+ }
+
+ def touchReset (x: Int, y: Int){
+ if ((200 <= x && x < 400) && (800 <= y && y < 900)) {
+ board.reset
}
}
@@ -77,17 +156,43 @@ class MainThread(holder: SurfaceHolder, context: Context) extends Thread {
}
}
- def drawTile(g: Canvas) {
+ def drawInfo(g: Canvas) {
val textPaint = new Paint
textPaint.setARGB(255, 255, 255, 255)
textPaint.setTextSize(48)
- g drawText ("OX GAME", 160, 100, textPaint)
- g drawText (ui.get.turn.toString, 200, 150, textPaint) // debugging
+ g drawText ("OX GAME", 200, 100, textPaint)
+ var text: String = ""
+ if (board.hasExited) {
+ board.currentPlayer match {
+ case Player.O => text = "Player O Win!"
+ case Player.X => text = "Player X Win!"
+ }
+ }
+ else if (board.length == 9) {
+ text = "Draw Game!"
+ }
+ else {
+ board.nextPlayer match {
+ case Player.O => text = "Turn of O"
+ case Player.X => text = "Turn of X"
+ }
+ }
+ g drawText (text, 200, 150, textPaint)
+ }
+
+ def drawTile(g: Canvas) {
for (j <- 0 until 3){
for (i <- 0 until 3) {
- g drawRect (i*200+10, 200+j*200+10, i*200+190, 200+j*200+190, bluishSilver)
+ g drawRect (i*200+10, 200+j*200+10, i*200+190, 200+j*200+190, bluishWhite)
}
}
+ val bluishGray = new Paint
+ bluishGray.setARGB(255, 128, 128, 128)
+ g drawRect (200, 800, 400, 900, bluishGray)
+ val textPaint = new Paint
+ textPaint.setARGB(255, 255, 255, 0)
+ textPaint.setTextSize(48)
+ g drawText ("RESET", 230, 870, textPaint)
}
def drawO(g: Canvas, dx: Int, dy: Int) {
@@ -118,10 +223,19 @@ class MainThread(holder: SurfaceHolder, context: Context) extends Thread {
}
}
+ def drawMark(g: Canvas, p: Piece) {
+ val player: Player = p.player;
+ player match {
+ case Player.O => drawO(g, p.point.x, p.point.y)
+ case Player.X => drawX(g, p.point.x, p.point.y)
+ }
+ }
+
def onPaint(g: Canvas) {
+ drawInfo(g)
drawTile(g)
- for (((x,y), i) <- pieces.reverse.zipWithIndex){
- drawMark(g, i, x, y)
+ for (p <- board.getPieces){
+ drawMark(g, p)
}
}

0 comments on commit 25a24e4

Please sign in to comment.