How to compare two strings?

  1. What do you want to achieve?
    I want to compare two strings and detect if they are similar.

  2. What is the issue?
    I created an NPC that detects what the player is chatting, but currently, player’s messages have to be VERY specific for the NPC.

  3. What solutions have you tried so far?
    I’m not very good with strings, and I don’t know how to do this.

What I want to do is compare two strings, the player’s message, and the string to be compared for the NPC to do something. Like:

Player’s message:

--Hello, what's up?

String to be compared:

--Hello, what's up?

The problem is that the player sometimes can chat something a bit different or deformed like: “Hello whats up” or “Hello wat 'up” so I want to compare the strings and see if they are similar
or not.

1 Like

Why not use a UI for this? Most games where NPCs have few dialogue options go down this route.

If you still want to do a text-based solution, then may I direct you to something like this:

While it may not be exactly the same as what you want, comparing and matching strings are pretty nicely solved by text based adventure games.

2 Likes

So this is a bit of a difficult task, but you can use something called the Levenshtein Distance Algorithm for finding the similarity between two strings. It calculates the minimum number of single-character edits (insertions, deletions, or substitutions) required to change one string into the other.

Try messing around with the threshold until you receive the desired sensitivity.

-- Threshold to determine how similiar the player's text must be (the lower the number, the more sensitive)
local threshold = 5

-- Function to calculate Levenshtein distance between two strings
local function levenshteinDistance(s1, s2)
	local len1 = #s1
	local len2 = #s2
	local matrix = {}

	for i = 0, len1 do
		matrix[i] = {[0] = i}
	end

	for j = 0, len2 do
		matrix[0][j] = j
	end

	for i = 1, len1 do
		for j = 1, len2 do
			local cost = (s1:sub(i, i) ~= s2:sub(j, j)) and 1 or 0
			matrix[i][j] = math.min(
				matrix[i-1][j] + 1,
				matrix[i][j-1] + 1,
				matrix[i-1][j-1] + cost
			)
		end
	end

	return matrix[len1][len2]
end

-- Function to check if two strings are similar based on a threshold
local function areSimilar(s1, s2, threshold)
	local distance = levenshteinDistance(s1, s2)
	return distance <= threshold
end

-- Example usage
local playerMessage = "hello, what is up?"
local stringToCompare = "Hello, what's up?"

if areSimilar(playerMessage, stringToCompare, threshold) then
	print("Player's message is similar to the string to compare!")
	-- Perform NPC action here
else
	print("Player's message is not similar enough.")
end
3 Likes

Thank you! I really needed this because very specific messages are not really good