I thought this was a really cool idea, so I wrote my own version of this module. I read it over half-a-million times and I’m tired of looking at it.
Module Code
-- MorseEncoder.lua
local characterToMorse = require(script.CharacterMorseMap)
local MorseEncoder = {}
MorseEncoder.__index = MorseEncoder
function MorseEncoder.new(toggleFunc, timeUnit)
local self = {
Toggle = toggleFunc,
TimeUnit = 0.1
}
setmetatable(self, MorseEncoder)
return self
end
local function playEncodedCharacter(self, encodedCharacter)
if encodedCharacter == nil then
task.wait(self.TimeUnit * 2)
else
for _, duration in ipairs(encodedCharacter) do
self.Toggle(true)
task.wait(self.TimeUnit * duration)
self.Toggle(false)
task.wait(self.TimeUnit)
end
end
task.wait(self.TimeUnit * 2)
end
function MorseEncoder:Play(message)
local lowered = string.lower(message)
if not self:CanConvert(message) then
error("Message cannot be converted due to one or more extraneous characters")
end
for i = 1, string.len(message) do
local letter = string.sub(lowered, i, i)
local encodedCharacter = characterToMorse[letter]
playEncodedCharacter(self, encodedCharacter)
end
end
function MorseEncoder:CanConvert(message)
local lowered = string.lower(message)
for i = 1, string.len(message) do
local letter = string.sub(lowered, i, i)
if characterToMorse[letter] == nil and string.match(letter, "%S") then
return false
end
end
return true
end
return MorseEncoder
-- MorseEncoder/CharacterMorseMap.lua
return {
-- letters
["a"] = {1, 3},
["b"] = {3, 1, 1, 1},
["c"] = {3, 1, 3, 1},
["d"] = {3, 1, 1},
["e"] = {1},
["f"] = {1, 1, 3, 1},
["g"] = {3, 3, 1},
["h"] = {1, 1, 1, 1},
["i"] = {1, 1},
["j"] = {1, 3, 3, 3},
["k"] = {3, 1, 3},
["l"] = {1, 3, 1, 1},
["m"] = {3, 3},
["n"] = {3, 1},
["o"] = {3, 3, 3},
["p"] = {1, 3, 3, 1},
["q"] = {3, 3, 1, 3},
["r"] = {1, 3, 1},
["s"] = {1, 1, 1},
["t"] = {3},
["u"] = {3, 3, 1},
["v"] = {1, 1, 1, 3},
["w"] = {1, 3, 3},
["x"] = {3, 1, 1, 3},
["y"] = {3, 1, 3, 3},
["z"] = {3, 3, 1, 1},
-- numbers
["1"] = {1, 3, 3, 3, 3},
["2"] = {1, 1, 3, 3, 3},
["3"] = {1, 1, 1, 3, 3},
["4"] = {1, 1, 1, 1, 3},
["5"] = {1, 1, 1, 1, 1},
["6"] = {3, 1, 1, 1, 1},
["7"] = {3, 3, 1, 1, 1},
["8"] = {3, 3, 3, 1, 1},
["9"] = {3, 3, 3, 3, 1},
["0"] = {3, 3, 3, 3, 3},
-- punctuation, misc.
["."] = {1, 3, 1, 3, 1, 3},
[","] = {3, 3, 1, 1, 3, 3},
["?"] = {1, 1, 3, 3, 1, 1},
["'"] = {1, 3, 3, 3, 3, 1},
["!"] = {3, 1, 3, 1, 3, 3},
["/"] = {3, 1, 1, 3, 1},
["("] = {3, 1, 3, 3, 1},
[")"] = {3, 1, 3, 3, 1, 3},
["&"] = {1, 3, 1, 1, 1},
[":"] = {3, 3, 3, 1, 1, 1},
[";"] = {3, 1, 3, 1, 3, 1},
["="] = {3, 1, 1, 1, 3},
["+"] = {1, 3, 1, 3, 1},
["-"] = {3, 1, 1, 1, 1, 3},
["_"] = {1, 1, 3, 3, 1, 3},
["\""] = {1, 3, 1, 1, 3, 1},
["$"] = {1, 1, 1, 3, 1, 1, 3},
["@"] = {1, 3, 3, 1, 3, 1},
-- non-latin letters
-- upper and lowercase since string.lower() doesn't catch them
["À"] = {1, 3, 3, 1, 3},
["à"] = {1, 3, 3, 1, 3},
["Ä"] = {1, 3, 1, 3},
["ä"] = {1, 3, 1, 3},
["Å"] = {1, 3, 3, 1, 3},
["å"] = {1, 3, 3, 1, 3},
["Ą"] = {1, 3, 1, 3},
["ą"] = {1, 3, 1, 3},
["Æ"] = {1, 3, 1, 3},
["æ"] = {1, 3, 1, 3},
["Ć"] = {3, 1, 3, 1, 1},
["ć"] = {3, 1, 3, 1, 1},
["Ĉ"] = {3, 1, 3, 1, 1},
["ĉ"] = {3, 1, 3, 1, 1},
["Ç"] = {3, 1, 3, 1, 1},
["ç"] = {3, 1, 3, 1, 1},
["Đ"] = {1, 1, 3, 1, 1},
["đ"] = {1, 1, 3, 1, 1},
["Ð"] = {1, 1, 3, 3, 1},
["ð"] = {1, 1, 3, 3, 1},
["É"] = {1, 1, 3, 1, 1},
["é"] = {1, 1, 3, 1, 1},
["È"] = {1, 3, 1, 1, 3},
["è"] = {1, 3, 1, 1, 3},
["Ę"] = {1, 1, 3, 1, 1},
["ę"] = {1, 1, 3, 1, 1},
["Ĝ"] = {3, 3, 1, 3, 1},
["ĝ"] = {3, 3, 1, 3, 1},
["Ĥ"] = {3, 3, 3, 3},
["ĥ"] = {3, 3, 3, 3},
["Ĵ"] = {1, 3, 3, 3, 1},
["ĵ"] = {1, 3, 3, 3, 1},
["Ł"] = {1, 3, 1, 1, 3},
["ł"] = {1, 3, 1, 1, 3},
["Ń"] = {3, 3, 1, 3, 3},
["ń"] = {3, 3, 1, 3, 3},
["Ñ"] = {3, 3, 1, 3, 3},
["ñ"] = {3, 3, 1, 3, 3},
["Ó"] = {3, 3, 3, 1},
["ó"] = {3, 3, 3, 1},
["Ö"] = {3, 3, 3, 1},
["ö"] = {3, 3, 3, 1},
["Ø"] = {3, 3, 3, 1},
["ø"] = {3, 3, 3, 1},
["Ś"] = {1, 1, 1, 3, 1, 1, 1},
["ś"] = {1, 1, 1, 3, 1, 1, 1},
["Ŝ"] = {1, 1, 1, 3, 1},
["ŝ"] = {1, 1, 1, 3, 1},
["Š"] = {3, 3, 3, 3},
["š"] = {3, 3, 3, 3},
["Þ"] = {1, 3, 3, 1, 1},
["þ"] = {1, 3, 3, 1, 1},
["Ü"] = {1, 1, 3, 3},
["ü"] = {1, 1, 3, 3},
["Ŭ"] = {1, 1, 3, 3},
["ŭ"] = {1, 1, 3, 3},
["Ź"] = {3, 3, 1, 1, 3, 1},
["ź"] = {3, 3, 1, 1, 3, 1},
["Ż"] = {3, 3, 1, 1, 3},
["ż"] = {3, 3, 1, 1, 3},
}
I removed the boolean looping argument because this is very easy to implement from outside Encoder
.
If the end-user wants to do something else in the loop, they want it to play after a different amount of time, etc., that second argument would have been useless.