Identifying letters in a string

Hi! I am attempting to make a simple hangman game for practice. I have stored some words in a table and then randomly generated a word and stored it in a variable called theWord. Now I’m trying to create the event so that when the player clicks on the letter “A” on screen it checks to see if the letter “A” is found in theWord and if so makes it visible.

The problem I’m having is getting it to identify the indiviual letter “A”. I read through the String Library Class and only got very confused so any help is appreciated! Here is my code for the event.

function gamePlay(event)
if event.target.name == “a” then
aa = string.find(“A”, theWord)
print (string.find)
if aa == not nil then
aa.isVisible = true
else hBody.isVisible = true
end
end
end

Thanks! [import]uid: 170524 topic_id: 30491 reply_id: 330491[/import]

Only did a quick glance, but I think you have the parameters for string.find() reversed. The first parameter should be the string you want to search (theWord) and the second should be the string you want to find (“A” in this case).

[code]
local function gamePlay(event)
local self = event.target

if self.name == “a” then
local aa = string.find(theWord,string.upper(self.name))
print("letter "… self.name … " found at position " … aa … " in word " … theWord )

if aa then
–letter found

else
–letter not found

end
end
end

[/code] [import]uid: 94868 topic_id: 30491 reply_id: 122169[/import]

Thanks that worked perfectly!

I have another question now lol
Now that I identify the letter I can’t figure out how to make only that letter visible. I appreciate the help, I’ve spent an couple hours trying different things but just can’t narrow it down. Here is my code:

This is how I genrated the word using table wordList:
theWord = wordList[mRand]
currentWord = display.newText(theWord, 10, 100, “Times New Roman”, 20)
currentWord.isVisible = false

Here I check to see if there is an A in theWord (which works) the problem comes at the ‘else’ part of the argument… how to make the ‘A’ of currentWord visible?

function gamePlay(event)
local self = event.target
if self.name == “a” then
aa = string.find(theWord, string.upper(self.name))
if aa == nil then
hBody.isVisible = true
else
print("letter "… self.name … " found at position " … aa … " in word " … theWord )
currentWord.isVisible(aa) = true
end
end
end

Thanks!! [import]uid: 170524 topic_id: 30491 reply_id: 122213[/import]

So it looks like you are displaying a text object. That is one whole object. If you use the isVisible property on it, the entire word is going to go invisible/visible. You cannot just do one specific letter. You would have to change the entire text in it if you want to hide some letters and show others. This is controlled by the text property (in this case, currentWord.text). You are then going to have to rebuild the word each and every time you want to show a new letter. It feels like this would be unnecessarily complex.

It might actually be a little easier if you make a separate text object for each letter. Then you would control the isVisible property of each letter. And looking at the code snippet you provided, that is what it looks like you were trying to do (currentWord.isVisible(aa)). But you are going to have to create a table to do that properly. Like below.

local theWord = wordList[mRand]  
  
local currentWord = {}  
  
local nextX = 10  
local nextY = 100  
for j=1,string.len(theWord) do  
--this loop will create a table, where each entry is a letter in the word   
  
 --get the current letter  
 local currentLetter = string.sub(theWord,j,j)  
  
 --make a text object out of the current letter  
 local displayLetter = display.newText(currentLetter, 10, 100, "Times New Roman", 20)  
 displayLetter.isVisible = false  
 displayLetter.x = nextX  
 displayLetter.y = nextY  
  
 --give the text object a custom property so that we can compare to it later  
 displayLetter.letter = string.upper(currentLetter)  
  
 --need to offset this letter from the previous one, so that they are not all in the same position  
 nextX = nextX + displayLetter.contentWidth + 2  
  
 --add text object to table  
 currentWord[#currentWord+1] = displayLetter  
end  
  
local function gamePlay(event)  
 local self = event.target  
 local checkLetter = string.upper(self.name)  
  
 for j=1,#currentLetter do  
 if currentLetter[j].letter == checkLetter then  
 currentLetter[j].isVisible = true  
 end  
 end  
end  
  

I didn’t actually test the code above, but I think it should work. [import]uid: 94868 topic_id: 30491 reply_id: 122295[/import]

That is fantastic! Thank you, I had to tweak it a bit to work with the rest of my code but this was a fantastic, clean coding solution :slight_smile:

I can’t wait until I am a good enough programmer to figure out and write code like that!

Cheers! [import]uid: 170524 topic_id: 30491 reply_id: 122327[/import]

glad to help :slight_smile: [import]uid: 94868 topic_id: 30491 reply_id: 122345[/import]

Only did a quick glance, but I think you have the parameters for string.find() reversed. The first parameter should be the string you want to search (theWord) and the second should be the string you want to find (“A” in this case).

[code]
local function gamePlay(event)
local self = event.target

if self.name == “a” then
local aa = string.find(theWord,string.upper(self.name))
print("letter "… self.name … " found at position " … aa … " in word " … theWord )

if aa then
–letter found

else
–letter not found

end
end
end

[/code] [import]uid: 94868 topic_id: 30491 reply_id: 122169[/import]

Thanks that worked perfectly!

I have another question now lol
Now that I identify the letter I can’t figure out how to make only that letter visible. I appreciate the help, I’ve spent an couple hours trying different things but just can’t narrow it down. Here is my code:

This is how I genrated the word using table wordList:
theWord = wordList[mRand]
currentWord = display.newText(theWord, 10, 100, “Times New Roman”, 20)
currentWord.isVisible = false

Here I check to see if there is an A in theWord (which works) the problem comes at the ‘else’ part of the argument… how to make the ‘A’ of currentWord visible?

function gamePlay(event)
local self = event.target
if self.name == “a” then
aa = string.find(theWord, string.upper(self.name))
if aa == nil then
hBody.isVisible = true
else
print("letter "… self.name … " found at position " … aa … " in word " … theWord )
currentWord.isVisible(aa) = true
end
end
end

Thanks!! [import]uid: 170524 topic_id: 30491 reply_id: 122213[/import]

So it looks like you are displaying a text object. That is one whole object. If you use the isVisible property on it, the entire word is going to go invisible/visible. You cannot just do one specific letter. You would have to change the entire text in it if you want to hide some letters and show others. This is controlled by the text property (in this case, currentWord.text). You are then going to have to rebuild the word each and every time you want to show a new letter. It feels like this would be unnecessarily complex.

It might actually be a little easier if you make a separate text object for each letter. Then you would control the isVisible property of each letter. And looking at the code snippet you provided, that is what it looks like you were trying to do (currentWord.isVisible(aa)). But you are going to have to create a table to do that properly. Like below.

local theWord = wordList[mRand]  
  
local currentWord = {}  
  
local nextX = 10  
local nextY = 100  
for j=1,string.len(theWord) do  
--this loop will create a table, where each entry is a letter in the word   
  
 --get the current letter  
 local currentLetter = string.sub(theWord,j,j)  
  
 --make a text object out of the current letter  
 local displayLetter = display.newText(currentLetter, 10, 100, "Times New Roman", 20)  
 displayLetter.isVisible = false  
 displayLetter.x = nextX  
 displayLetter.y = nextY  
  
 --give the text object a custom property so that we can compare to it later  
 displayLetter.letter = string.upper(currentLetter)  
  
 --need to offset this letter from the previous one, so that they are not all in the same position  
 nextX = nextX + displayLetter.contentWidth + 2  
  
 --add text object to table  
 currentWord[#currentWord+1] = displayLetter  
end  
  
local function gamePlay(event)  
 local self = event.target  
 local checkLetter = string.upper(self.name)  
  
 for j=1,#currentLetter do  
 if currentLetter[j].letter == checkLetter then  
 currentLetter[j].isVisible = true  
 end  
 end  
end  
  

I didn’t actually test the code above, but I think it should work. [import]uid: 94868 topic_id: 30491 reply_id: 122295[/import]

That is fantastic! Thank you, I had to tweak it a bit to work with the rest of my code but this was a fantastic, clean coding solution :slight_smile:

I can’t wait until I am a good enough programmer to figure out and write code like that!

Cheers! [import]uid: 170524 topic_id: 30491 reply_id: 122327[/import]

glad to help :slight_smile: [import]uid: 94868 topic_id: 30491 reply_id: 122345[/import]