struct Point {

x : int ,

y : int

}

impl Point {

fn neighbors ( ) - > ~ [ Point ] {

return ~ [ Point { x : self. x - 1 , y : self. y - 1 } ,

Point { x : self. x , y : self. y - 1 } ,

Point { x : self. x + 1 , y : self. y - 1 } ,

Point { x : self. x + 1 , y : self. y } ,

Point { x : self. x + 1 , y : self. y + 1 } ,

Point { x : self. x , y : self. y + 1 } ,

Point { x : self. x - 1 , y : self. y + 1 } ,

Point { x : self. x - 1 , y : self. y } ] ;

}

}

struct LifeMap {

width : int ,

height : int ,

data : ~ [ mut bool ]

}

fn LifeMap ( width : int , height : int ) - > ~LifeMap {

return ~LifeMap {

width : width,

height : height,

data : vec :: to_mut ( vec :: from_elem ( ( width * height ) as uint, false ) )

} ;

}

impl LifeMap {

fn get ( p : & Point ) - > bool {

let wx = ( p. x + self. width ) % self. width ;

let wy = ( p. y + self. height ) % self. height ;

return self. data [ ( wy * self. width ) + wx ] ;

}

fn set ( p : & Point, v : bool ) {

let wx = ( p. x + self. width ) % self. width ;

let wy = ( p. y + self. height ) % self. height ;

self. data [ ( wy * self. width ) + wx ] = v ;

}

fn live_neighbors ( p : & Point ) - > int {

let mut count = 0 ;

for vec :: each ( p. neighbors ( ) ) | n | {

if self. get ( n ) {

count + = 1 ;

}

}

return count ;

}

fn survives ( p : & Point ) - > bool {

let n = self. live_neighbors ( p ) ;

if self. get ( p ) {

match n {

2 | 3 => true ,

_ => false

}

} else {

match n {

3 => true ,

_ => false

}

}

}

fn render ( ) {

for int :: range ( 0 , self. height ) | y | {

for int :: range ( 0 , self. width ) | x | {

match self. get ( & Point { x : x, y : y } ) {

true => io :: print ( "*" ) ,

false => io :: print ( "-" )

}

}

io :: print ( "

" ) ;

}

io :: print ( "

" ) ;

}

}

fn evolve ( curr : & LifeMap, next : & LifeMap ) {

for int :: range ( 0 , curr. height ) | y | {

for int :: range ( 0 , curr. width ) | x | {

let p = Point { x : x, y : y } ;

match curr. survives ( & p ) {

true => next. set ( & p, true ) ,

false => next. set ( & p, false )

}

}

}

}

fn main ( ) {

let mut curr = LifeMap ( 4 , 4 ) ;

let mut next = LifeMap ( 4 , 4 ) ;

curr. set ( & Point { x : 1 , y : 1 } , true ) ;

curr. set ( & Point { x : 2 , y : 1 } , true ) ;

curr. set ( & Point { x : 3 , y : 1 } , true ) ;

for 4 . times {

curr. render ( ) ;

evolve ( curr, next ) ;

curr < - > next ;

}