Skip to content

Instantly share code, notes, and snippets.

@hdp
Created February 9, 2011 18:35
Show Gist options
  • Save hdp/818980 to your computer and use it in GitHub Desktop.
Save hdp/818980 to your computer and use it in GitHub Desktop.
abstract class Cell()
case class Space() extends Cell {
override def toString() = " "
}
case class X() extends Cell {
override def toString() = "X"
}
case class O() extends Cell {
override def toString() = "O"
}
abstract class GameResult()
case class Continue() extends GameResult
case class Draw() extends GameResult
case class Win(c: Cell) extends GameResult
class Game() {
val state: Array[Cell] = Array.fill(9)(Space())
private var lastMove: Cell = Space()
private var lastResult: GameResult = Continue()
def moves(m: Array[(Int,Cell)]) = m.foreach(ic => move(ic._1, ic._2))
def move(i: Int, c: Cell) = {
assume( lastResult == Continue(), "game must not be over" )
assume( state(i) == Space(), "current cell must be empty" )
assume( c != Space(), "new cell must be nonempty" )
assume( c != lastMove, "must alternate moves" )
state(i) = c
lastMove = c
lastResult = result
lastResult
}
def winners() = {
val r = Array.range(0, 3)
Array(
(for { i <- r; j <- r } yield i * 3 + j).grouped(3).toArray,
(for { i <- r; j <- r } yield i + j * 3).grouped(3).toArray,
(for { i <- Array(0, 2) } yield Array(0 + i, 4, 8 - i))
).flatten
}
def result(): GameResult = {
for (w <- winners) {
w.map(i => state(i)) match {
case Array(x, y, z) if x != Space() && x == y && y == z => {
return Win(x)
}
case _ => ()
}
}
if (state.exists(x => x == Space()))
return Continue()
return Draw()
}
override def toString() = {
state.grouped(3).map(x => x.mkString("[", "", "]")).mkString("\n")
}
}
object xoxoxo {
def rows() = {
val g = new Game()
g.moves(Array(
(0, X()),
(4, O()),
(8, X()),
(2, O()),
(6, X()),
(3, O()),
(7, X())));
Console.println(g.toString)
Console.println(g.result.toString)
}
def cols() = {
val g = new Game()
g.moves(Array(
(0, X()),
(4, O()),
(8, X()),
(2, O()),
(6, X()),
(7, O()),
(3, X())));
Console.println(g.toString)
Console.println(g.result.toString)
}
def diag() = {
val g = new Game()
g.moves(Array(
(0, X()),
(2, O()),
(8, X()),
(1, O()),
(4, X())
));
Console.println(g.toString)
Console.println(g.result.toString)
}
def main(args: Array[String]) = {
rows
cols
diag
}
}
// vim: set ts=4 sw=4 et:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment