diff --git a/packages/index.json b/packages/index.json index cedf7d0..e92ac64 100644 --- a/packages/index.json +++ b/packages/index.json @@ -6,7 +6,7 @@ "trapos-net": "0.3.0", "trapos-ui": "0.2.2", "trapos-ai": "0.6.4", - "trapos-sandbox": "0.1.3", + "trapos-sandbox": "0.1.4", "trapos": "0.8.6" } } diff --git a/packages/trapos-sandbox/ccpm.json b/packages/trapos-sandbox/ccpm.json index 57ee18e..7c58e14 100644 --- a/packages/trapos-sandbox/ccpm.json +++ b/packages/trapos-sandbox/ccpm.json @@ -1,6 +1,6 @@ { "name": "trapos-sandbox", - "version": "0.1.3", + "version": "0.1.4", "description": "TrapOS sandbox programs for ccpm experiments and Lua learning", "dependencies": ["trapos-core"], "files": [ diff --git a/programs/creeper.lua b/programs/creeper.lua index f431840..22e8753 100644 --- a/programs/creeper.lua +++ b/programs/creeper.lua @@ -3,30 +3,97 @@ local createVersion = require('/apis/libversion'); local args = table.pack(...); local FACE = { - '0000000000000000', - '0000000000000000', - '0011110000111100', - '0011110000111100', - '0011110000111100', - '0011110000111100', - '0000001111000000', - '0000001111000000', - '0000111111110000', - '0000111111110000', - '0000111111110000', - '0000111111110000', - '0000110000110000', - '0000110000110000', - '0000110000110000', - '0000000000000000', + 'LlGgLlGg', + 'lGGllGGL', + 'GXXggXXG', + 'gXXGGXXg', + 'LGGXXGGl', + 'gGXXXXGg', + 'LGXggXGL', + 'gGGLLGGg', }; +local THEMES = { + vanilla = { + title = 'Creeper', + background = colors.black, + text = colors.white, + palette = { + G = colors.green, + g = colors.lime, + L = colors.lightGray, + l = colors.gray, + X = colors.black, + }, + }, + charged = { + title = 'Charged Creeper', + background = colors.black, + text = colors.white, + palette = { + G = colors.blue, + g = colors.cyan, + L = colors.lightBlue, + l = colors.white, + X = colors.black, + }, + }, + magma = { + title = 'Magma Creeper', + background = colors.black, + text = colors.orange, + palette = { + G = colors.red, + g = colors.orange, + L = colors.yellow, + l = colors.brown, + X = colors.black, + }, + }, + ocean = { + title = 'Ocean Creeper', + background = colors.black, + text = colors.lightBlue, + palette = { + G = colors.blue, + g = colors.lightBlue, + L = colors.cyan, + l = colors.blue, + X = colors.black, + }, + }, + sand = { + title = 'Sand Creeper', + background = colors.black, + text = colors.yellow, + palette = { + G = colors.yellow, + g = colors.orange, + L = colors.white, + l = colors.lightGray, + X = colors.brown, + }, + }, +}; + +local THEME_NAMES = { 'vanilla', 'charged', 'magma', 'ocean', 'sand' }; + local function printUsage() print('creeper usage:'); print(); print(' creeper'); + print(' creeper '); + print(' creeper --theme '); + print(' creeper --random'); print(' creeper --version'); print(' creeper --help'); + print(); + print('themes: vanilla, charged, magma, ocean, sand'); + print(); + print('examples:'); + print(' creeper charged'); + print(' creeper --theme sand'); + print(' creeper --random'); end local function drawRun(x, y, len, color) @@ -35,21 +102,76 @@ local function drawRun(x, y, len, color) term.write(string.rep(' ', len)); end -local function drawCreeper() - local width, height = term.getSize(); - local pixelW = math.max(1, math.floor(width / 20)); - local pixelH = math.max(1, math.floor(height / 18)); +local function themeNamesText() + return table.concat(THEME_NAMES, ', '); +end - if pixelW > 3 then pixelW = 3; end - if pixelH > 2 then pixelH = 2; end +local function parseArgs(argv) + local selectedTheme = 'vanilla'; + local selectedExplicitly = false; + local randomTheme = false; + local index = 1; + + while index <= argv.n do + local arg = argv[index]; + + if arg == '--random' or arg == '-random' then + if selectedExplicitly then + return nil, '--random cannot be combined with a theme'; + end + randomTheme = true; + elseif arg == '--theme' or arg == '-theme' then + if randomTheme or selectedExplicitly then + return nil, arg .. ' cannot be combined with another theme option'; + end + index = index + 1; + selectedTheme = argv[index]; + if selectedTheme == nil then + return nil, 'missing theme after ' .. arg; + end + selectedExplicitly = true; + elseif THEMES[arg] ~= nil then + if randomTheme or selectedExplicitly then + return nil, arg .. ' cannot be combined with another theme option'; + end + selectedTheme = arg; + selectedExplicitly = true; + else + return nil, 'unknown option or theme: ' .. tostring(arg); + end + + index = index + 1; + end + + if randomTheme then + math.randomseed(os.epoch('utc')); + selectedTheme = THEME_NAMES[math.random(1, #THEME_NAMES)]; + end + + if THEMES[selectedTheme] == nil then + return nil, 'unknown theme: ' .. tostring(selectedTheme) + .. ' (available: ' .. themeNamesText() .. ')'; + end + + return THEMES[selectedTheme]; +end + +local function drawCreeper(theme) + local width, height = term.getSize(); + local pixelW = math.max(1, math.floor(width / 12)); + local pixelH = math.max(1, math.floor(height / 12)); + + if pixelW < 2 and width >= #FACE[1] * 2 then pixelW = 2; end + if pixelW > 4 then pixelW = 4; end + if pixelH > 3 then pixelH = 3; end local artW = #FACE[1] * pixelW; local artH = #FACE * pixelH; local startX = math.max(1, math.floor((width - artW) / 2) + 1); local startY = math.max(1, math.floor((height - artH) / 2) + 1); - term.setBackgroundColor(colors.green); - term.setTextColor(colors.white); + term.setBackgroundColor(theme.background); + term.setTextColor(theme.text); term.clear(); for row = 1, #FACE do @@ -57,26 +179,29 @@ local function drawCreeper() local y = startY + ((row - 1) * pixelH) + sy; local col = 1; while col <= #FACE[row] do - local bit = FACE[row]:sub(col, col); + local token = FACE[row]:sub(col, col); local run = 1; while col + run <= #FACE[row] - and FACE[row]:sub(col + run, col + run) == bit do + and FACE[row]:sub(col + run, col + run) == token do run = run + 1; end - local color = colors.green; - if bit == '1' then - color = colors.black; - end + local color = theme.palette[token] or theme.palette.G; drawRun(startX + ((col - 1) * pixelW), y, run * pixelW, color); col = col + run; end end end - term.setBackgroundColor(colors.green); - term.setTextColor(colors.white); + term.setBackgroundColor(theme.background); + term.setTextColor(theme.text); + + if height >= startY + artH then + term.setCursorPos(math.max(1, math.floor((width - #theme.title) / 2) + 1), startY + artH + 1); + term.write(theme.title); + end + term.setCursorPos(1, height); end @@ -92,9 +217,11 @@ if command == '-version' or command == '--version' or command == 'version' then return; end -if command ~= nil then - printUsage(); +local theme, err = parseArgs(args); +if not theme then + print(err); + print('utilise: creeper -help'); return; end -drawCreeper(); +drawCreeper(theme);