Instantly share code, notes, and snippets.

Embed
What would you like to do?
import scala.collection.mutable.HashMap
import java.lang.Math
class Vector(var x:Int, var y:Int) {
override def toString = {
"("+ x + "," + y + ")"
}
override def equals(that: Any): Boolean =
that.isInstanceOf[Vector] && {
val o = that.asInstanceOf[Vector]
o.x == x && o.y == y
}
override def hashCode = {
(x, y).hashCode()
}
def + (that: Vector): Vector = {
new Vector(that.x + x, that.y + y)
}
def - (that: Vector): Vector = {
new Vector(that.x - x, that.y - y)
}
}
class Cell(var state:Boolean) {
def step(previous: Cell, neighbors: List[Cell]) {
state = (previous.state, neighbors.count( b => b.state)) match {
case (true, 2) => true
case (true, 3) => true
case (false, 3) => true
case _ => false
}
}
override def toString = {
(if (state) "*" else ".")
}
}
class Board {
var min = new Vector(0,0)
var max = new Vector(0,0)
var field = new HashMap[Vector, Cell];
def cellFor(position:Vector): Cell ={
if (field.contains(position)) {
field(position)
} else {
new Cell(false)
}
}
def put(position:Vector, cell:Cell):Board = {
if (cell.state) {
field(position) = cell
expand_field(position)
}
this
}
def expand_field(position:Vector) {
if (position.x < min.x) min.x = position.x
if (position.y < min.y) min.y = position.y
if (position.x > max.x) max.x = position.x
if (position.y > max.y) max.y = position.y
}
def cut_field() {
var at = (min.x to max.x).map(x => (min.y to max.y).map(y => cellFor(new Vector(x,y)))).map(line => line.toList.count(c => c.state) > 0).indexOf(true)
if (at != -1) {
min.x = (min.x to max.x)(at)
}
at = (min.y to max.y).map(y => (min.x to max.x).map(x => cellFor(new Vector(x,y)))).map(line => line.toList.count(c => c.state) > 0).indexOf(true)
if (at != -1) {
min.y = (min.y to max.y)(at)
}
at = (min.x to max.x).map(x => (min.y to max.y).map(y => cellFor(new Vector(x,y)))).map(line => line.toList.count(c => c.state) > 0).lastIndexOf(true)
if (at != -1) {
max.x = (min.x to max.x)(at)
}
at = (min.y to max.y).map(y => (min.x to max.x).map(x => cellFor(new Vector(x,y)))).map(line => line.toList.count(c => c.state) > 0).lastIndexOf(true)
if (at != -1) {
max.y = (min.y to max.y)(at)
}
}
}
class Game {
var board = new Board;
var use_cut_field = false;
private var cycle = 0
def put(x:Int, y:Int) {
board.put(new Vector(x, y), new Cell(true))
}
def step {
var newboard = new Board;
cycle += 1
for(x <- board.min.x-1 to board.max.x+1) {
for(y <- board.min.y-1 to board.max.y+1) {
var position = new Vector(x,y)
var neighbors = List(new Cell(false))
for( diffx <- (-1 to 1) ) {
for( diffy <- (-1 to 1) ) {
if (!(diffx == 0 && diffy == 0)) {
neighbors = board.cellFor(position + new Vector(diffx, diffy)) :: neighbors
}
}
}
var newcell = new Cell(false)
newcell.step(board.cellFor(position), neighbors)
newboard.put(position, newcell)
}
}
board = newboard
}
override def toString = {
if (use_cut_field) board.cut_field
var buffer = ""
if (use_cut_field) buffer += (board.min + new Vector(-1,-1)) + "~" + (board.max + new Vector(1,1)) + "\n"
for(x <- board.min.x-1 to board.max.x+1) {
for(y <- board.min.y-1 to board.max.y+1) {
var position = new Vector(x,y)
buffer += board.cellFor(position)+" "
}
buffer += "\n"
}
buffer
}
}
object LifeGame {
def main(args: Array[String]) {
var i=0;
var game = new Game
for (arg <- args) {
if (arg == "use_cut_field") {
game.use_cut_field = true
}
if (arg == "glider") {
load(game, glider)
}
if (arg == "blinker") {
load(game, blinker)
}
if (arg == "glidergun") {
load(game, glidergun)
}
if (arg == "help") {
println("% scala LifeGame [glider|blinker|glidergun] (use_cut_field)")
exit
}
}
while(true) {
println(game)
game.step
Thread.sleep(80)
}
}
def load(game: Game, what: List[(Int, Int)]) {
for(pos <- what) {
game.put(pos._2, pos._1)
}
}
def glider = List((0,1),(1,2),(2,2),(2,1),(2,0))
def blinker = List((0,0),(1,0),(2,0))
def glidergun = List(
(-1,4),
(-1,5),
(0,4),
(0,5),
(9,4),
(9,5),
(9,6),
(10,3),
(10,7),
(11,2),
(11,8),
(12,2),
(12,8),
(13,5),
(14,3),
(14,7),
(15,4),
(15,5),
(15,6),
(16,5),
(19,2),
(19,3),
(19,4),
(20,2),
(20,3),
(20,4),
(21,1),
(21,5),
(23,0),
(23,1),
(23,5),
(23,6),
(33,2),
(33,3),
(34,2),
(34,3)
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment