diff --git a/assignments/final_project.rb b/assignments/final_project.rb index a621230..a3a332a 100644 --- a/assignments/final_project.rb +++ b/assignments/final_project.rb @@ -3,7 +3,7 @@ # ======================================================================================== # The Game of Life is a simplified model of evolution and natural selection -# invented by the mathematician James Conway. +# invented by the mathematician John Horton Conway. # http://en.wikipedia.org/wiki/Conway's_Game_of_Life @@ -59,17 +59,147 @@ module FinalProject class GameOfLife + class Board + attr_accessor :board_array + attr_reader :size + def initialize(size) + @board_array = [] + @size = size + size.times do + @board_array << Array.new(size, 0) + end + end + def onNext?(row, col) + # returns true if cell at row,col has 3 live neighbors + # returns true if cell is live and has 2 live neighbors + # returns false for anything else + sum_of_above_row = self.board_array[row - 1][col - 1] + self.board_array[row - 1][col] + self.board_array[row - 1][(col == size - 1) ? 0 : (col + 1)] + sum_of_sides = @board_array[row][col - 1] + @board_array[row][(col == size - 1) ? 0 : (col + 1)] + sum_of_below_row = @board_array[(row == size - 1) ? 0 : (row + 1)][col - 1] + @board_array[(row == size - 1) ? 0 : (row + 1)][col] + @board_array[(row == size - 1) ? 0 : (row + 1)][(col == size - 1) ? 0 : (col + 1)] + sum_of_neighbors = sum_of_above_row + sum_of_sides + sum_of_below_row + sum_of_neighbors == 3 || (sum_of_neighbors == 2 && @board_array[row][col] == 1) + end + end # class Board + def initialize(size) # randomly initialize the board + @size = size + @board = Board.new size + @board.board_array = @board.board_array.map do |row| + row = row.map do |cell| + cell = rand(2) + end + end + end + def size + @size + end + def boardArray + @board.board_array + end + + def saveBoard(filename = "savedboard.txt", board = @board) + # save board to text file + output = File.open(filename, "w+") + @board.board_array.each do |row| + arr_row_string = row.map {|cell| cell.to_s} + row_string = arr_row_string.join + output.puts row_string + end + output.close + end + def loadBoard(filename = "savedboard.txt") + # load board from text file + input = File.open(".\\" + filename, "r") + new_board_array = [] + input.each_line do |line| + str_row = line.chop.split "" # removing newline + row = str_row.map {|cell| cell.to_i} + new_board_array << row + end + input.close + @size = new_board_array.length + @board = Board.new @size + @board.board_array = new_board_array end - def evolve + def evolve(board = @board) # apply rules to each cell and generate new state + # create new empty board + new_board = Board.new board.size + # for each cell, if it's off, grow? if it's on, live? + (0..(board.size - 1)).each do |row| + (0..(board.size - 1)).each do |col| + new_board.board_array[row][col] = board.onNext?(row, col) ? 1 : 0 + end + end + board.board_array = new_board.board_array end - def render + def render(board = @board) # render the current state of the board + board.board_array.each do |row| + row.each do |cell| + print cell + end + print "\n" + end end - def run(num_generations) + def run(num_generations, board = @board) # evolve and render for num_generations + num_generations.times do + evolve board + render board + end end + + end # class GameOfLife +end # module FinalProject + +# Tests +require 'minitest/autorun' + +class TestFinalProject < Minitest::Test + + def test_board_initialize_size + (1..100).each do |x| + game = FinalProject::GameOfLife.new x + refute_nil game + assert_equal x, game.size + end + end + + def test_save_load + # initialize random board + game = FinalProject::GameOfLife.new 50 + test_ary = game.boardArray + game.saveBoard("test_save_load.txt") + game.loadBoard("test_save_load.txt") + # verify loaded board equals saved board + assert game.boardArray == test_ary + end + +# def test_render +# end + + def test_evolve + game = FinalProject::GameOfLife.new 50 + game.saveBoard "test_evolve.txt" + game2 = FinalProject::GameOfLife.new 50 + game2.loadBoard "test_evolve.txt" + + game.run(5) + (1..5).each do + game2.evolve + end + assert_equal game.boardArray, game2.boardArray + end + + def test_evolve2 + game = FinalProject::GameOfLife.new 10 + game2 = game + game.loadBoard("test_evolve2.txt") + game.evolve + game2.loadBoard("test_evolve2_correct.txt") + assert_equal game.boardArray, game2.boardArray end -end + +end # TestFinalProject < Minitest::Test \ No newline at end of file diff --git a/assignments/test_evolve.txt b/assignments/test_evolve.txt new file mode 100644 index 0000000..f72a735 --- /dev/null +++ b/assignments/test_evolve.txt @@ -0,0 +1,50 @@ +10000000010101010101010110110110000000010001111100 +10101000101000111000011000011111111111000001011000 +10100101111000110011111011011110010110101001000010 +00101001101011011101101100011000010011100101010100 +11100111001111011110011001101111011011110111001010 +01101100100011100111110111111101111111100111011010 +11111010010111111010111100001011100110101110001001 +00010010001010110000101001100000111000101011001100 +01000010111100101101110010110110111000001011010010 +10110011110111100011011111010100100010000110100011 +01110001101110001101111101111001011101011110001010 +00110000100100011001001101001110000100011110001110 +11100111011101000100100110100010000011011110101110 +00001111111010101010011010101001110110110101000010 +00010010100010111011111000010000010010010111000010 +00111100111110110010100001010111101010010000111000 +00100101001100011000001010010011101100011010100110 +11110010010110000111100100110001000011011111100110 +11111100001011100111100000000010110011011100101101 +00101101111001000111011001100111000001111100000011 +00001011001010101110110110111011111100000101101010 +11111110010110111111000111101001011011000111011001 +01001010001111001100101001100111010011001111111010 +10110110100111111111111011001010110110010000001111 +00011001001001011000100100000000110011010001101110 +01010010111010100110010111011111100111001000001000 +01100101001010111111010010001000100011011010000000 +10001110001010010111100011101010001100101011100011 +01101111001100001101100111000001000010001000100100 +11100000001000001100111001100101001010001001100111 +01000100010110111110111111101010010100100001111011 +01011000101111001000110100111001001100000100100111 +01010101011000101101111000111111101101100001111110 +11010001111100100001101101111001001110000101111010 +10001011011001111011111000011110000111101010101101 +00000001000101011111000111001111111000010000011001 +01100011110010000110010001010101110011000011111010 +11111110111100000111100000111001011101001110000100 +01111110010111011000100111011111010011000110110011 +00010110000000111110010100010011000000101100001001 +11100010100100100100110000100110001010001100100111 +00010010001010010011010000100001100111000010101100 +11100111101001010001101001100111000011001001110100 +11100001110111000001000011011000001000001000110101 +11111101000010000010001000001101010001110110111001 +00011110010001001011001001110110010100110111010000 +10011110111000000011101011001010101110000010101001 +01001110011001010010011010101001001000111111011001 +01101011011000000111111110101001100110010001001000 +01101101111001001000011001011010100010100111100110 diff --git a/assignments/test_evolve2.txt b/assignments/test_evolve2.txt new file mode 100644 index 0000000..85ed70e --- /dev/null +++ b/assignments/test_evolve2.txt @@ -0,0 +1,10 @@ +1100000001 +0000000000 +0000000000 +0000010000 +0000010000 +0000010000 +0000000000 +0000000000 +0000000000 +0000000000 diff --git a/assignments/test_evolve2_correct.txt b/assignments/test_evolve2_correct.txt new file mode 100644 index 0000000..191e89b --- /dev/null +++ b/assignments/test_evolve2_correct.txt @@ -0,0 +1,10 @@ +1000000000 +1000000000 +0000000000 +0000000000 +0000111000 +0000000000 +0000000000 +0000000000 +0000000000 +1000000000 diff --git a/assignments/test_save_load.txt b/assignments/test_save_load.txt new file mode 100644 index 0000000..d351acc --- /dev/null +++ b/assignments/test_save_load.txt @@ -0,0 +1,50 @@ +01001001110010010011101101111110001011011101110111 +01111110100000111011111010000111001101101101110001 +10000111001000011100110001001011010101000100001001 +00011110101101111010011011110111101011101100100110 +00100011000110100100111111000000100010010000001010 +00101010010011101000101111010101011101111101011110 +01000000011000110001100110111010110010110111101101 +01110011000000000000110000110011111100001100000010 +11011111000010110101000101001001001111110000011111 +11010101100111001110110111101001001101010110011000 +01010101110011111101000010111101110001101001000101 +10100110101000100011001010001101000001110001100100 +10011001100010000011010101011000100010111011110101 +11110101011101001101001001101100000011011100011110 +10000001101010001011110010100101110001001110111100 +01111111001111111010110110110011011000111001111010 +10101001101110101010000011000001110001111000000101 +10000000100101001111101001111110100011110000111001 +11111011110101001000000001100101010000001110000100 +01100110111110001111011011111001101100111011111011 +00110110101011101101011110000110100101001111011110 +00001011011000000111011101100110000000100111001010 +01111101111011001110100111000101010000101100111111 +10111100001101110011111111101000110011100100110001 +00001111100101011111100010011100100000011011111000 +00010100111000001110010010110011100111010100011111 +00110010000100110011111110101000011011011011100000 +00000000111001110011001011110000101010011011101111 +00011101110000011110110001011111111011000001010010 +11011110111000001000100101110001110100101011100111 +01101001000101100010000000101011001111101001010100 +00000101001110111101100101111011100000100010010100 +11001000100001000000111110111000010001100011011011 +11101011010011100011011110010000001110010111111110 +00010101001010110010100011100000111101111010001000 +10110111111101101010100001100110110101000111011101 +11100011001101000001011010010011000000110101010001 +10111111100100001111101100010100110100100101111000 +10110000100100101100000000100101010111111111101101 +10000100101101000100110000001111100010100100111010 +01000101101110001001011111111001110000111100100110 +00011000001000001110001110001010100010101000100100 +10110011110100001010111010010000001010011010111111 +10000001101111100111010101111101110110000011111000 +00100100100111100110101100101101101110101101100011 +11000101001000010101001000001000101010011011010101 +11111101100001010111000011001000111101010000000001 +11100100001011110000001110111001000100111000001010 +00110111001001010101100101000001111000001000110101 +11000101110110011111101010011110101000001011101001