Changing individual characters in a string (SOLVED)

Io
31 Dec 2018, 01:37

So in a game I'm making, I have the player encounter a puzzle. One of those where you get a grid of black and white tiles, and the goal is to get them all one color, but whenever you select one both it and anything next to it swaps color.

I have the display for the grid done - I used a stringlist attribute, with each row being a separate string. I have the input done - recursive functions that get an input, convert it to int, and store it as an XCoord and YCoord attribute, and can properly throw errors if the player enters r56rg$ or some nonsense. I can even get it to print the specific character in the specific string the player indicates using Mid.

What I can't do is seemingly the most simple; actually CHANGING that one character in a string. I've looked through the functions and I can't seem to find the right syntax for doing this. Can anyone point me in the right direction? Thanks in advance!


Dcoder
31 Dec 2018, 01:55

Off the top of my head...

NameOfYourString = Replace(NameOfYourString, "OldCharacter", "NewCharacter")

Io
31 Dec 2018, 02:23

No, that doesn't seem to work. Trying this with the idea of Xs to Os, gives me this code:

if (Mid(StringListItem(TheList, YPlace), XPlace, 1)="X") {
  StringListItem(TheList, YPlace) = Replace(StringListItem(TheList, YPlace), Mid(StringListItem(TheList, YPlace), XPlace, 1), "O")
}
else {
  StringListItem(TheList, YPlace) = Replace(StringListItem(TheList, YPlace), Mid(StringListItem(TheList, YPlace), XPlace, 1), "X")
}

Which, when run, gets the following error:

Error running script: Invalid variable name 'StringListItem(TheList, YPlace)' in 'StringListItem(TheList, YPlace) = Replace(StringListItem(TheList, YPlace), Mid(StringListItem(TheList, YPlace), XPlace, 1), "O")'

mrangel
31 Dec 2018, 10:20

You can't have a function on the left side of an assignment; and Quest doesn't allow you to change an element in the middle of a list.

In this case, you would probably be better storing the data as either a single string (with the ; in so you can split it when you come to display it.

Or, store the grid as an object with attributes named cell_3_7 and similar, giving you access to whichever ones you want.


mrangel
31 Dec 2018, 10:44

Working with a list of strings, as you described, you could do that using something like:

TempList = TheList
for (i, 0, ListCount (TheList)-1) {
  line = ListItem (TheList, 0)
  list remove (TheList, line)
  if (i = YPlace) {
    before = Left (line, XPlace-1)
    after = Mid (line, XPlace+1)
    character = Mid (line, XPlace, 1)
    if (character = "X") {
      character = "0"
    }
    else {
      character = "X"
    }
    line = before + character + after
  }
  list add (TempList, line)
}
foreach (line, TempList) {
  list add (TheList, line)
}

(Note: I am assuming here that your X coordinates start from 1, while your Y coordinates start from 0. That's because characters in a string are numbered from 1, but items in a list are numbered from 0)

(Also note - this function removes all the lines from the list and puts them in a temporary list, changing the relevant one as it is moved. You need to do this in order to prevent the lines getting out of order)

(3rd note: typing on my phone, don't have Quest here, so can't test this right now)

(4th note: If this isn't a function, the last foreach loop could just be replaced with TheList = TempList)


mrangel
31 Dec 2018, 10:49

Or if your lines are all the same length, you could do:

LineLength = LengthOf (StringListItem (TheList, YPlace))
FullGrid = Join (TheList, ";")
pos = YPlace * (LineLength + 1) + XPlace
if (Mid (FullGrid, pos, 1) = "X") {
  character = "0"
}
else {
  character = "X"
}
FullGrid = Left (FullGrid, pos-1) + character + Mid (FullGrid, pos+1)
TheList = Split(FullGrid)

Io
01 Jan 2019, 21:46

Thanks, that... sort of works. It's letting me change O into X - the else - but the X into O isn't working. It doesn't even call it. For some reason it's not recognizing it as being 'X', so it just calls the Else and changes the X into X again.


mrangel
01 Jan 2019, 23:12

Sorry, careless typo. Corrected; I was comparing "X" to Mid (FullGrid, pos) (the remainder of the string starting at pos) instead of Mid (FullGrid, pos, 1) (the single character at position pos)


Io
02 Jan 2019, 01:11

And now it works perfectly. thanks!