Answered Dynamically add/remove items from List<string> based on user input?

Ren6175

Member
Joined
Aug 5, 2019
Messages
22
Programming Experience
Beginner
I posted here the other day and got a good answer. I’ve been working on the code and I have a new challenge. I created a simple program that chooses a random item from a list. I figured out how to make it dynamic using checkboxes. I have 10 groups of data that I created using list<string>. If box A is checked the button chooses a random item from group A. If box A,B,C are checked it chooses a random one from from all three groups. I did this by writing them to a hidden listview box and return a random item from the list then clearing the list.

Anyway, what I need to do now is add another set of checkboxes that will add/remove monsters from the different groups. For context the items are types of monsters for a board game. But most people don’t have all the different monsters. So I want to be able to have them select which expansions they have then that will add/remove that monster from the appropriate list when choosing a random monster.

The only solution I see as a novice is to use a bunch of if statements in front of the .Add. For example,
If (checkboxA.checked) {monster.Add.(“Dragon”);}

Is this the best way? Any advice is appreciated. Thanks.
 
Last edited:
Please post your code in code tags so we can see what you've created so far. It will also help us to figure out the best way for you to approach what it is that you're doing.

I did this by writing them to a hidden listview box and return a random item from the list then clearing the list.

Why clear the list? Why not just remove the item/monster you just used?

Anyway, what I need to do now is add another set of checkboxes that will add/remove monsters from the different groups. For context the items are types of monsters for a board game. But most people don’t have all the different monsters. So I want to be able to have them select which expansions they have then that will add/remove that monster from the appropriate list when choosing a random monster.

I didn't understand that. Please explain. You also failed to ask a question. Lets start with one question at a time please.

As for adding and removing items from a list, you can add, or remove like so. List<T>.Add(T) or List<T>.Remove(T)
 
NEVER use hidden controls for data storage. Controls are specifically for user interaction. There's never a need to use them for simple storage as there are plenty of types without a UI for that.

It's hard to know the best way to proceed because you haven't provided enough relevant information, e.g. what constitutes a group. Based on the information you have provided, I'll suggest how I might solve a problem like this.

I would start with a class to represent a monster and the value that distinguishes its group, e.g.
C#:
public enum MonsterType
{
    Aerial,
    Terrestrial,
    Aquatic
}

public class Monster
{
    public MonsterType Type { get; set; }
   
    // ...
}
If you were to store all your monsters in a List<Monster> then you could first filter that list based on the user selections, then pick a random item from the filtered list, e.g.
C#:
var filteredMonsters = (from monster in monsters
                        where (aerialCheckBox.Checked && monster.Type == MonsterType.Aerial) ||
                              (terrestrialCheckBox.Checked && monster.Type == MonsterType.Terrestrial) ||
                              (aquaticCheckBox.Checked && monster.Type == MonsterType.Aquatic)
                        select monster).ToArray();
var monster = filteredMonsters[myRandom.Next(filteredMonsters.Length)];

EDIT: I got my Boolean logic a bit wrong on the first go but it's fixed now.
 
Last edited:
Please post your code in code tags so we can see what you've created so far. It will also help us to figure out the best way for you to approach what it is that you're doing.

I did this by writing them to a hidden listview box and return a random item from the list then clearing the list.

Why clear the list? Why not just remove the item/monster you just used?



I didn't understand that. Please explain. You also failed to ask a question. Lets start with one question at a time please.

As for adding and removing items from a list, you can add, or remove like so. List<T>.Add(T) or List<T>.Remove(T)
Haha. Sorry about that. I actually don’t know how you answer any questions because people like me are just writing vague descriptions of stuff that is in their head. I’ll try to follow the rules.
 
NEVER use hidden controls for data storage. Controls are specifically for user interaction. There's never a need to use them for simple storage as there are plenty of types without a UI for that.

It's hard to know the best way to proceed because you haven't provided enough relevant information, e.g. what constitutes a group. Based on the information you have provided, I'll suggest how I might solve a problem like this.

I would start with a class to represent a monster and the value that distinguishes its group, e.g.
C#:
public enum MonsterType
{
    Aerial,
    Terrestrial,
    Aquatic
}

public class Monster
{
    public MonsterType Type { get; set; }
  
    // ...
}
If you were to store all your monsters in a List<Monster> then you could first filter that list based on the user selections, then pick a random item from the filtered list, e.g.
C#:
var filteredMonsters = (from monster in monsters
                        where (aerialCheckBox.Checked && monster.Type == MonsterType.Aerial) ||
                              (terrestrialCheckBox.Checked && monster.Type == MonsterType.Terrestrial) ||
                              (aquaticCheckBox.Checked && monster.Type == MonsterType.Aquatic)
                        select monster).ToArray();
var monster = filteredMonsters[myRandom.Next(filteredMonsters.Length)];

EDIT: I got my Boolean logic a bit wrong on the first go but it's fixed now.
First, you guys are great. 2nd sorry for posting poorly worded questions. 3rd you basically nailed it. I have 10 types of monsters similar to what you listed i.e. cave, cold, hot. There are about 5-10 monsters per group. Cave has goblins, spiders, etc. Hot has imps, hellhounds, etc. When you play the game (Descent 2e BTW) you have to select random monsters for some quests. But these monsters come in expansions in packs of 3. So I might get goblins, imps, and dragons in one pack and spiders, hellhounds, and ogres in another. I want to be able to check which expansions I own so that when I generate a random group it only selects monsters filtered by both expansions I own AND type.

I literally started coding this project 2 days ago and I’ve never used C# before. I’m just watching videos on YouTube and the one way I saw to do what I want was the way I did it. But that is why I was asking my questions here because I’m sure I’m not doing it the most efficient way.

I appreciate you guys responding because I’m sure it is frustrating. But your response are helping me a lot. Thanks.
 
Please post your code in code tags so we can see what you've created so far. It will also help us to figure out the best way for you to approach what it is that you're doing.

I did this by writing them to a hidden listview box and return a random item from the list then clearing the list.

Why clear the list? Why not just remove the item/monster you just used?
If you read my other response it will make more sense but I cleared the list for 2 reasons. 1. I want it to generate a random monster each time regardless of previous results so I had it rebuild the list each time I pressed the button. 2. That is the only way I could figure to do it, was to reset the list.
 
I’m just watching videos on YouTube and the one way I saw to do what I want was the way I did it. But that is why I was asking my questions here because I’m sure I’m not doing it the most efficient way.
No disrespect meant to you, but if you are following youtube tutorials, then I am sure you are not doing things the most efficient way. Because any Youtube video I ever watched on howto's, was filled with absolute tripe and misinformation. I think you'd be best spending your time reading up on the MSDN documentation to educate yourself on the subjects of study that your application requires you to learn. As I think you will find your time well spent, compared to Youtube, and on some wannabe developer. I'd only advice using Youtube as a pointer and take what you see on there with a pinch of salt.

By the way, the enums posted by John above is a great idea and a nice example of using enums as your monster types, and it's also how I would have started out too.
 
Last edited:
As a variation on that code I posted, if you need to select a number of items from the list at random, a good way to avoid duplicates is to randomise the list and then just take as many as you need from the head of the list, e.g.
C#:
var filteredMonsters = from monster in monsters
                       where (aerialCheckBox.Checked && monster.Type == MonsterType.Aerial) ||
                             (terrestrialCheckBox.Checked && monster.Type == MonsterType.Terrestrial) ||
                             (aquaticCheckBox.Checked && monster.Type == MonsterType.Aquatic)
                       select monster;
var threeRandomMonsters = filteredMonsters.OrderBy(m => myRandom.NextDouble()).Take(3).ToArray();
 
Last edited:
No disrespect meant to you, but if you are following youtube tutorials, then I am sure you are not doing things the most efficient way. Because any Youtube video I ever watched on howto's, was filled with absolute tripe and misinformation. I think you'd be best spending your time reading up on the MSDN documentation to educate yourself on the subjects of study that your application requires you to learn. As I think you will find your time well spent, compared to Youtube, and on some wannabe developer. I'd only advice using Youtube as a pointer and take what you see on there with a pinch of salt.

By the way, the enums posted by John above is a great idea and a nice example of using enums as your monster types, and it's also how I would have started out too.
No offense taken and 100% you are correct. My code and my way of learning to code have been extremely inefficient. For me this is just a fun little project I’m doing in my spare time. My degree is in pharmacology so computer language isn’t my strength. I appreciate the input you and John have given. Thanks again.
 
BTW, here is how I did it originally.
C#:
public partial class UserControl3 : UserControl
    {
        List<string> cavemonsters = new List<string>();
        ;
added items to the list.
C#:
 private List<string> addcave()
        {
            cavemonsters.Add("Goblin Archer");
            cavemonsters.Add("Deep Elf");
            cavemonsters.Add("Cave Spider");
            cavemonsters.Add("Ferrox");
            cavemonsters.Add("Hybrid Sentinel");
           return cavemonsters;

Chose a random item from the list and displayed it in a text box. Then cleared the list, so I could try again.
C#:
private void Button2_Click(object sender, EventArgs e)
if (cave.Checked) { listBox1.Items.AddRange(addcave().ToArray()); }
Random monster = new Random();
            int i = listBox1.Items.Count;
            int chosenItem = monster.Next(0, i);
            listBox1.SelectedIndex = chosenItem;
            textBox1.Text = listBox1.SelectedItem.ToString();
            listBox1.Items.Clear();

I am going to try to recreate these results with your suggestions. I just wasn't using most of the built in functionality of the language. Not elegant.
 
Yes. Thank you. I will read some tutorials on enums. I grasp the idea of what he is saying to do and I can follow the code he has written, but I really have no idea what he is talking about. I understand enum and what a class is, but then I don't know the syntax to, for example, continue his example above. In other words I recreated his code and then I had no idea what to do next. I realize now that posting here was a bad idea because I'm in way over my head. I need to learn the basics. Thank you for your time.
 
He is using Linq, import the using directive for using System.Linq;
I am assuming you don't understand this? :
C#:
            var filteredMonsters = from monster in monsters
                                   where (aerialCheckBox.Checked && monster.Type == MonsterType.Aerial) ||
                                         (terrestrialCheckBox.Checked && monster.Type == MonsterType.Terrestrial) ||
                                         (aquaticCheckBox.Checked && monster.Type == MonsterType.Aquatic)
                                   select monster;
            var threeRandomMonsters = filteredMonsters.OrderBy(m => myRandom.NextDouble()).Take(3).ToArray();
Where monsters is probably not defined for you? Yea, maybe he could have explained the code a little better for you, even with inline comments. But you're wrong, you are not in over your head, as you seem to have a good understanding. Unlike some people who post here, they have no interest in learning and just want to jump into the next chapter, and I respect that you want to learn, as you show interest and continue to engage with the topic at hand. And that is exactly what we want you to do here.

If you're knew to C#, then I'd agree, you do need to know the basics, and I don't think throwing Linq code at you is a good idea for someone starting out, regardless however basic it looks. I'd say John wrote it that way by force of habit, because that's how most of us write code for ourselves. Linq is actually brilliant if you learn it. Sadly I don't know any dedicated books on the subject. I learned it mostly by experimenting through the IDE. But most importantly, you should always tell us if you don't understand something, and we will always do our best to make you understand how something works.
 
Sort of. I can follow the logic of the code, I think. The variable filteredmonsters will be filled with all the results from checking all the checkboxes for the different types of monsters. I don’t know what || is. If that is just formatting in the post or something I need.

I also understand that Enumerable converts all the monster types to a list of numbers that can be manipulated. I also understand that a class describes the qualities of a set of data, like luxury cars could be a class.

I’m not sure how to put it all together. I guess maybe I still create the Lists? Or I put the lists in the class somehow? Then convert them to numbers using Enum, execute the code he wrote which will return 3 monsters? Or maybe it puts them in an array that I will need to print out to a text box?
 
Back
Top Bottom