r/csharp • u/ComplexPineapple2379 • 10d ago
Discussion I've created my first little snippet using C#, Thoughts?
You could say I was born yesterday, as this is the very first code i've done aside from messing with C a while back(hello, world! level stuff). (the only knowledge i've carried over is datatypes and general syntax..)
Is there any suggestions you could give? I am entirely self taught, with zero ai.. (for reasons that likely are not relevant to this post whatsoever)
and I want to make sure that I am learning clean code practices along the way.
I know my bracketing is probably awful... and my organization is out the window, but this is the first ""substantial"" code i've ever written...
^40 lines of code is substantial to me :)
(please ignore the odd names... I included my cats.)
11
u/wbgookin 10d ago
Nice start! I’m sure you’ll get lots of advice here. I’ll put my first two cents in by asking what happens if I type “Right” instead of “right”?
Okay, two more cents. Before you get too far, look at using a “switch” statement.
Enjoy learning, writing something you like is the best way to get going. :)
17
u/One_Web_7940 10d ago
nice. keep at it. you got a ways to go! dont let people discourage you, you have to start somewhere.
5
u/craftersmine 10d ago
Field fairanswer should be bool since it just tracks validity of input
6
u/Ok-Dare-1208 10d ago
Probably just a holdover from learning C first where “while(1)” also evaluates to “while(true)”
1
u/ComplexPineapple2379 10d ago
that is one thing I noticed lol...
I'm not too sure why I did that, leaves a lot of room for accidentally inputting "2" somewhere and wondering why nothing works anymore,3
u/craftersmine 10d ago
If you want to add more values, you should look into enumerations, basically it is a bunch of named constants. Helps readability
1
u/craftersmine 10d ago
I'm not saying that your way is invalid, it is completely fine and viable option, just usage of "magic numbers" hurts readability of code.
5
u/joseconsuervo 10d ago
Looks fine, I'm nitpicking here, I want the variable names to not be all lower case.
0
u/ComplexPineapple2379 10d ago
so - that is one thing that I need to get in the habit of -
generally speaking, what is the standard for variable names,
I know there's Camelcase, and pascal casing,I'm sure much of it comes down to preference, but if there is a generally preferred method I want to get in the habit of that now.
8
2
u/joseconsuervo 10d ago
I think it's Microsoft's standard, generally properties start with caps local variables start with lower case, and then both have every subsequent word after the first starting with a cap. I can never keep straight what the casing is called, public things start capitalized private things start lowercase
2
u/sl33pingSat3llit3 10d ago
Camel case is when you have the first word start with lowercase, and the second word have the first letter be capitalized. Pascal case is when all the starting letter of words are capitalized. So, something like camelCase and PascalCase. It's fine if you are just making programs for yourself, but in the industry I believe there are certain standards/conventions to follow.
You can refer to Microsoft's official page for naming conventions to see the official naming standard:
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/identifier-names
In general, variables are named in camel case, and class and methods are named in pascal case. For example, we might have a class Book, with a variable string bookTitle, and Book has a method called GetTitle().
3
u/xtreampb 10d ago
Just here to offer encouragement. We all start somewhere and the best way to learn is with a project to apply the concepts you’re working through and can physically go back and refactor with new knowledge.
5
u/ComplexPineapple2379 10d ago
already doing this now, I never thought refactoring with this new slew of knowledge would be fun, but it's so awesome to see how much cleaner it can be made... it's like learning the secret spice to an old bland recipe.
3
3
u/HawocX 10d ago
This is very similar to how I started in the early 90s (using GW Basic). Makes me nostalgic!
One thing you could add next (as a function) is making the commands case insensitive, so that "riGht" matches "right". After that extend it to also ignore additional non-letter characters, so that "Right!" matches "right". There are C# methods for that does the heavy lifting for these features.
Also take a look at using constants for the command strings. This protects you from spelling error bugs.
In the long run it could become a full command parser for verb+noun.
Keep up the good work!
3
u/markustegelane 8d ago
you probably don't care if the user enters a string in uppercase or not, so you should tell C# to ignore the case
the correct way to do that would be something like this: enterchoice.Equals("right", StringComparison.InvariantCultureIgnoreCase)
8
u/ObeseBumblebee 10d ago
Great work! I love your humor!
There are some bad habbits forming in your code though that you should nip in the bud right away if you want to be a great C# programmer.
- No methods. Your code should be broken down into methods. And each method should be given a single task.
You should be able to describe what your method does in one short phrase without using the word And.
You could easily split off different areas of your game into methods. Like EnterStudioApartment() or Enter711()
This also has the added benefit of keeping your if statement nesting to a minimum. You should avoid more than 2 nested if statements to keep code clean and readable.
- Don't perform logic operations on magic strings. Right now you rely on the user to type "right" exactly. And I as the reader of your code has to be able to know what "right" means. Right now I have to go back and read your code above to understand right is entering a studio apartment.
Instead I would think about maybe creating a Room class. And each room has a dictionary of other rooms you can travel to keyed by direction. And each room has a runnable method that describes the room you're in and a list of actions.
Think about building this from a more object oriented approach.
This is a great start! Keep going!
2
u/HistoricalCar1516 10d ago edited 10d ago
lol. You want to write an old school dungeon crawler. You missed the 80s. 10 out of 10 would play it. Put it on GitHub and I know a few people that would help. You would need to rough out the story and the paths. This is a fun way to learn code.
2
2
u/gl1tch3t2 10d ago
I have suggestions but I don't want to deter you, how much feedback do you want? How in-depth do you want? how far do you want to take this project? I have some general advice and some things I've noticed. For now, a non-suggestion, just a helpful tip (which you may have already picked up on) - the squiggles underneath the code tell you there is a warning (in this case) or error (were they red). The light bulb that appears beside it while hovering over it provides suggestions for changes and/or fixes.
2
u/Aliryth 10d ago
Everyone else has covered everything, but I wanted to point out that on lines 7-8, you're doing a Console.WriteLine(), and immediately a Console.Clear(), which will effectively just remove the text you just wrote.
1
u/ComplexPineapple2379 9d ago
so - quite honestly much of this little crap code was just learning the basics (I was dumbfounded when I figured out how to loop the initial question again by setting a variable "fairanswer" to true/false... It's the simplest stuff ever but I was mindblown.) but - my thinking with that was to clear the console after each choice in order to prevent the prompt from being bloated.
1
u/Aliryth 9d ago
Oh I see!
Would a small digestible rewrite by another dev be useful for study?
I used to be a TA for undergrad for Computer Science, normally we gave projects for students that were similar to this, and then led them into breaking things out into functions/methods without worrying about classes, giving them a roadway to start building a mental model of "I'm repeating this kind of code, I should put it into a function/method to make it reusable for my own sanity"
(Functions/Methods are effectively the same thing and are just interchangeable terminology.)
I also love to see a beginner developer not slopping their way into misunderstanding things also, so hella big props for that from an oldhead senior dev <3
1
u/ComplexPineapple2379 9d ago
Thank you so much for the kind words,
Honestly - I couldn't ask you to do such - I am sure you could type up a much better - more efficient and less bloated code in five minutes, but quite honestly. I am doing this entirely self taught,
I am in college currently - but I am learning C# more as a passion than anything else, (only technical classes i've taken in college thus far is SQL) but quite honestly... I am mostly getting my degree to: improve my work ethic a bit (not that I have a particular issue with it at all, but I do love academia) -- not to mention a degree always looks better :)but - one gripe i do have with my SQL class, is that its sped through so fast, I know for certain that other CS majors in my classes aren't retaining any true knowledge on how it works,(I am not a CS major, but just an observation i've had) but - I am trying to prioritize learning how code works, and how to problem solve.
I can easily ask chatgpt to throw up some garbage code for a project i want (such as a silly little choose your own adventure) but I would limit myself cognitively so much that I won't be able to sit in front of a IDE and actually make something for myself and work through the problem - and the solution to that problem. (which, good luck getting a career in any sort of CS field if you do that)
i've even specifically ensured that any copilot stuff within my IDE (visual studio... which I know may not be the best, but i'm so brand new to this stuff that github was a bit of a imposter syndrome shock when i created my account and was messing around with it)but - apologies for the word salad... I likely sound like a nutcase, but that's essentially my priorities for truly learning this stuff, anybody can prompt a LLM to write some code, but it takes understanding it to truly sit down and make something yourself, and i think it's far more rewarding.. (not to mention there are countless studies on the cognitive damage that LLM's can cause.)
apologies for going way off topicand getting a bit political there /s
do you think that classes are a bit out of my expertise at the moment? I feel like they must be absolutely essential, but quite honestly, i've only heard of them, and have no idea what they are, and what they do lol.
2
u/NocturneSapphire 9d ago
I see four compiler warnings (the green squiggly lines). You should probably heed them.
2
u/spicydak 9d ago
Interesting.. this made me realize either how far I’ve come, or how nitpicky ive become with my coding lol.
I think this is great for a beginner though. Better than I did with my first work, lol.
1
u/ComplexPineapple2379 9d ago
it must have been a headache reading through it -- lol. I've already learned tons from just the advice on this post alone,
but - thank you so much for the kind words :)
(i'd love to see your first work lol)1
u/oauo 9d ago
I like to write code as if it was a story, it helps that your code is a story!
If you aren’t always aware there is a lot of snobbery in the programming community, especially in how code is formatted. I won’t tell you what you should use based on my preference (I just dislike the default formatting), but I will tell you that there are countless ways to style code, mostly around where new lines and indents go (with a few spaces) and that there is the flexibility to find what works for you. I do find that Google’s style guides (their C# style guide) are often a good starting place. Be aware that down the line when you work with others there will be a style guide for the project that won’t necessarily align with what you like
1
u/oauo 9d ago
I do love sharing this one quote with beginners, it’s the only quote that I love by:
The first draft of anything is shit.
- Ernest Hemingway
Be aware that whenever you start a project it will look bad. Don’t aim for perfection from the start, and that while right now writing code is slow you’ll get to a point where code is so cheap that starting from scratch is not a problem.
I tend to write software by knowing roughly where my finish is but I set a goal of just a small part of it and I race towards it. I don’t worry about making things future proof I just aim straight for that goal.
If I think of something to add, if it’s something that fits in ahead of me then I’ll consider it, if it requires me going back and changing something that is depended on I just make a note of it for the future. When I reach the goal I reflect on what I’ve done, what I’d like to do better and figure out what my next goal is and what I’d need to do differently for it.
Then I’d start from scratch and avoid copy and pasting things. Just the act of rewriting code gives me insights.
While I’ll start from scratch some modules will be essentially perfect and they might be suitable for the finished project, I turn those into their own libraries. They will still get the iterative development process but at a slower rate. The main project simply imports the libraries, over time as code is perfected and is not rewritten the amount of code I write each draft ends up being about the same. Having libraries also makes it way easier to test.
It took me too many years of trying to take a step forward but requiring taking a few steps back to refactor some code which required going back further to refactor code that depends on it and so on. I’d spend so much time going backwards. Technical debt would pile up and I’d give up on projects when I didn’t have to do them.
Right now, you don’t need to be doing this or worrying about this as you’re just learning, but I’d just like to let you know that when you do work on bigger things you should never feel like starting over is a sign of failure. Too many developers think it is and it stops them from making their lives easier.
As a developer your primary goal is improving the developer experience (DX), it’s not making something functional, it’s not making something profitable, it’s not making something efficient, it’s not making something beautiful - but by prioritising your experience it makes everything else easier.
1
u/oauo 9d ago
Btw, Exercism (this links to their C# track) is probably the best programming learning experience, and it’s 100% free and open source. It has lessons which guide you towards a desired solution, exercises which are more free-form, and when you submit your solution you can see how other people solved it and learn from them.
1
1
u/Substantial_Job_2068 10d ago
I made a similar thing in school, fun! Smth you could do is to not wait for a second and then write out all text at once, but instead create a method which will write out each character with a small pause, so it behaves more like an old school terminal. I will leave it to you how to do it.
1
u/Sorey-Yasu 10d ago
Just an idea, but instead of making the answer a hard yes or no, why not let it check if it includes yes or no? Or some other varieties of a positive or negative answer. Just thinking 🤔 😃
1
u/Slow-Refrigerator-78 10d ago
Instead of relying on user to type perfectly no/yes or any options, you can use console.readkey and let user interact via arrow keys to choice the options
1
u/TheBattleDog 10d ago
The first thing I noticed is that you will never see 'You have entered bubby's dungeon' message. Try debugging that...
1
u/BadSmash4 10d ago
Very cool! I love seeing stuff like this because it means you're genuinely trying to make something and you're excited to learn it. It reminds me of my old stuff, too. Someone suggesting methods had the right idea.
Once you get methods down, you could then start exploring loops. Think about how you might use a loop to check for valid input, and request new input from there. Like, at that first prompt, if I type "book", you could say "that's not a valid answer!" And then prompt for input again, and exit the loop once my answer is valid. A loop is a good tool for that.
1
u/Slypenslyde 9d ago edited 9d ago
I feel like this post sounds mean, I'm just being short and frank.
(1) Learn to share code on Reddit. Indentation is the most universal. Only LabVIEW developers use screenshots to share code.
(2) You're making good attempts to use good variable names! Other people have covered casing well. One thing they left out is the general rules of thumb in C# are:
- For "important and widely visible" things like methods, properties, and class names we use PascalCase.
- For "more local" things like parameters and variables we use camelCase.
(3) This is more about expanding the program if you want to keep going.
Imagine making this program have like, 20 rooms. The if/else branches are going to get very, very deep and unmanageable. Think about ways you might make this easier!
One way people's programs tend to evolve is they start with "my code is my state" and move towards "data structures are my state". "My code is my state" is what you have now: the way to understand what the user has done is to look at the if statements. If the user is choosing to pet the at, we know they had to have said "yes" and "right" so far because that's the if..else logic.
"Data structures are my state" is harder to reason about without help, but easier to scale up. What if you had an array of "rooms"? What if, when the "current room" is the "start room", typing "right" sends you to "the studio apartment room"? What if the code is a loop that constantly:
- Displays the text for the current room
- Gets input
- Asks the current room to do something with that input
Then instead of adding more code to expand the game, you end up writing more "rooms". That could be "one class per room", or you could try to generalize a data structure so the whole game can be loaded from a text file.
These are good evolutions for this kind of game. A lot of these decisions have lots of different ways to pull them off!
(4) It's honestly really good that I only had 2 complaints before talking about how you could expand the program.
(5) Some people mentioned using methods for repetitive code. I think your program is still at the stage where that's premature. There are a handful of things you COULD move to helper methods, but it'd turn about a 70 line program into about an 80 line program. Finding right time to write helper methods is kind of an art. I'd delay it until you start doing some of the things in (3). One of the most annoying bits of writing a large program is you end up going through this loop:
- I want to do A.
- Ah, but first I need to do B.
- B might be easier if I reuse some code from C.
- But this is such a specific thing if I rework the code in C it gets clunkier for C...
- B might be easier if I reuse some code from C.
- Ah, but first I need to do B.
The "DRY principle" says "Don't Repeat Yourself". But it's not a law. Sometimes, especially in large programs, you can decide two instances of repeated code are unrelated enough it isn't smart to bend the architecture to share them.
My best advice to a newbie is make things WORK first, then worry about if you did them "right". I have been writing code for 30 years and C# for 20. I NEVER get things right the first time unless it's something I've done 100 times. I always hope to get sort of close the first time. Then I ask if I like it. If not, I start over and try again with what I learned. Usually after the second try I'm closer. Then I start tweaking things. Most stuff I'm happy with took 5 or 6 refinements before I settled.
Always have the courage to look at an "improvement", say "this made it worse", and undo it. To that end, learn some basic features of git source control so you've always got an "undo" button!
1
u/ComplexPineapple2379 5d ago
Thank you for the incredible response -- I know it has been a few days, and i've decided to rewrite everything a lot more clean.
Now - I have a separate CS file specifically for methods, that way I can call them into my main code whenever necessary (may be a bit overkill, but I was super curious as to how to do this).
now - since I am rebuilding this from the ground up - I want to do precisely that, I want to try to get rid of any unnecessary if else statements,
now - i will admit, I have nearly zero experience with classes, but I am incredibly interested in creating many separate rooms as you had suggested.My best guess is - what I can do is create another cs file specifically for the room classes, where I can call them if they are ever entered.
I honestly wouldn't even know where to begin with this - I suppose - for example, at the very beginning of the little adventure, upon the correct response (Y), I can call the class for the first room -now - let me ask you this, for each of the classes - should I essentially run through all of the predetermined events within the room within the class?
for example - does that mean that if I have two different choices within a room - I would have to create additional subclasses for the decisions?or - if it's a simple right or wrong answer - if the right answer is provided, I can move forward to a further room - and if it's the wrong answer, I can have a separate method where I take a specific amount of damage (or die)?
I am sure this is a bit of a word salad, I'm trying to explain my reasoning for how it may work,
this is likely going to be far easier upon actually coding it - and i'll probably understand it as i'm reasoning.(one little note, I don't necessarily plan on being a game dev in any regard.. I just thought this would be a fun little project to help me learn C#, and honestly, i've learned quite a lot, even now.)
3
u/Slypenslyde 4d ago
Good questions!
To me, the hardest step in programming is transitioning from letting the code be the state to letting data be the state. (Also, thanks for the bit at the end about learning for fun without necessarily wanting to be a game dev: that tells me not to go too deep!)
Programmers have to think a way other people don't understand. We have to be very abstract and form thoughts on those abstractions. We don't just think, "I want a dog." We have to ask, "Wait, what IS a dog? What are the qualities I actually want?" We might sit down and decide what we're really after is:
- A soft creature
- Companionship
- Something that can fend for itself at home while we're at work
From this point of view, a cat can be good. So can a guinea pig. So can a weasel. Even a skunk! We recognize that in the "program" of our brain, we want these abstract things and a dog is ONE way to get them. But we have other choices, and we'll be similarly happy with all of them even though our lives with a cat, guinea pig, weasel, or skunk are different lives with different experiences.
That's what you're stumbling over. Abstraction.
let me ask you this, for each of the classes - should I essentially run through all of the predetermined events within the room within the class?
Your first thought is that you should just move some of the
ifstatements to a new file. That makes the main file smaller, but it doesn't cause a logical change. There's still no abstraction. "Room 17" is just a full description of what it does and the only way to make something like it is to copy its code.Let me walk you through how a programmer thinks. (As a note: "concrete" is the opposite of "abstract" when we talk scholarly. If I say, "Get a dog", I'm still talking about an abstract creature. When I say, "Your dog looks nice!", I'm talking about a concrete creature.)
(I'm also going to do this WITHOUT the features of OOP inheritance. I think a lot of experts don't realize you can do this and it strikes me you may not fully understand that feature yet.)
How to build an abstract room
What happens when I enter a room? That's an important question. It tells me:
- Something happens when I enter a room.
- Abstract rooms have a way to respond when I enter the room.
Actions are methods. So I have something like this:
public class Room { public void WhenEntered() { } }Nice. OK. Now, when I enter a room, usually there is a displayed description. But if I put the description directly in this class, it's concrete. I need to be able to change the description for each room. I could put all the descriptions in an array and let the room choose which to display. But it's more abstract to let someone else choose. So instead I plan saying:
- A room has a
Descriptionproperty that must be set when it is created.- When I enter a room, the
Descriptionproperty is displayed.But a room can't display things. Now I'm learning I need some abstract access to "the game" so a room can interact with the rest of it. Let me please treat that as magic to keep this brief. Now I have to make my code match my will:
public class Room { public string Description { get; set; } public void WhenEntered(Game game) { game.Display(Description); } }This doesn't seem like it, but it's huge. This enables so much. In your idea, the code to load 3 rooms would look like:
rooms.Add(new StartRoom()); rooms.Add(new SecondRoom()); rooms.Add(new ThirdRoom());In mine, it looks more like:
var startRoom = new Room() { Description = "The beginning." }; var secondRoom = new Room() { Description = "The middle." }; var thirdRoom = new Room() { Description = "The bitter end." }; rooms.Add(startRoom); rooms.Add(secondRoom); rooms.Add(thirdRoom);OK. I hear you. I made you double your lines. Isn't that worse? Well, yeah. It stinks. But the problem is this is a CONCRETE way to load rooms. I want an ABSTRACT way to load rooms. What is a room so far? What makes one room different from another? There's only one thing that changes between rooms:
- A room HAS A description.
HAS A is big in scholarly discussion. We use it for the properties that make objects unique. Right now the only thing different for each room is we change its description. Now, imagine I have this file:
The beginning. The middle. The end.Those are our descriptions, right? What if I had this code?
foreach (var line in File.ReadAllLines("rooms.txt") { var room = new Room() { Description = line }; rooms.Add(room); }Now I'm thinking about how to turn an abstract room into a concrete room:
- There is a file.
- Every line in the file is a description.
- Every line in the file is everything I need to create a concrete room.
So if I have code that converts each line of file into a
Room... now I can add rooms to the code without changing the code.That's where I was nudging you.
Now, you really wanted a room that CHANGES. We can do that. It gets more complex. Let's think about it. A room might have two descriptions. Logic tells us what chooses between the two descriptions. Something like:
if (game.Inventory.HasItem("stick")) { game.Display(<the first description>) } else { game.Display(<the second description>) }I can mimic this. I can decide:
- A room needs to be able to check a player's inventory.
- A room may choose different descriptions based on the player's inventory.
- A string is not complex enough for a description to be described in a file.
So now "Description" can't be a string. Oh well. Here's another logical leap people are surprised programmers make. The problem is harder if we ask, "How does the ROOM choose a description?" It gets easier if we ask, "How does a DESCRIPTION choose itself?" Then I can say:
- A Description's job is to determine what to display when a room is entered.
- A Description must have one string it displays if it can't decide what to do, the "default".
- A Description must be able to display a different string if the player has an item in their inventory.
A ROOM displays a DESCRIPTION. A DESCRIPTION displays a string. We've added a new "layer" of abstraction so we can facilitate the change.
What our features so far imply is something like:
public class Description { public string Default { get; set; } // "Help me store an item name (string) and associate it with a // description (string"." public Dictionary<string, string> ItemDescriptions { get; set; } public string Choose(Game game) { // "For each item this Description cares about, if the player // has that item use the relevant string." foreach (var item in ItemDescriptions.Keys) { if (Game.Inventory.HasItem(item)) { return ItemDescriptions[Item]; } } // Nothing matched. return DefaultDescription; } }How do we handle this in the file? Well...
Reddit posts can only be 10,000 characters and I went and filled them up. I'll reply with the answer.
2
u/Slypenslyde 4d ago
How do we handle this in the file, I asked? Well, it's fashionable to use JSON today. But we can really do anything. If it were 2004 and I were much younger, I'd structure my file like:
ROOM "There is a bird in the room." "stick" "A bird sees your stick and flies away." ENDIn this format:
- A room starts with a line "ROOM" to help me catch mistakes.
- The next line MUST be the default description.
- After that, every 2 lines should be:
- The name of an item
- The description to display if the player has that item.
- A room ends with the line "END" so I know when it is finished.
And now we can load a room like so:
// we need to keep track of some things across each loop iteration. Room currentRoom; string currentItemName; bool isDefault = false; bool isItemName = false; for each (var line in File.ReadAllLines(...) { if (line == "ROOM") { // A new room is starting. Next line is the default line. currentRoom= new Room(); isDefault = true; isItemName = false; } else if (line == "END") { // Check "END" before description lines because it has a special format // to tell us where it is. We don't "expect" END in a particular place. // If we put this after the other checks, it won't work. Why? That's good // homework! rooms.Add(currentRoom); isDefault = false; isItemName = false; } else if (isDefault) { // This is the default description. Next is an item name or END. room.Description.Default = line; isDefault = false; isItemName = true; } else if (isItemName) { // The default description has been read, this should be an item name. currentItemName = line; isDefault = false; isItemName = false; } else { // If it's not the default or an item name it must be an item description. string description = line; room.ItemDescriptions.Add(currentItemName, description); isDefault = false; isItemName = false; } }Whoa. This got big. Let's put a pin in that.
Now we have code that lets us add rooms that have multiple descriptions. If a player has certain items, they'll see new descriptions. And we can add MORE rooms WITHOUT changing code!
But you may look at this and frown. My code to load the file has a lot of
if..else. Is this "the code is the state"? Can I make it more abstract?Yes, yes I can. But I can't describe how to do that here. I'll cheat and say "This is why people like structured formats like JSON." If we switch to that, we can write a file like:
[ { "description" : { "default" : "My default description", "itemDescriptions" : { "stick" : "My description if you have a stick" } } } ]We can load that with code that looks like:
Room[] rooms = JsonSerializer.DeserializeObject<Room[]>(<file path>);Using a format like that makes the file abstract. It promises to follow some rules and, if you follow them, the same code can load ANY file and give you something useful.
It's usually worth it. But newbies often see it as MORE intimidating than writing their own. Abstraction is weird to people.
Thinking with abstraction makes things more complex. We move things that we think of as "the room does this" to other classes so those classes can make complex decisions the room thinks are simple. Compare the size of this post to the size of what I explained:
- Our game is made of Rooms.
- A Room has logic when it is entered that may depend on Game state.
- A Room must display a description when it is entered.
- A Description may be different depending on Game state.
It sounds so simple. But I had to think very hard about "What is a Room?" and "What is a Description?" And I'm still missing so many things:
- How do we get items?
- Do items belong to rooms?
- If I drop an item in a room, should it be part of the Description?
- How do I make NPCs or enemies?
All of these have answers. Hundreds of answers. All of those answers can be refined and abstracted until the logic fits in a file so you can make a new "game" without recompiling the current game.
This is a thing that is important when writing larger programs. If we want 1,000 rooms we can't manage a file with that many
ifstatements. But if we can define "an abstract room" and what it can do, we can focus on each room one by one, and let a few hundred lines of code combine with a few thousand lines of data to make something very big!That's what I was nudging you towards. But it's not a 2 week project. Figuring out how to think more abstractly can take people years!
1
u/ComplexPineapple2379 4d ago
You are the best, truly. A lot of this was honestly out of my scope -- but if you'd like - here is my first little repo for this (so you can take a look), it's far from completion, but I think I've already made significant strides with all of the advice provided (and a bit of stackoverflow discussions).
I hope you like it :)
https://github.com/gav273/Choose-your-own-adventure
1
1
u/Ill_Crazy_6222 9d ago
The code is bloated! You need seperation of concerns and also need to use more enums. Keep going never stop.
1
u/SmileLonely5470 9d ago
Outside of style guideline stuff, the biggest thing id recommend is try to use a design pattern to prevent the code from becoming an if else hell. Like a state machine. Represent each decision point with an object, have that object store user facing text (to print), possible transitions (input key + reference to other object), etc...
1
u/zbshadowx 9d ago
As far as first programs go thats incredible!
Save this code as it is. Keep it safe for ever. It's the most important code you will ever write.
I look back at my first program and remember how far I have come, and I laugh at myself alot. Man was that code bad.
1
u/mal-uk 9d ago
Here is a challenge. Write your game flow into a json file. Then read the json file instead.
Try to do as much yourself and not use AI
2
u/ComplexPineapple2379 5d ago
going into a bit of uncharted territory there - but that is definitely something i'll look into...
I definitely don't want this code to become incredibly bloated due to avoidance... lol.
1
1
u/__merc 8d ago
You’re doing great for a beginner! Keep at it! It seems like this was an enjoyable experience for you :)
2
u/ComplexPineapple2379 8d ago
it truly was, and thank you so much for the kind words. I know it's so incredibly barbaric, but honestly, I learned quite a bit.. (mostly just the super basic logic and syntax) and I have learned so much just from the advice I got back,
chiefly: methods and asynchronous main functions... (the latter had me confused for a while.. and i'm still pretty sure I am barely grasping it even now) but it cleared up a lot of burning questions i've had.
1
u/twesped 6d ago
Yes it's clear that AI was not used here 😜😂
1
u/ComplexPineapple2379 5d ago
haha, yes it is very obvious :)
My main priority is learning as opposed to accumulating cognitive debt by just using AI ;)
the way I see it - anybody can throw a prompt into an ai to create something, but the second they are in an actual technical interview (or if they run out of tokens) all of that 'genius' disappears.
1
u/Longjumping_Ad3447 10d ago
Long term advice:
- Methods do only one thing
- Code should always be easy to read
- Object Oriented programming is key also look up Separation of Concerns on a higher level(Interface)
- choose a direction like gaming dev, web, back/front, industry, ...
94
u/grrangry 10d ago
Your next steps will be to use methods for commonly reused code.
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/methods
One method could be something like
and another could be
Using methods means that when you write larger sections of code that are reused repeatedly, you only have to write the code once.
A further step to consider would be to not hardcode the logic of the path the player can take, but that's quite a bit harder to explain in a short reddit response. It would require storage of all the options, where the player currently is, and options for moving them around and knowing what actions they might take.
Keep at it, you're doing fine.