-
Notifications
You must be signed in to change notification settings - Fork 179
/
Copy pathtictactoe.scala
32 lines (30 loc) · 1.07 KB
/
tictactoe.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
trait Piece
case object X extends Piece
case object O extends Piece
type Pieces = Vector[Option[Piece]]
case class Board(board: Pieces) {
require(board.size == 9, "board.size must be 9 but is" + board.size)
def checkPos(pos: Int) = require(pos>=0 && pos < 9, "pos must be inside[0,9[")
def isFree(pos: Int) = {
checkPos(pos)
!board(pos).isDefined
}
def put(pos: Int, piece: Piece): Board = {
checkPos(pos)
require(isFree(pos), s"pos $pos must be free")
Board(board.updated(pos, Some(piece)))
}
def row(i: Int): Pieces = board.drop(i * 3).take(3)
def col(i: Int): Pieces = (0 to 2).map(k => board(k*3 + i)).toVector
override def toString: String = {
val strings = board.map(p => if (!p.isDefined) "." else p.get.toString)
def maybeNewline(i: Int) = if (i % 3 == 2) "\n" else ""
val addNl = for (i <- 0 until strings.size) yield strings(i) + maybeNewline(i)
addNl.mkString
}
}
object Board {
def empty: Board = new Board(Vector.fill(9)(None))
def isAllSame(xs: Pieces, piece: Piece): Boolean =
xs.forall(_ == Some(piece))
}