Skip to content
Snippets Groups Projects
gol.fut 2.09 KiB
Newer Older
baptiste.coudray's avatar
baptiste.coudray committed
let count_neighbours [n] (board: [n][n]i8) : [n][n]i8 =
    let north = rotate (-1) board
    let south = rotate 1 board
    let east = map(rotate 1) board
    let west = map(rotate (-1)) board

    let north_east = map(rotate 1) north
    let north_west = map(rotate (-1)) north
    let south_east = map(rotate 1) south
    let south_west = map(rotate (-1)) south

    in map3 (\(nwr,nr,ner) (wr, br, er) (swr, sr, ser) ->
        map3 (\(nw,n,ne) (w, _, e) (sw, s, se) -> nw + n + ne + w + e + sw + s + se)
        (zip3 nwr nr ner) (zip3 wr br er) (zip3 swr sr ser))
    (zip3 north_west north north_east) (zip3 west board east) (zip3 south_west south south_east)

let augment_board [n][m] (chunk_board :[n][n]i8) (envelope_board: [4][m]i8): [m][m]i8 =
    tabulate_2d (m) (m) (\i j ->
                              -- North
                              if (i == 0) then envelope_board[0,j]
                              -- East
                              else if (j == m-1) then envelope_board[1,i]
                              -- South
                              else if (i == m-1) then envelope_board[2,j]
                              -- West
                              else if (j == 0) then envelope_board[3,i]
                              else chunk_board[i-1,j-1])


entry next_chunk_board [n][m] (chunk_board :[n][n]i8) (envelope_board: [4][m]i8) :[n][n]i8 =
    let augmented_board = augment_board chunk_board envelope_board
    let neighbours = count_neighbours augmented_board
    let next_board = map2 (\augmented_board_r neighbours_r ->
        map2(\cell nb_alive_cells ->
            if (cell == 1 && (nb_alive_cells == 2 || nb_alive_cells == 3)) || (cell == 0 && nb_alive_cells == 3)
            then 1
            else 0)
        augmented_board_r neighbours_r)
      augmented_board neighbours
    in next_board[1:n+1, 1:n+1] :> [n][n]i8

entry get_envelope [n] (chunk_board: [n][n]i8): [4][n]i8 =
    let north = chunk_board[0]
    let south = chunk_board[n-1]
    let tr_chunk_board = transpose chunk_board
    let east = tr_chunk_board[n-1]
    let west = tr_chunk_board[0]
    in [north, east, south, west]