Skip to content

Instantly share code, notes, and snippets.

@Jacoby6000
Last active August 29, 2015 14:20
Show Gist options
  • Save Jacoby6000/d8bd64711c023a44b488 to your computer and use it in GitHub Desktop.
Save Jacoby6000/d8bd64711c023a44b488 to your computer and use it in GitHub Desktop.
import scala.annotation.tailrec
import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
import scala.util.Try
object Main extends App {
import scala.concurrent.ExecutionContext.Implicits.global
implicit val board = GameBoard(Vector(40,20))
var dir: Vector = Vector(1,0)
var quit: Boolean = false
@tailrec
def play(data: GameData)(implicit board: GameBoard): Boolean = {
// readInput()
println()
println()
println("Score: " + data.score)
val newSnake = data.snake.move(dir)
val boardData = newSnake.segments.map((_,'#')).toMap
board.render(boardData)
Try{Await.result(Future(readInput()), 300 millis)}
if(quit) false else play(data.copy(snake = newSnake))
}
def readInput() = {
java.lang.System.in.read().toChar match {
case 0 =>
case readValue =>
val newDir = readValue match {
case 'w' => Vector(0, 1)
case 'a' => Vector(-1, 0)
case 's' => Vector(0, -1)
case 'd' => Vector(1, 0)
case 'x' =>
quit = true
Vector(0, 0)
case _ => dir
}
if(newDir != Vector(dir.x* -1, dir.y* -1))
dir = newDir
}
}
play(GameData(Snake(List(Point(20,10), Point(21,10),Point(22,10),Point(23,10))),Point(5,5), 0))
}
case class Point(x: Int, y: Int) {
def move(vel: Vector, steps: Int = 1)(implicit gameBoard: GameBoard) = Point(
(x + vel.x * steps) % gameBoard.size.x,
(y + vel.y * steps * -1) % gameBoard.size.y // Invert X/Y movement
)
}
case class Vector(x: Int, y: Int)
case class GameData(snake: Snake, foodPosition: Point, score: Int)
case class Snake(segments: List[Point]){
def move(dir: Vector, steps: Int = 1)(implicit gameBoard: GameBoard): Snake = Snake(
segments.foldLeft((List.empty[Point],Option.empty[Point])){
(data, curPoint) => (data._1 :+ data._2.getOrElse(curPoint.move(dir)), Some(curPoint))
}._1
)
}
case class GameBoard(size: Vector) {
def render(boardData: Map[Point, Char]): Unit =
print((for (
y <- 0 to size.y;
x <- 0 to size.x + 1
)
yield {
val curPos = Point(x, y)
if (x == size.x + 1) '\n'
else if ((y == size.y && x == 0) || (y == size.y && x == size.x) || (y == 0 && x == 0)) '+'
else if (y == 0 && x == size.x) '+'
else if (y == 0 || y == size.y) '-'
else if (x == 0 || x == size.x) '|'
else boardData.getOrElse(curPos, ' ')
}).mkString)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment