Created
February 28, 2017 21:41
-
-
Save xianny/40a79c1210ca3ab7fbaa8731d90ec88d to your computer and use it in GitHub Desktop.
General purpose board for grid-based board games
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.xianny.gameutils | |
/* | |
1 2 3 | |
1 (1,1) (2,1) (3,1) | |
2 (1,2) (2,2) (3,2) | |
3 (1,3) (2,3) (3,3) | |
*/ | |
// object BoardTest { | |
// def main(args: Array[String]) = { | |
// val b = new Board[Token](5, Map()) | |
// CLI.print(b) | |
// val next = b.add(X, Position(5,1)) | |
// next.map(CLI.print) | |
// val nextP = CLI.read | |
// next.getOrElse(b).add(X, nextP).map(CLI.print) | |
// } | |
// } | |
trait Token | |
case object X extends Token | |
case object O extends Token | |
case class Position(x: Int, y: Int) | |
case class Board[A](size: Int, places: Map[Position, A]) { | |
def add(token: A, p: Position): Option[Board[A]] = | |
if (isLegal(p)) { | |
val newPlaces = places + ((p, token)) | |
Some(Board(size, newPlaces)) | |
} else None | |
def remove(p: Position) = { | |
val newPlaces = places - p | |
Board(size, newPlaces) | |
} | |
// 1-indexed co-ordinate system | |
def isLegal(p: Position): Boolean = isLegal(p.x) && isLegal(p.y) | |
def isLegal(x: Int): Boolean = x > 0 && x <= size | |
} | |
trait IO[A] { | |
def print(b: Board[A]): Unit | |
def read: Position | |
} | |
case object CLI extends IO[Token] { | |
def print(b: Board[Token]): Unit = { | |
val _rows = (1 to b.size) map { y => | |
val _rowValues = for ( | |
x <- 1 to b.size; | |
p = Position(x, y); | |
token = b.places.get(p).getOrElse("_")) yield token | |
_rowValues.mkString(s"$y | "," | ", " |") | |
} | |
val _colHeaders = (1 to b.size).map(_.toString).mkString(" | ", " | ", " |") | |
val rowSeparator = List.fill(b.size)("===").mkString("==|","|","|") | |
println(_colHeaders) | |
_rows.foreach { r => | |
println(rowSeparator) | |
println(r) | |
} | |
println(rowSeparator) | |
} | |
def read: Position = { | |
import scala.util.Try | |
val xy = readLine("Enter coordinate for next play: ") | |
xy.toList.flatMap(x => Try(x.asDigit).toOption) match { | |
case (x: Int) :: (y: Int) :: Nil => Position(x, y) | |
case _ => | |
println("Invalid input") | |
read | |
} | |
} | |
} | |
// BoardTest.main(args) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment