172 lines
4.6 KiB
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;
|