Skip to content

Instantly share code, notes, and snippets.

@dirk
Created June 28, 2012 21:18
Show Gist options
  • Save dirk/3013974 to your computer and use it in GitHub Desktop.
Save dirk/3013974 to your computer and use it in GitHub Desktop.
Conway's game of life in Rust
use std;
use time;
import result::{ok, err};
import to_str::*;
// Count the number of live neighbors for a given cell.
// Neighbors are cells adjacent vertically, horizontally, or diagonally.
fn live_neighbors(board: [[bool]], row: int, column: int) -> int {
let mut count = 0;
let rows = vec::len(board) as int;
let cols = vec::len(board[0]) as int;
let spread = [-1, 0, 1];
for vec::each(spread) {|r|
for vec::each(spread) {|c|
let mut continue = true;
if r == 0 && c == 0 {
continue = false;
}
if (row + r) < 0 && cont {
continue = false;
}
if (row + r) > (rows - 1) && cont {
continue = false;
}
if (column + c) < 0 && cont {
continue = false;
}
if (column + c) > (cols - 1) && cont {
continue = false;
}
if continue && board[row + r][column + c] == true {
count += 1;
}
}
}
ret count;
}
// Run an iteration of the game over the given board and return the new board.
fn tick(old: [[bool]]) -> [[bool]] {
let mut n: [[bool]] = [];
let mut r: int = 0;
let mut c: int = 0;
while r < vec::len(old) as int {
c = 0;
let mut nr: [bool] = [];
while c < vec::len(old[r]) as int {
let mut state: bool = old[r][c]; // start out what it originally was
let orig_state = state;
let live = live_neighbors(old, r, c);
//let dead = dead_neighbors(old, r, c);
if orig_state == true { // Live cell
if live < 2 {
state = false;
};
if live == 2 || live == 3 {
state = true;
};
if live > 3 {
state = false
};
} else { // Dead cell
if live == 3 {
state = true;
}
};
vec::push(nr, state);
c += 1;
};
vec::push(n, nr);
r += 1;
};
ret n;
}
// Output an entire board.
fn print_board(board: [[bool]]) {
for vec::each(board) {|row|
for vec::each(row) {|cell|
if cell == true {
io::print("0");
} else {
io::print(" ");
};
};
io::print("\n");
};
}
fn clear_screen() {
io::print("\x1b[1J");
}
fn reset_cursor() {
io::print("\x1b[;H")
}
/*
fn sleep(amount: int) {
let start = time::get_time().sec;
while time::get_time().sec < (start + (amount as i64)) {
// pass
};
}
*/
fn time_as_float() -> f64 {
let {sec, nsec} = time::get_time();
let t = (sec as f64) + (nsec as f64) / ((1000 * 1000 * 1000) as f64);
ret t;
}
fn sleep_milliseconds(amount: int) {
let start = time_as_float();
while time_as_float() < (start + ((amount as f64) / (1000 as f64))) {
// pass
}
}
fn main(args: [str]) {
let length = vec::len(args);
let mut board: [[bool]] = [];
if length != 2 as uint {
io::println("usage: ./conway initial_data");
ret;
}
let str_data = alt io::read_whole_file_str(args[1]) {
ok(data) { data }
err(e) { fail e.to_str() }
};
// Parse the data file
let rows: [str] = str::lines_any(str::trim(str_data));
for vec::each(rows) {|row|
let mut rd: [bool] = [];
let chars: [char] = str::chars(row);
for vec::each(chars) {|c|
//io::println((*c).to_str());
let i = int::from_str(str::from_char(c));
vec::push(rd, alt option::get(i) {
1 { true }
_ { false }
});
};
vec::push(board, rd);
};
// Set up the screen with the initial board.
clear_screen();
reset_cursor();
print_board(board);
// Run the machine endlessly (Ctrl+C to interrupt)
while true {
board = tick(board);
// Move the cursor back to the origin and overwrite
reset_cursor();
print_board(board);
sleep_milliseconds(250);
};
}
0000000000000000000000000000000000000000000000000
0000000000000000000000000100000000000000000000000
0000000000000000000000010100000000000000000000000
0000000000000110000001100000000000011000000000000
0000000000001000100001100000000000011000000000000
0110000000010000010001100000000000000000000000000
0110000000010001011000010100000000000000000000000
0000000000010000010000000100000000000000000000000
0000000000001000100000000000000000000000000000000
0000000000000110000000000000000000000000000000000
0000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment