0

I'm writing a chat helper tool for a game with a custom library.

I want to change specific variables when player sends the message.

This is my code

static List<string> asciis = new List<string> { "shrug", "omg" };
static List<string> converteds = new List<string> { @"¯\_(ツ)_/¯", @"◕_◕"};

private static void Game_OnInput(GameInputEventArgs args)
{
    newtext = args.Input;
    foreach (var ascii in asciis)
    {
        foreach (var converted in converteds)
        {              
            if (args.Input.Contains(ascii))
            {
                newtext = args.Input.Replace(ascii, converted);
                Game.Say(newtext);
            }
        }
    }
}

As you can see I'm trying to get the texts from "asciis" and convert them to "converteds" (in order).

Whenever I type something that not in "asciis" list it perfectly works. But whenever I type shrug it prints ¯\_(ツ)_/¯ + ◕_◕ + ◕_◕ (it prints omg 2 times). Same in omg too.

You probably understand that I'm really beginner. I really didn't understand what is wrong with this code...

3
  • 3
    you should use a dictionary. Commented Sep 21, 2015 at 21:33
  • Not sure if a dictionary could help here. He need to check every word and (if found) replace it. So you need to traverse the entire set of keys. Let see if someone could provide an example with a dictionary Commented Sep 21, 2015 at 21:49
  • @Steve How is that different from traversing a list of words? What am I missing? Commented Sep 21, 2015 at 21:51

3 Answers 3

1

It seems that your two lists have the same length (in terms of elements contained) and each element in one list has its replacement in the same position in the other list.

Then you could treat the two lists as two arrays and use a different way to search for the input term and replace it with the substitution text

private static void Game_OnInput(GameInputEventArgs args)
{
    newtext = args.Input;
    for(int x = 0; x < ascii.Count; x++)
        if (args.Input.Contains(ascii[x]))
        {
           newtext = args.Input.Replace(ascii[x], converted[x]);
           Game.Say(newtext);
        }
}

While i don't think there is a big improvement, you could also implement the same with a dictionary

static Dictionary<string, string> converter = new Dictionary<string, string>()
{
    {"shrug", @"¯\_(ツ)_/¯"},
    {"omg", @"◕_◕"}
};

private static void Game_OnInput(GameInputEventArgs args)
{
    newtext = args.Input;
    foreach(KeyValuePair<string, string> kvp in converter)
        if (args.Input.Contains(kvp.Key))
        {
           newtext = args.Input.Replace(kvp.Key, kvp.Value);
           Game.Say(newtext);
        }
}

Well, probably is a bit more readable, but still we need traversing the dictionary Keys one by one.

Sign up to request clarification or add additional context in comments.

3 Comments

This will definitely work, however I would recommend a Dictionary<string, string> over 2 separate arrays.
But you need to traverse the full dictionary Keys for replacement so what's the dictionary advantage?
You have a single object that holds the Key-Value mapping, e.g. Smiley-> =) rather than a 2 array index-based lookup that has a huge possibility of becoming misaligned.
0

As Daniel pointed out in his comment, this is a good use case for dictionaries.

Have a dictionary that maps the text you want replaced to the stuff you want to be replaced with:

Dictionary<string, string> dict = new Dictionary<string, string>
{
    {"shrug", @"¯\_(ツ)_/¯" },
    {"omg", "◕_◕" }
}; // etc

Then find all occurrences of the keys from the dictionary and replace them with the corresponding values.

Also why are you using static methods and fields? I may be wrong, but I expect most, if not all of your other methods and fields are static as well. I strongly recommend avoiding getting used to them. Try learning more about OOP instead.

Comments

0

Your main problem is that you are always replacing on args.Input, but storing the results in newtext each time, overwriting your previous replacements. Your next problem is that you are outputting the result after each replacement attempt so that's why you are getting multiple weird output results.

I also suggest a dictionary since by definition, it is a mapping of one thing to another. Also, note my changes below, I have moved the Game.Say call outside of the loops and changed "args.Input.Replace" to "newtext.Replace"

Dictionary<string, string> dictionary = new Dictionary<string, string>
{
    {"shrug", @"¯\_(ツ)_/¯" },
    {"omg", "◕_◕" }
};

private static void Game_OnInput(GameInputEventArgs args)
{
    string newtext = args.Input;
    foreach(string key in dictionary.Keys){
        newtext = newtext.Replace(key,dictionary[key]);
    }

    Game.Say(newtext);
}

3 Comments

Changing args.Input.Replace to newtext.Replace changes the behavior of the code. Consider if dictionary included {"◕_◕", "omg"}.
I don't follow. The purpose of this code is to replace all instances of a dictionary Key with the associated Value, so why would there also be a reverse mapping of "◕_◕" to "omg"? Consider the case where you have the string "omg! that was so weird? shrug". If you kept args.Input.Replace then the first iteration would set newtext to "omg! that was so weird? ¯_(ツ)_/¯" and then the second iteration would overwrite it as "◕_◕! that was so weird? shrug", thus only overwriting one Key with its appropriate value.
The original code replaces all instances of a dictionary key in args.Input with the associated value. Your code replaces all instances of a dictionary key in args.Input and in subsequent dictionary values with the associated value. Those will be different if a dictionary value contains a dictionary key. Yes, the example has no dictionary values containing a dictionary key, but that is a risky thing to rely on.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.