about summary refs log tree commit diff stats
path: root/linux/pack.subx
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-11-07 16:37:10 -0800
committerKartik K. Agaram <vc@akkartik.com>2021-11-07 16:37:10 -0800
commit3ca102f0152f23718b72b35207e9272daf7514c3 (patch)
tree6ce6e0cabb4eecd46dd2a47e69c2ec49054139e9 /linux/pack.subx
parentad2dd26ed49a5eb721773b376c3f28d1c8dcfcc9 (diff)
downloadmu-3ca102f0152f23718b72b35207e9272daf7514c3.tar.gz
tutorial: improve task 14 based on sejo's feedback
Diffstat (limited to 'linux/pack.subx')
0 files changed, 0 insertions, 0 deletions
99'>99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200







































































































































































































                                                                                                                                   
window = curses.stdscr()


-- animation-based app
window:nodelay(true)

function sleep(a)
    local sec = tonumber(os.clock() + a);
    while (os.clock() < sec) do
    end
end


-- grid data structure
lines, cols = window:getmaxyx()

grid = {}
for i=1,lines*4 do
  grid[i] = {}
  for j=1,cols*2 do
    grid[i][j] = 0
  end
end


-- grab a 4x2 chunk of grid
function grid_char(line, col)
  result = {}
  for l, row in ipairs({unpack(grid, (line-1)*4+1, line*4)}) do
    result[l] = {unpack(row, (col-1)*2+1, col*2)}
  end
  return result
end

function print_grid_char(window, x)
  result = {}
  for l, row in ipairs(x) do
    for c, val in ipairs(row) do
      window:mvaddstr(l, c, val)
    end
  end
  return result
end

-- testing for grid_char
--? grid = {
--?         {1, 2, 3, 4},
--?         {5, 6, 7, 8},
--?         {9, 10, 11, 12},
--?         {13, 14, 15, 16},
--?       }
--? for l, row in ipairs(grid_char(1, 1)) do
--?   print(l, row)
--?   for c, val in ipairs(row) do
--?     print(l, c, val)
--?   end
--? end


-- look up the braille pattern corresponding to a 4x2 chunk of grid
-- https://en.wikipedia.org/wiki/Braille_Patterns
-- not obviously programmatic because Unicode added 4x2 after 3x2
glyph = {
  0x2800, 0x2801, 0x2802, 0x2803, 0x2804, 0x2805, 0x2806, 0x2807,   0x2840, 0x2841, 0x2842, 0x2843, 0x2844, 0x2845, 0x2846, 0x2847,
  0x2808, 0x2809, 0x280a, 0x280b, 0x280c, 0x280d, 0x280e, 0x280f,   0x2848, 0x2849, 0x284a, 0x284b, 0x284c, 0x284d, 0x284e, 0x284f,
  0x2810, 0x2811, 0x2812, 0x2813, 0x2814, 0x2815, 0x2816, 0x2817,   0x2850, 0x2851, 0x2852, 0x2853, 0x2854, 0x2855, 0x2856, 0x2857,
  0x2818, 0x2819, 0x281a, 0x281b, 0x281c, 0x281d, 0x281e, 0x281f,   0x2858, 0x2859, 0x285a, 0x285b, 0x285c, 0x285d, 0x285e, 0x285f,
  0x2820, 0x2821, 0x2822, 0x2823, 0x2824, 0x2825, 0x2826, 0x2827,   0x2860, 0x2861, 0x2862, 0x2863, 0x2864, 0x2865, 0x2866, 0x2867,
  0x2828, 0x2829, 0x282a, 0x282b, 0x282c, 0x282d, 0x282e, 0x282f,   0x2868, 0x2869, 0x286a, 0x286b, 0x286c, 0x286d, 0x286e, 0x286f,
  0x2830, 0x2831, 0x2832, 0x2833, 0x2834, 0x2835, 0x2836, 0x2837,   0x2870, 0x2871, 0x2872, 0x2873, 0x2874, 0x2875, 0x2876, 0x2877,
  0x2838, 0x2839, 0x283a, 0x283b, 0x283c, 0x283d, 0x283e, 0x283f,   0x2878, 0x2879, 0x287a, 0x287b, 0x287c, 0x287d, 0x287e, 0x287f,

  0x2880, 0x2881, 0x2882, 0x2883, 0x2884, 0x2885, 0x2886, 0x2887,   0x28c0, 0x28c1, 0x28c2, 0x28c3, 0x28c4, 0x28c5, 0x28c6, 0x28c7,
  0x2888, 0x2889, 0x288a, 0x288b, 0x288c, 0x288d, 0x288e, 0x288f,   0x28c8, 0x28c9, 0x28ca, 0x28cb, 0x28cc, 0x28cd, 0x28ce, 0x28cf,
  0x2890, 0x2891, 0x2892, 0x2893, 0x2894, 0x2895, 0x2896, 0x2897,   0x28d0, 0x28d1, 0x28d2, 0x28d3, 0x28d4, 0x28d5, 0x28d6, 0x28d7,
  0x2898, 0x2899, 0x289a, 0x289b, 0x289c, 0x289d, 0x289e, 0x289f,   0x28d8, 0x28d9, 0x28da, 0x28db, 0x28dc, 0x28dd, 0x28de, 0x28df,
  0x28a0, 0x28a1, 0x28a2, 0x28a3, 0x28a4, 0x28a5, 0x28a6, 0x28a7,   0x28e0, 0x28e1, 0x28e2, 0x28e3, 0x28e4, 0x28e5, 0x28e6, 0x28e7,
  0x28a8, 0x28a9, 0x28aa, 0x28ab, 0x28ac, 0x28ad, 0x28ae, 0x28af,   0x28e8, 0x28e9, 0x28ea, 0x28eb, 0x28ec, 0x28ed, 0x28ee, 0x28ef,
  0x28b0, 0x28b1, 0x28b2, 0x28b3, 0x28b4, 0x28b5, 0x28b6, 0x28b7,   0x28f0, 0x28f1, 0x28f2, 0x28f3, 0x28f4, 0x28f5, 0x28f6, 0x28f7,
  0x28b8, 0x28b9, 0x28ba, 0x28bb, 0x28bc, 0x28bd, 0x28be, 0x28bf,   0x28f8, 0x28f9, 0x28fa, 0x28fb, 0x28fc, 0x28fd, 0x28fe, 0x28ff,
}

-- https://stackoverflow.com/questions/7983574/how-to-write-a-unicode-symbol-in-lua
do
  local bytemarkers = { {0x7FF,192}, {0xFFFF,224}, {0x1FFFFF,240} }
  function utf8(decimal)
    if decimal<128 then return string.char(decimal) end
    local charbytes = {}
    for bytes,vals in ipairs(bytemarkers) do
      if decimal<=vals[1] then
        for b=bytes+1,2,-1 do
          local mod = decimal%64
          decimal = (decimal-mod)/64
          charbytes[b] = string.char(128+mod)
        end
        charbytes[1] = string.char(vals[2]+decimal)
        break
      end
    end
    return table.concat(charbytes)
  end
end

-- testing for glyphs
--? for _, val in ipairs(glyph) do
--?   window:mvaddstr(10, 10, utf8(val))
--?   window:mvaddstr(10, 20, " ")
--?   curses.getch()  -- just check for menu keys
--?   sleep(0.1)
--? end


-- convert a chunk of grid into a number
function grid_char_to_glyph_index(g)
  return g[1][1]    + g[2][1]*2  + g[3][1]*4  + g[4][1]*8 +
         g[1][2]*16 + g[2][2]*32 + g[3][2]*64 + g[4][2]*128 +
         1  -- 1-indexing
end


function render(window)
  window:clear()
  for line=1,lines do
    for col=1,cols do
      window:addstr(utf8(glyph[grid_char_to_glyph_index(grid_char(line, col))]))
    end
  end
  curses.refresh()
end

-- test single iteration of render
--? grid[1][1] = 1
--? grid[2][1] = 1
--? print_grid_char(window, grid_char(1, 1))
--? window:mvaddstr(10, 10, grid_char_to_glyph_index(grid_char(1, 1)))
--? window:mvaddstr(10, 20, string.format("%x", glyph[grid_char_to_glyph_index(grid_char(1, 1))]))
--? window:mvaddstr(10, 30, utf8(glyph[grid_char_to_glyph_index(grid_char(1, 1))]))
--? curses.getch()

-- test render
--? grid[10][11] = 1
--? grid[10][12] = 1
--? grid[10][13] = 1
--? 
--? while true do
--?   render(window)
--?   curses.getch()  -- just check for menu keys
--?   sleep(0.1)
--? end

-- step
function state(line, col)
  if line < 1 or line > table.getn(grid) or col < 1 or col > table.getn(grid[1]) then
    return 0
  end
  return grid[line][col]
end

function num_live_neighbors(line, col)
  return state(line-1, col-1) + state(line-1, col) + state(line-1, col+1) +
         state(line,   col-1) +                      state(line,   col+1) +
         state(line+1, col-1) + state(line+1, col) + state(line+1, col+1)
end

--? grid[10][11] = 1
--? grid[10][12] = 1
--? grid[10][13] = 1
--? window:mvaddstr(10, 10, num_live_neighbors(10, 12))
--? curses.getch()

function step()
  local new_grid = {}
  for line=1,table.getn(grid) do
    new_grid[line] = {}
    for col=1,table.getn(grid[1]) do
      local n = num_live_neighbors(line, col)
      if n == 3 then
        new_grid[line][col] = 1
      elseif n == 2 then
        new_grid[line][col] = grid[line][col]
      else
        new_grid[line][col] = 0
      end
    end
  end
  grid = new_grid
end

grid[83][172] = 1
grid[83][173] = 1
grid[84][173] = 1
grid[84][174] = 1
grid[85][173] = 1

while true do
  render(window)
  curses.getch()  -- just check for menu keys
--?   sleep(0.1)
  step()
end