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("\n"); } io::print("\n"); } } 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; } }