Skip to content

Instantly share code, notes, and snippets.

@wrwills
Created October 2, 2018 14:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wrwills/9c0d87ae7b2153a292d89f68f08baf31 to your computer and use it in GitHub Desktop.
Save wrwills/9c0d87ae7b2153a292d89f68f08baf31 to your computer and use it in GitHub Desktop.
tictactoe
sealed trait TicTacToePlayer
case object X extends TicTacToePlayer
case object Y extends TicTacToePlayer
case class TicTacToeBoard(moves: List[(Int,TicTacToePlayer)]) {
val boardRange = 0 to 8
val players = List(X,Y)
lazy val movesMap = moves.toMap
def lastPlayer = moves.headOption.map( _._2)
def print = printBoard.foreach( println )
def printBoard = {
val t = boardRange.map(i => movesMap.get(i).map(_.toString).getOrElse("-"))
t.grouped(3).map(_.mkString)
}
def win(is: Seq[Int]): Option[TicTacToePlayer] = {
val played = is.flatMap(movesMap.get)
if (played.size == 3 && played.toSet.size == 1)
played.headOption
else
None
}
def winner = {
val rows = boardRange.grouped(3)
val columns = boardRange.take(3).map(x => List(0, 3, 6).map(_ + x))
val diags = List(List(0, 4, 8), List(2, 4, 6))
(rows ++ columns ++ diags).flatMap(win).toList.headOption
}
def move(column: Int, row: Int) = {
val player = lastPlayer.flatMap( player => players.filterNot( _ == player ).headOption).getOrElse(players.head)
val move = column + row * 3
if (movesMap.contains(move))
None
else
Some(this.copy( moves = (move,player) :: moves))
}
}
object TicTacToeBoard {
def apply(): TicTacToeBoard = TicTacToeBoard(List.empty)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment