C
C#2mo ago
Silk&Song

What parts of these should i put in functions?

Im a beginner so i dont know where to begin
84 Replies
Jimmacle
Jimmacle2mo ago
you should break code into functions based on some logical task that is getting done for example, attacking or defending could be an Attack or Defend function
TheRanger
TheRanger2mo ago
they could make a single class called Human that has the stats defined as properties, and create 2 instances of that class for player and enemy follow the DRY principle
Silk&Song
Silk&SongOP2mo ago
put all defense logic in a function? some of the attacking code needs the defense code could you show an example
TheRanger
TheRanger2mo ago
First, do u know how to make a class?
Silk&Song
Silk&SongOP2mo ago
no
Anton
Anton2mo ago
There are 2 easy rules: 1. Group related data into classes or structs 2. Make functions out of repeating code
TheRanger
TheRanger2mo ago
Is that a school/uni project?
Silk&Song
Silk&SongOP2mo ago
no But im planning to add more to it
Anton
Anton2mo ago
Also, send data as parameters, don't use globals
TheRanger
TheRanger2mo ago
first you should learn what classes are
Anton
Anton2mo ago
Then there are more considerations: 1. Conditions or checks getting too involved or too nested -> pull out a function 2. Same code done on multiple pieces of data -> use an array and a loop 3. Higher and lower level operations mixed up in a single function -> pull out more functions so it's easier to reason about These are the basic things you should master
TheRanger
TheRanger2mo ago
dont think fortnite that has 100 players declare their variables like this
int player1Power = 100;
int player1Health = 100;

int player2Power = 100;
int player2Health = 100;

int player3Power = 100;
int player3Health = 100;
and so on
int player1Power = 100;
int player1Health = 100;

int player2Power = 100;
int player2Health = 100;

int player3Power = 100;
int player3Health = 100;
and so on
they use the power of object orientation, and C# is an object oriented level
Anton
Anton2mo ago
Note: don't actually get too deep into OOP as a beginner, it's going to be overwhelming unless you know the basics I mentioned above
TheRanger
TheRanger2mo ago
classes atleast should be beginner friendly its not like theyre gonna use interface or abstract classes
Anton
Anton2mo ago
Well that's how you structure data public fields As a beginner, that's pretty much what you should go for by default
TheRanger
TheRanger2mo ago
you could start checking out the links below $helloworld to start learning the basics of C#
Silk&Song
Silk&SongOP2mo ago
I did in codeacademy
TheRanger
TheRanger2mo ago
it didnt teach you what class is?
Silk&Song
Silk&SongOP2mo ago
its teaching abstraction next
TheRanger
TheRanger2mo ago
without teaching what a class is first?
Anton
Anton2mo ago
learn that it's like one of the most important things what an algorithm is and what an abstraction is
Silk&Song
Silk&SongOP2mo ago
ngl I dont really understand algorithims at all
Anton
Anton2mo ago
they're related in many ways
Silk&Song
Silk&SongOP2mo ago
yes
Anton
Anton2mo ago
algorithm means input data, steps to transform it, and output data abstraction basically means giving names to a group of operations or data a variable is an abstraction for accessing a piece of memory it has a name, and it lets you do something indirectly — interact with computer memory through the name
Silk&Song
Silk&SongOP2mo ago
it seems to be much more complex that that
Anton
Anton2mo ago
it is just this interface + implementation = algorithm that's me rephrasing the same sentence people may start talking about classes and OOP when they hear "abstraction" but classes are not required for it
Silk&Song
Silk&SongOP2mo ago
so its just making steps to solve a problem and transfering the steps to code?
Anton
Anton2mo ago
That's called solving a problem by writing a program. Algorithm is more or less the product of this It's a bit more general Like, it doesn't have to exist in code It's more the idea of a sequence of steps than a concrete program so an algorithm is basically just the steps
Silk&Song
Silk&SongOP2mo ago
im going to put teh attack and defend in there own functions but i feel like its going to cause errors
Anton
Anton2mo ago
how so?
Silk&Song
Silk&SongOP2mo ago
this code
else if (enemyChoice == 1)
{
if (enemyDefendTR <= 0 & enemyCooldown == 0)
{
enemyDefendTR += 2;
enemyDefense += 2;
Console.WriteLine("The enemy defended and gained 2 defense points!");
Console.ReadKey();
}
else if (enemyDefendTR >= 1 | enemyCooldown == 1)
{
Console.WriteLine($"The enemy attacked and dealt {enemyAttack} damage to you! ");
yourHealth -= enemyAttack - playerDefense;
Console.ReadKey();
if (playerDefenseTR > 0)
{
playerDefenseTR--;

}
else if (playerDefenseTR >= 0)
{

}
else if (enemyChoice == 1)
{
if (enemyDefendTR <= 0 & enemyCooldown == 0)
{
enemyDefendTR += 2;
enemyDefense += 2;
Console.WriteLine("The enemy defended and gained 2 defense points!");
Console.ReadKey();
}
else if (enemyDefendTR >= 1 | enemyCooldown == 1)
{
Console.WriteLine($"The enemy attacked and dealt {enemyAttack} damage to you! ");
yourHealth -= enemyAttack - playerDefense;
Console.ReadKey();
if (playerDefenseTR > 0)
{
playerDefenseTR--;

}
else if (playerDefenseTR >= 0)
{

}
attacks in else if because I gave them a defense cooldown so if it it selects defense again it will still attack so should i still put that in the defense fuction? then do I put the player attack and the enemy attack in the same function? how will the ennemy defend when its in antoher function and idk if the turns will work
Anton
Anton2mo ago
honestly I have no idea what you said
Jimmacle
Jimmacle2mo ago
you need to structure your code in a way that the information the function needs is accessible
Anton
Anton2mo ago
Yes, start from pulling every variable that represents a piece of game state into a single class, this sounds fair public fields your functions can take in the game state as a parameter
Silk&Song
Silk&SongOP2mo ago
I dont know how to do that
Jimmacle
Jimmacle2mo ago
that's part of software development, taking a problem and turning it into smaller pieces that can connect together you just have to practice it
Silk&Song
Silk&SongOP2mo ago
so how do you do that
Anton
Anton2mo ago
you see related data, you group it. you see code that repeats, you make a function that takes in what it needs to do the thing. there's more, like recognizing when an abstraction does multiple separate things and restructuring it into multiple abstractions that communicate but start from those two
Silk&Song
Silk&SongOP2mo ago
ok im going to tdo that and see if i get errors Ok when do you use classes
Jimmacle
Jimmacle2mo ago
whenever you have data and behavior that can be meaningfully treated as one "thing"
Anton
Anton2mo ago
when you see related data
Silk&Song
Silk&SongOP2mo ago
breaks code since i dont really know how to implement classes though i know how to make them
Anton
Anton2mo ago
public class GameState
{
public int PlayerHealth;
// ...
}
public class GameState
{
public int PlayerHealth;
// ...
}
in main you now do
var state = new GameState();
state.PlayerHealth = 100;
//...
var state = new GameState();
state.PlayerHealth = 100;
//...
and replace playerHealth for state.PlayerHealth
Silk&Song
Silk&SongOP2mo ago
GitHub
Turn-Based-C-Console-App/turnbasedc#/Program.cs at master · TakenGi...
My turn based c# console app for practicing code and just having fun making new mechanics - TakenGit2/Turn-Based-C-Console-App
TheRanger
TheRanger2mo ago
Nice but why make a class called Enemy if it behaves the exact same as the Player class u could just do Player Enemy = new Player();
Silk&Song
Silk&SongOP2mo ago
so they can have diffrent special abilites but that dosent work because to make the abilty worj it has to be in both classes
TheRanger
TheRanger2mo ago
u have methods in both classes that do the exact same thing This is where you can create a parent class for both so you can inherit these methods from the parent class so you dont have to write them down twice
Silk&Song
Silk&SongOP2mo ago
i just made one befroe global stats wait how
MODiX
MODiX2mo ago
Angius
REPL Result: Success
abstract class Base
{
public void Speak()
{
Console.WriteLine("Unga bunga");
}
}

class Foo : Base
{}

class Bar : Base
{}

var f = new Foo();
var b = new Bar();
f.Speak();
b.Speak();
abstract class Base
{
public void Speak()
{
Console.WriteLine("Unga bunga");
}
}

class Foo : Base
{}

class Bar : Base
{}

var f = new Foo();
var b = new Bar();
f.Speak();
b.Speak();
Console Output
Unga bunga
Unga bunga
Unga bunga
Unga bunga
Compile: 438.858ms | Execution: 75.058ms | React with ❌ to remove this embed.
TheRanger
TheRanger2mo ago
havent seen Unga Bunga for a while 😄
Angius
Angius2mo ago
My go-to lmao
TheRanger
TheRanger2mo ago
look up Inheritance
Silk&Song
Silk&SongOP2mo ago
i tried but i just get errors like theseInvalid token '(' in class, record, struct, or interface member declaration The name 'Enemy.Attack' does not exist in the current context. The name 'Attack' does not exist in the current context. Tuple must contain at least two elements. Invalid token ';' in class, record, struct, or interface member declaration Argument 2: cannot convert from 'Enemy' to 'ConsoleAppTurnBased.Player' Argument 2: cannot convert from 'Enemy' to 'ConsoleAppTurnBased.Player' Argument 2: cannot convert from 'Enemy' to 'ConsoleAppTurnBased.Player' Argument 2: cannot convert from 'Enemy' to 'ConsoleAppTurnBased.Player' Argument 2: cannot convert from 'Enemy' to 'ConsoleAppTurnBased.Player' Argument 2: cannot convert from 'Enemy' to 'ConsoleAppTurnBased.Player' Argument 2: cannot convert from 'Enemy' to 'ConsoleAppTurnBased.Player' Argument 2: cannot convert from 'Enemy' to 'ConsoleAppTurnBased.Player' Argument 2: cannot convert from 'Enemy' to 'ConsoleAppTurnBased.Player' There is no argument given that corresponds to the required parameter 'player' of 'GlobalStats.takeThrust(int, Player)' There is no argument given that corresponds to the required parameter 'player' of 'GlobalStats.takeThrust(int, Player)' There is no argument given that corresponds to the required parameter 'player' of 'GlobalStats.takeThrust(int, Player)' There is no argument given that corresponds to the required parameter 'player' of 'GlobalStats.takeThrust(int, Player)' There is no argument given that corresponds to the required parameter 'player' of 'GlobalStats.takeThrust(int, Player)' Argument 1: cannot convert from 'Enemy' to 'ConsoleAppTurnBased.Player' Argument 1: cannot convert from 'Enemy' to 'ConsoleAppTurnBased.Player' Argument 2: cannot convert from 'ConsoleAppTurnBased.Player' to 'Enemy' 'Player' does not contain a definition for 'youcantStab' and no accessible extension method 'youcantStab' accepting a first argument of type 'Player' could be found (are you missing a using directive or an assembly reference?) Argument 1: cannot convert from 'ConsoleAppTurnBased.Player' to 'Enemy' Argument 1: cannot convert from 'ConsoleAppTurnBased.Player' to 'Enemy'
Anton
Anton2mo ago
GitHub
Turn-Based-C-Console-App/turnbasedc#/Enemy.cs at master · TakenGit2...
My turn based c# console app for practicing code and just having fun making new mechanics - TakenGit2/Turn-Based-C-Console-App
Anton
Anton2mo ago
why? why d instead of Defense? why do you have private fields? use named arguments in the constructor, or use required and public fields
Silk&Song
Silk&SongOP2mo ago
wym
Anton
Anton2mo ago
there's no point to inheritance if the enemy doesn't add its own fields to the shared set of fields and even then, inheritance is bad, which you will learn eventually after you've screwed yourself with it a couple of times
Silk&Song
Silk&SongOP2mo ago
i made class globalstats and i put all stats in there and then i made player and enemy inherit
Anton
Anton2mo ago
doesn't make sense, just give them each a globalstats field
Silk&Song
Silk&SongOP2mo ago
i did
Anton
Anton2mo ago
do some simple procedural programming specific static functions for enemy, specific ones for the player
Silk&Song
Silk&SongOP2mo ago
I did before i tried to do the inheritance stuff
Anton
Anton2mo ago
ok stick to that it's better especially when you're a beginner
Silk&Song
Silk&SongOP2mo ago
yeah i did that in github
Anton
Anton2mo ago
well maybe you didn't push or something there's nothing of sorts in the repo you linked I just see duplicated code
Silk&Song
Silk&SongOP2mo ago
well i already did that before i started trying to use oop
Anton
Anton2mo ago
ok, keep doing procedural, don't do oop
Silk&Song
Silk&SongOP2mo ago
why
Anton
Anton2mo ago
because you don't need it yet and it's going to confuse you
Silk&Song
Silk&SongOP2mo ago
well when am i going to need it
Anton
Anton2mo ago
when you understand why you would want to encapsulate data when you're able to see good abstractions when you need polymorphism When there's lots of public data in a single place, it's going to get difficult to ensure you only change it in some well defined way encapsulation will help with that put bits of data in containers that provide a well-defined set of ways to access it or modify it encapsulation basically means that the data may only be changed through those methods and not directly and the type that houses the methods and the data is referred to as an abstraction polymorphism is for when you want to do the strategy pattern think an effect that triggers on pickup or a function that decides what action to take it can be a multitude of things like on pickup it might add a stat, might create a passive effect, might apply a curse you can model this with a switch but the benefit to using an interface for this is that the implementation could have its owen data in a switch, you'd have to store and pass along that data for either all implementations, or the current one but most of you code should be procedural now, it could be instance methods instead of static methods, but it's mostly going to be just lists of steps of stuff to do with some context
Silk&Song
Silk&SongOP2mo ago
While im begginer
Anton
Anton2mo ago
in general I'm not a beginner 95-ish percent of my code is procedural
Silk&Song
Silk&SongOP2mo ago
isnt c# whole thing is oo?
Anton
Anton2mo ago
well c# being oop just means it has syntax for these things it doesn't mean you have to use it when it's not going to be useful you can do oop without the syntax it's just less convenient people do oop in C the only thing that doesn't have an exact equivalent is just private data I think you have to jump through hoops for that in C
Silk&Song
Silk&SongOP2mo ago
sym von nbys bupy xczzlyhn julugynylm mi nbun qihn qile
TheRanger
TheRanger2mo ago
where? the Attack method for example the parameters can just have the type of the parent class the only other difference i see in its body is if (paraChance == 1 & paraTurns > 0) and if (paraChance == 4 & paraTurns > 0) this can be replaced with for example if (paraChance == GetParaChance() && paraTurns > 0), the GetParaChance can be an abstract or a virtual method that can get overridden in the subclasses, returning a different value for each you can even divide your code in that method into multiple methods for instance extracting the whole switch statement of switch (AttackNumbers) into a method called PrintAttackNumbers() so even if you want to keep the method in both subclasses, atleast extract a piece of code like the switch (AttackNumbers) into a method, and call it on the Attack method of both classes
Angius
Angius2mo ago
&&
Silk&Song
Silk&SongOP2mo ago
cmhn w# qbify nbcha cm ii?
Angius
Angius2mo ago
hgag ;ok; 'asoliu 'klksf&* sd!
Silk&Song
Silk&SongOP2mo ago
F alkq rkabopqxka elt jxkv ibqqbop afa vlr bkzlab? rpb 3 pl f zxk rkabopqxka wym? Ouqx rhe... ixkj kh ijkfyt qii veh Y huqbb owuj ed oekh tkcr qiydzyzyzyzkdd i will just make an class for abilites
TheRanger
TheRanger2mo ago
what did i just read
public class Character
{
public void Attack(Character unitthatsgetAttacking, Character player, Character enemy)
{
// some code
if (paraChance == GetParaChance() & paraTurns > 0)
{
enemy.paralyzeCheck();
}
// rest of code
}
public abstract int GetParaChance();
}
public class Enemy : Character
{
public override int GetParaChance()
{
return 4;
}
}
public class Player : Character
{
public override int GetParaChance()
{
return 1;
}
}
public class Character
{
public void Attack(Character unitthatsgetAttacking, Character player, Character enemy)
{
// some code
if (paraChance == GetParaChance() & paraTurns > 0)
{
enemy.paralyzeCheck();
}
// rest of code
}
public abstract int GetParaChance();
}
public class Enemy : Character
{
public override int GetParaChance()
{
return 4;
}
}
public class Player : Character
{
public override int GetParaChance()
{
return 1;
}
}
since Player and Enemy inherit from class Character, u can pass instances of Player or Enemy to the Parameter of type Character

Did you find this page helpful?