about summary refs log blame commit diff stats
path: root/swift/life/Sources/main.swift
blob: 3bd47cd3071bbf9d189b21bec8ee21d0cd49f8ec (plain) (tree)
1
2
3
4

                 

                  










                                                        
                                             
                                                                  
                                                                 
                                                                                                         

                                                           
                                               
                                                         

                                 

                                                                       
                                                                 
                                                                                

                                            

                                                                                                




                                                         
                                                  

                                                                  
                                                                      
                                                                                 

                                                   
                                                                      
                                  

                                                       
                                 

                        

                         




                       
                                                 
                                     




                                                                                         
 
 
                                                                                     






                                        
                                                                                      




                                        
                                                                                     







                                       
                                                                                   






                                     
 
                                                                                         




                    









                                              
import Foundation

let rows: Int = 10
let cols: Int = 10

func printBoard(_ board: [[Int]]) {
    board.forEach { row in
        row.forEach { cell in
            print(cell == 1 ? "@" : ".", terminator: "")
        }
        print()
    }
    print("\n")
}

// Are these comments enough for a blog post?
func countLiveNeighbors(_ board: [[Int]], x: Int, y: Int) -> Int {
    // All of the possible directions to check for live neighbors
    let directions: [(Int, Int)] = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
    
    // Iterate over the directions and count live neighbors
    return directions.reduce(0) { count, dir in
        // Calculate the coordinates of the neighbor cell
        let newX: Int = x + dir.0
        let newY: Int = y + dir.1
        
        // Check if the neighbor cell is within the bounds of the board
        if newX >= 0 && newX < rows && newY >= 0 && newY < cols {
            // If the neighbor cell is within bounds, add its value to the count
            return count + board[newX][newY]
        }
        
        // If the neighbor cell is out of bounds, ignore it and continue with the next direction
        return count
    }
}

func nextGeneration(_ currentBoard: [[Int]]) -> [[Int]] {
    // Iterate over each cell in the current board
    return currentBoard.enumerated().map { (x: Int, row: [Int]) in
        return row.enumerated().map { (y: Int, cell: Int) in
            // Count the number of live neighbors for the current cell
            let liveNeighbors: Int = countLiveNeighbors(currentBoard, x: x, y: y)
            
            // Determine the next state of the cell
            if cell == 1 && (liveNeighbors < 2 || liveNeighbors > 3) {
                // Determine death
                return 0
            } else if cell == 0 && liveNeighbors == 3 {
                // Determine life
                return 1
            }
            
            // Do nothing
            return cell
        }
    }
}

func simulate(board: [[Int]], generations: Int) {
    var currentBoard: [[Int]] = board
    for _ in 0..<generations {
        printBoard(currentBoard)
        currentBoard = nextGeneration(currentBoard)
        sleep(1) // FIXME: figure out how to sleep for periods shorter than a full second
    }
}

var glider: [[Int]] = Array(repeating: Array(repeating: 0, count: cols), count: rows)
glider[1][2] = 1
glider[2][3] = 1
glider[3][1] = 1
glider[3][2] = 1
glider[3][3] = 1
simulate(board: glider, generations: 10)

var flasher: [[Int]] = Array(repeating: Array(repeating: 0, count: cols), count: rows)
flasher[4][5] = 1
flasher[5][5] = 1
flasher[6][5] = 1
simulate(board: flasher, generations: 4)

var beacon: [[Int]] = Array(repeating: Array(repeating: 0, count: cols), count: rows)
beacon[2][2] = 1
beacon[2][3] = 1
beacon[3][2] = 1
beacon[4][5] = 1
beacon[5][4] = 1
beacon[5][5] = 1
simulate(board: beacon, generations: 4)

var toad: [[Int]] = Array(repeating: Array(repeating: 0, count: cols), count: rows)
toad[3][4] = 1
toad[3][5] = 1
toad[3][6] = 1
toad[4][3] = 1
toad[4][4] = 1
toad[4][5] = 1
simulate(board: toad, generations: 5)

var rpentomino: [[Int]] = Array(repeating: Array(repeating: 0, count: cols), count: rows)
rpentomino[3][4] = 1
rpentomino[3][5] = 1
rpentomino[4][3] = 1
rpentomino[4][4] = 1
rpentomino[5][4] = 1
simulate(board: rpentomino, generations: 22)

func randomBoard() -> [[Int]] {
    return (0..<rows).map { _ in
        return (0..<cols).map { _ in
            return Int.random(in: 0...1)
        }
    }
}
simulate(board: randomBoard(), generations: 10)