mutable struct GameOfLife board::Array{Bool, 2} step::Integer maxSteps::Integer GameOfLife() = new(fill(false, (16, 16)), 0, 50) GameOfLife(b::Array{Bool, 2}; step = 0, maxSteps = 50) = new(b, step, maxSteps) end function Base.show(io::IO, b::GameOfLife) res = String[] rows, cols = size(b.board) for i in 1:rows push!(res, join((v -> v? '#' : ' ').(b.board[i, :]))) end print(io, "\u2502", join(res, "\u2502\n\u2502"), "\u2502") end Base.start(iter::GameOfLife) = iter.step Base.done(iter::GameOfLife, state) = iter.maxSteps <= iter.step behaviours = ( (x) -> false, (x) -> x, (x) -> true, (x) -> false ) function Base.next(iter::GameOfLife, state) iter.step += 1 if state == 0 return iter, iter.step end rows, cols = size(iter.board) newboard = fill(false, (rows, cols)) for x in 1:rows, y in 1:cols neighbors = sum(iter.board[ [x, x == 1 ? rows : x - 1, x == rows ? 1 : x + 1], [y, y == 1 ? cols : y - 1, y == cols ? 1 : y + 1] ]) - iter.board[x,y] newboard[x,y] = behaviours[clamp(neighbors, 1, 4)](iter.board[x,y]) end iter.board = newboard return iter, iter.step end #board = reshape([rand(false:true) for i in 1:16], (4, 4)) board = fill(false, (8, 16)) # Glider # # # # # ### board[2, 3] = true board[3, 4] = true board[4, 2:4] = true g = GameOfLife(board, maxSteps = 100) printborder(g, i) = println(done(g, i) ? "\u2514" : (i.step), "\u2500"^(done(g, i) ? size(i.board, 2) : size(i.board, 2) + 1 - length("$(i.step)")), done(g, i) ? "\u2518" : "\u2524") println("Game of Life: $(g.maxSteps) cycles!") println("\u250c", ^("\u2500", size(g.board, 2)) ,"\u2510") for i in g println(i) printborder(g, i) end