cc-libs/apis/libcarre.lua

172 lines
4.6 KiB
Lua

local DEFAULT_SIZE = 8;
local DEFAULT_CHAR = '#';
local RANDOM_CHARS = { '#', '*', '+', 'x', '@', '=' };
local function firstChar(value)
value = tostring(value or '');
if value == '' then return nil; end
return string.sub(value, 1, 1);
end
local function parsePositiveInteger(value, name)
local number = tonumber(value);
if not number or number < 1 or number ~= math.floor(number) then
return nil, name .. ' doit etre un entier positif';
end
return number;
end
local function parseNonNegativeNumber(value, name)
local number = tonumber(value);
if not number or number < 0 then
return nil, name .. ' doit etre un nombre positif ou nul';
end
return number;
end
local function clamp(value, minValue, maxValue)
if value < minValue then return minValue; end
if value > maxValue then return maxValue; end
return value;
end
local function createCarre(opts)
opts = opts or {};
local random = opts.random or math.random;
local api = {};
function api.parseArgs(args)
args = args or {};
local config = {
size = DEFAULT_SIZE,
char = DEFAULT_CHAR,
fill = false,
random = false,
count = 1,
delay = 0,
clear = false,
explicit = {},
};
local i = 1;
while i <= (args.n or #args) do
local arg = args[i];
if arg == '-size' then
local value, err = parsePositiveInteger(args[i + 1], '-size');
if not value then return nil, err; end
config.size = value;
config.explicit.size = true;
i = i + 1;
elseif arg == '-x' then
local value, err = parsePositiveInteger(args[i + 1], '-x');
if not value then return nil, err; end
config.x = value;
config.explicit.x = true;
i = i + 1;
elseif arg == '-y' then
local value, err = parsePositiveInteger(args[i + 1], '-y');
if not value then return nil, err; end
config.y = value;
config.explicit.y = true;
i = i + 1;
elseif arg == '-char' then
local value = firstChar(args[i + 1]);
if not value then return nil, '-char doit recevoir un caractere'; end
config.char = value;
config.explicit.char = true;
i = i + 1;
elseif arg == '-fill' then
config.fill = true;
elseif arg == '-random' then
config.random = true;
elseif arg == '-count' then
local value, err = parsePositiveInteger(args[i + 1], '-count');
if not value then return nil, err; end
config.count = value;
i = i + 1;
elseif arg == '-delay' then
local value, err = parseNonNegativeNumber(args[i + 1], '-delay');
if not value then return nil, err; end
config.delay = value;
i = i + 1;
elseif arg == '-clear' then
config.clear = true;
else
return nil, 'option inconnue: ' .. tostring(arg);
end
i = i + 1;
end
return config;
end
function api.computeSquare(config, width, height)
width = math.max(1, tonumber(width) or 1);
height = math.max(1, tonumber(height) or 1);
config = config or {};
local explicit = config.explicit or {};
local maxSize = math.max(1, math.min(width, height));
local size = config.size or DEFAULT_SIZE;
local char = config.char or DEFAULT_CHAR;
if config.random then
if not explicit.size then
size = random(1, maxSize);
end
if not explicit.char then
char = RANDOM_CHARS[random(1, #RANDOM_CHARS)];
end
end
size = clamp(size, 1, maxSize);
local maxX = math.max(1, width - size + 1);
local maxY = math.max(1, height - size + 1);
local x = config.x;
local y = config.y;
if config.random and not explicit.x then
x = random(1, maxX);
elseif not x then
x = math.floor((width - size) / 2) + 1;
end
if config.random and not explicit.y then
y = random(1, maxY);
elseif not y then
y = math.floor((height - size) / 2) + 1;
end
return {
x = clamp(x, 1, maxX),
y = clamp(y, 1, maxY),
size = size,
char = firstChar(char) or DEFAULT_CHAR,
fill = config.fill == true,
};
end
function api.drawSquare(termLib, square)
for row = 1, square.size do
termLib.setCursorPos(square.x, square.y + row - 1);
for column = 1, square.size do
local isBorder = row == 1 or row == square.size or column == 1 or column == square.size;
if square.fill or isBorder then
termLib.write(square.char);
else
termLib.write(' ');
end
end
end
end
return api;
end
return createCarre;