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;