Morse code translator

For my game, I want to create a morse code translator, where it will take in morse code and output normal text, I have a table of morse code to text values so all I have to do is write a function that translates it. Since each character in morse code requires a space, for example,

.... .. --[[ hi because h = ...., i = .. ]]

actual spaces are 3 spaces long.

.... . .-.. .-.. ---   .-- --- .-. .-..  -.. this is "hello world" notice how between hello and world there is 3 spaces.

That is the exact problem I am facing here, each time I put this in the function, I expect it to return “hello world”, but it actually returns helloworld. I try to split each morse code group into a table. Then I compare them to the dictonary.

local MORSE_CODE = {
    [".-"] = "A",
    ["-..."] = "B",
    ["-.-."] = "C",
    ["-.."] = "D",
    ["."] = "E",
    ["..-."] = "F",
    ["--."] = "G",
    ["...."] = "H",
    [".."] = "I",
    [".---"] = "J",
    ["-.-"] = "K",
    [".-.."] = "L",
    ["--"] = "M",
    ["-."] = "N",
    ["---"] = "O",
    [".--."] = "P",
    ["--.-"] = "Q",
    [".-."] = "R",
    ["..."] = "S",
    ["-"] = "T",
    ["..-"] = "U",
    ["...-"] = "V",
    [".--"] = "W",
    ["-..-"] = "X",
    ["-.--"] = "Y",
    ["--.."] = "Z",
    ["-----"] = "0",
    [".----"] = "1",
    ["..---"] = "2",
    ["...--"] = "3",
    ["....-"] = "4",
    ["....."] = "5",
    ["-...."] = "6",
    ["--..."] = "7",
    ["---.."] = "8",
    ["----."] = "9",
    [".-.-.-"] = ".",
    ["--..--"] = ",",
    ["..--.."] = "?",
    [".----."] = "'",
    ["-.-.--"] = "!",
    ["-..-."] = "/",
    ["-.--."] = "(",
    ["-.--.-"] = ")",
    [".-..."] = "&",
    ["---..."] = "=>",
    ["-.-.-."] = ";",
    ["-...-"] = "=",
    [".-.-."] = "+",
    ["-....-"] = "-",
    ["..--.-"] = "_",
    [".-..-."] = "\"",
    ["...-..-"] = "$",
    [".--.-."] = "@",
    ["...---..."] = "SOS"
}
local function split(inputstr, sep)
  if sep == nil then
    sep = "%S+"
  end
  local t = {}
  for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
    table.insert(t, str)
  end
  return t
end


local function decode_morse_code(morse_code)
  local splitStrings = split(morse_code, " ")
  local newTable = {}
  for i, v in pairs(splitStrings) do
    table.insert(newTable, MORSE_CODE[v])
  end
  local hi = ftostring(newTable)
  return hi
end

print(decode_morse_code(".... . -.--   .--- ..- -.. .")) --it should print HEY JUDE, but it prints HEYJUDE

Everything else I got working, ftostring(newTable) is a helper function for formatting the table, but the fact is, when the parser goes through the 3 spaces, it ignores them and parses them out. I don’t want that, because then it will result in morse code with no spaces.

2 Likes
local MORSE_CODE = {
	[".-"] = "A",
	["-..."] = "B",
	["-.-."] = "C",
	["-.."] = "D",
	["."] = "E",
	["..-."] = "F",
	["--."] = "G",
	["...."] = "H",
	[".."] = "I",
	[".---"] = "J",
	["-.-"] = "K",
	[".-.."] = "L",
	["--"] = "M",
	["-."] = "N",
	["---"] = "O",
	[".--."] = "P",
	["--.-"] = "Q",
	[".-."] = "R",
	["..."] = "S",
	["-"] = "T",
	["..-"] = "U",
	["...-"] = "V",
	[".--"] = "W",
	["-..-"] = "X",
	["-.--"] = "Y",
	["--.."] = "Z",
	["-----"] = "0",
	[".----"] = "1",
	["..---"] = "2",
	["...--"] = "3",
	["....-"] = "4",
	["....."] = "5",
	["-...."] = "6",
	["--..."] = "7",
	["---.."] = "8",
	["----."] = "9",
	[".-.-.-"] = ".",
	["--..--"] = ",",
	["..--.."] = "?",
	[".----."] = "'",
	["-.-.--"] = "!",
	["-..-."] = "/",
	["-.--."] = "(",
	["-.--.-"] = ")",
	[".-..."] = "&",
	["---..."] = "=>",
	["-.-.-."] = ";",
	["-...-"] = "=",
	[".-.-."] = "+",
	["-....-"] = "-",
	["..--.-"] = "_",
	[".-..-."] = "\"",
	["...-..-"] = "$",
	[".--.-."] = "@",
	["...---..."] = "SOS"
}


function Encode(x)
	x = string.upper(x)
	local Encoded = ""
	for i = 1,string.len(x) do
		local Char = x:sub(i,i)
		if Char ~= " " then
			local Morse = ""
			for x,c in pairs(MORSE_CODE) do
				if c == Char then
					Morse = x
				end
			end
			Encoded = Encoded..Morse.." "
		else
			Encoded = Encoded.."   "
		end
	end
	return Encoded
end


function Decode(x)
	local Decoded = ""
	local DecodedWords = {}
	local Words = string.split(x, "   ")
	for i,v in pairs(Words) do
		local Characters = string.split(v, " ")
		local Word = ""
		for x, c in pairs(Characters) do
			if MORSE_CODE[c] then
				Word = Word..MORSE_CODE[c]
			end
		end
		table.insert(DecodedWords, Word)
	end
	for i,v in pairs(DecodedWords) do
		Decoded = Decoded..v.." "
	end
	return Decoded
end


print(Decode(Encode("This is a test message.")))
1 Like

Thanks for the answer, do you know how to filter out the space at the end? I ran the function and I got

HEY BRO [SPACE]

it messes with the formatting and such. I would assume that using the function you can remove the space?

You would use the string.sub function.

print(string.sub(Decode(Encode("This is a test message.")), 1, -2))

or when you are returning the string in the last function you can string.sub over there.

return string.sub(Decoded, 1, -2)
1 Like

If you’re splitting by a space, you won’t be receiving spaces in the resulting table containing all the matches. I feel like you could just use table.concat with a space on the results you accumulate, since it seems like you have the right words but can’t figure out how to get the spacing back.

function Decode(x)
	local Decoded = ""
	local DecodedWords = {}
	local Words = string.split(x, "   ")
	for i,v in pairs(Words) do
		local Characters = string.split(v, " ")
		local Word = ""
		for x, c in pairs(Characters) do
			if MORSE_CODE[c] then
				Word = Word..MORSE_CODE[c]
			end
		end
		table.insert(DecodedWords, Word)
	end
	for i,v in pairs(DecodedWords) do
		if i ~= #DecodedWords then
			Decoded = Decoded..v.." "
		end
	end
	return Decoded
end

Just added a check to see if it is the last word of the array and if it is, dont add the space

Line 16-18