Null reference exception was unhandled in c# - c#

For example in section a: i have a random number and in the section b: i want to multiply that random number by 2 but it has to be in a function and then section c: has to add 10 and so on. I guess this is very simple for you guys. and i am sure i am writing very silly codes but i am not a programmer.
thanks.
class Program
{
static void Main(string[] args)
{
Boot boot = new Boot();
Game game = new Game();
Console.WriteLine("Matrix Lengte: " + game.Matrix);
Console.WriteLine("Lengte boot: " + boot.Lengte);
Console.ReadLine();
class Game
{
private Boot boot;
private int matrix;
public int Matrix
{
get { return matrix; }
set { matrix = value; }
}
public Game()
{
matrix= boot.Lengte*2;
}
internal Boot Boot
{
get { return boot; }
set { boot = value; }
}

By default fields have their default values, which is null for reference types. So, just add boot initialization:
public Game()
{
boot = new Boot(); // or pass via constructor parameter
matrix = boot.Lengte * 2;
}

Related

Try to display a int through a static field, but return a weird value (C#)

I'm trying to cut down on how much duplication I have on my code, so I decided to make one of my classes a static class since I decided that its data should really be shared with everyone. Here's the static method below:
// A static class, that holds all object's coordinates, and methods to return & update their values.
internal static class Coordinate
{
private static int[,] PlayerCoordinate { get; set; }
public static int[,] GateCoordinate { get; }
public static int[,] FountainCoordinate { get; }
static Coordinate() // FIRST VALUE IS X (column), SECOND VALUE IS Y (row).
{
PlayerCoordinate = new int[,] { { 0, 0 } };
GateCoordinate = PlayerCoordinate; // Just starts off in the same place as player.
FountainCoordinate = new int[,] { { 2, 0 } };
}
// A static method, that sends the data of all object coordinates, deconstructed into seperate ints.
public static int PlayerColumn() { return PlayerCoordinate[0, 0]; }
public static int PlayerRow() { return PlayerCoordinate[0, 1]; }
public static int GateColumn() { return GateCoordinate[0, 0]; }
public static int GateRow() { return GateCoordinate[0, 1]; }
public static int FountainColumn() { return FountainCoordinate[0, 0]; }
public static int FountainRow() { return FountainCoordinate[0, 1]; }
// Updates the coordinates of the player.
public static void UpdatePlayerCoordinate(int column, int row) { PlayerCoordinate = new int[,] { { column, row } }; }
}
The main issue comes in from my GameManager class. On the console, the beginning section should print out "You are the room at (Column=0, Row=0), but it prints this instead:
Here is the code for my GameManager class:
internal class GameManager
{
private bool IsGameOver;
private Player Player;
private Updater Updater;
// Don't need to call Fountain or Coordinate since they're static
public GameManager()
{
IsGameOver = false;
Player = new();
Updater = new();
}
public void RunGame()
{
while (!IsGameOver)
{
Console.WriteLine("----------------------------------------------------------");
Updater.DisplayPlayerPosition(); // This is the main line that I'm having issues with as of right now. All other functions past this are another problem.
Updater.DisplayPlayerSenses();
string playerInput = Player.GetInput();
Updater.MovePlayer(playerInput);
IsGameOver = Updater.CheckForWin();
}
}
}
And just to make sure, here is the code from my updater class, with the specific method that I'm having issues with:
internal class Updater
{
// No fields
// Default constructor
// Gets the text to show the player his current position.
public void DisplayPlayerPosition() // This is the method that I'm having issues with.
{
Console.WriteLine($"You are in the room at (Column={Coordinate.PlayerColumn}, Row={Coordinate.PlayerRow})");
}
...
I'm fairly new to the static keyword so I believe that I may be missing smth. I personally believe that it's because the class itself hasn't been initialized (like I haven't called the constructor for the Coordinate class, and apparently you can't call a static constructor anyways), but that's just me. If I could get any help, I'd greatly appreciate it!
PlayerColumn() and PlayerRow() are methods, but you are accesing them in the WriteLine statement as if they are properties.
Update your WriteLine to:
Console.WriteLine($"You are in the room at (Column={Coordinate.PlayerColumn()}, Row={Coordinate.PlayerRow()})");

Variable Values are not getting Updated

I have 3 class files. First is the Main class, second is the Ship class, and the third is the Skill class. All values are added to my Main class file. I have a method where the parameters should be the value in my Main class. Please see below:
public class Skill
{
public double _capInc;
public int bscEng, advEng, expEng;
// engineering
public double capInc(int bsc, int adv, int exp)
{
if(bsc == 5 && adv == 5 && exp == 4)
{
_capInc = 0.48;
}
return _capInc;
}
The values of int bsc, int adv, and int exp should be the value of bscEng, advEng, & expEng which was set in my Main class
skill.bscEng = 5;
skill.advEng = 5;
skill.expEng = 4;
But when I try to run the method in my Ship class, values are different
public class Ship
{
Skill skill = new Skill();
public double capacitor;
public double totalCap()
{
double _totalCap = capacitor * skill.capInc(skill.bscEng, skill.advEng, skill.expEng);
Console.WriteLine(skill.bscEng + " bscEng inside totalCap");
return _totalCap;
}
This is the result when I run my Main class
class MainClass
{
public static void Main (string[] args)
{
Ship ship = new Ship();
Skill skill = new Skill();
skill.bscEng = 5;
skill.advEng = 5;
skill.expEng = 4;
Console.WriteLine(skill.bscEng + " bscEng in Main");
Console.WriteLine(ship.totalCap());
}
}
Result:
5 bscEng in Main
0 bscEg inside totalCap
0
You should assign the values to skill in your ship object.
Example:
ship.skill.bscEng = <yourValue>;
ship.skill.advEng = <yourValue>;
ship.skill.expEng = <yourValue>;
As I said in the comments you need to pass the skill object to the ship object. I've also added an constructor to both classes. I don't know what you really want to do and the code is weird but here's a working solution:
class MainClass
{
public static void Main (string[] args)
{
Skill skill = new Skill(5, 5, 4);
Ship ship = new Ship(skill);
Console.WriteLine(skill.bscEng + " bscEng in Main");
Console.WriteLine(ship.totalCap());
}
}
public class Skill
{
public Skill(int bscEnd, int advEng, int expEng)
{
this.bscEng = bscEnd;
this.advEng = advEng;
this.expEng = expEng;
}
public double _capInc;
public int bscEng, advEng, expEng;
// engineering
public double capInc()
{
if(bscEng == 5 && advEng == 5 && expEng == 4)
{
_capInc = 0.48;
}
return _capInc;
}
}
public class Ship
{
public Ship(Skill skill)
{
Skill = skill;
capacitor = 1.0; // TODO
}
private Skill Skill;
public double capacitor;
public double totalCap()
{
double _totalCap = capacitor * Skill.capInc();
Console.WriteLine(Skill.bscEng + " bscEng inside totalCap");
return _totalCap;
}
}
Output should be:
5 bscEng in Main
5 bscEng inside totalCap
0,48

How to change a variable from a called method

I am writing a bit of a dungeon crawler as I learn my way through c#. I am using visual studio and the application is a "Console App (.NET Framework)". My problem is that I use a method (a fighting sequence) that can be called from the Main method. However I want it to be able to change the balance variable in my Main method.
static void Main(string[] args )
{
int balance = 0;
battle(balance);
}
static void battle(int balance);
{
balance = balance + 30;
}
// I want the balance in the battle to change the balance in the Main.
You need to pass the value by reference. To pass the value by reference, change the following line:
static void battle(int balance)
to
static void battle(ref int balance)
Then you can call the function as follows:
battle(ref balance);
Alternatively, you can just change your function to return the balance as a result, as follows
static void Main(string[] args )
{
int balance = 0;
balance += battle();
}
static int battle();
{
return 30;
}
I used 30 because this is all your original function does.
You can return the value from the method battle(int balance)
class Program
{
static void Main(string[] args)
{
int balance = 0;
balance = battle(balance);
}
private static int battle(int balance)
{
balance = balance + 30;
return balance;
}
}
Or you can create a class-scope variable
class Program
{
private static int balance;
static void Main(string[] args)
{
battle(balance);
}
private static void battle(int balance)
{
balance = balance + 30;
}
}
While using ref is one possible way to do this (see Kibbee's answer for a example), another way that will help you scale up in the future is put all of your variables that relate to the player in to a Player class that can be passed in to methods.
This allows more variables to be added in the future and you don't need to modify the functions to add the extra parameter.
class Player
{
int Health {get; set;}
int Balance {get; set;}
}
static void Main(string[] args )
{
Player player = new Player();
player.Balance = 0;
player.Health = 50;
Battle(player);
}
static void Battle(Player player);
{
player.Balance = player.Balance + 30;
player.Health = player.Health - 5;
}
This also lets you expand in the future if you want your game to have more than one person in the party.
static void Main(string[] args )
{
Player player1 = new Player();
player1.Balance = 0;
player1.Health = 50;
Player player2 = new Player();
player2.Balance = 500;
player2.Health = 100;
Battle(player1);
CastHeal(player1, player2)
}

Knights Tour recursive C# Im getting something wrong in my way of doing the stuff

class Knight
{
public static readonly double LegalDistance = Math.Sqrt(5);
public Stack<Field> Steps { get; set; }
private static readonly List<Field> board = Board.GameBoard;
private static List<Field> fields;
private static readonly Random random = new Random();
private static readonly object synLock = new object();
public Knight(Field initial)
{
Steps = new Stack<Field>();
Steps.Push(initial);
}
public void Move()
{
Field destination = Choose();
if (destination == null)
{
return;
}
Console.WriteLine("Moving from " + GetPosition().GetFieldName() + " to " + destination.GetFieldName());
Steps.Push(destination);
}
public Field Back()
{
Field from = Steps.Pop();
Console.WriteLine("Moving back from " + from.GetFieldName() + " to " + GetPosition().GetFieldName());
return from;
}
public Field Choose()
{
List<Field> legalMoves = Behaviour();
legalMoves.RemoveAll(field => Steps.Contains(field, new FieldValueComparer()));
if (legalMoves.Count == 0)
{
return null;
}
Field theChoosenOne;
int index;
lock (synLock)
{
index = random.Next(0, legalMoves.Count);
}
theChoosenOne = legalMoves.ElementAt(index);
return theChoosenOne;
}
private List<Field> Behaviour()
{
fields = new List<Field>();
fields.AddRange(board);
for (int i = fields.Count - 1; i >= 0; i--)
{
double actualDistance = fields[i].GetDistance(GetPosition());
if (!actualDistance.Equals(LegalDistance))
{
fields.Remove(fields[i]);
}
}
return fields;
}
public List<Field> GetSteps()
{
return Steps.ToList();
}
public Field GetPosition()
{
return Steps.Peek();
}
}
So this is how I'd do the stuff. The problem is, I am missing some key functionality, because on low given stepcount it backtracks to the start, on high stepcount, it causes StackOverFlow.
Here are some other functions to let you understand what I want to do:
Calculating distance:
public double GetDistance(Field other)
{
return Math.Sqrt(Math.Pow(other.X - X, 2) + Math.Pow(other.Y - Y, 2));
}
Finding the path:
class PathFinder
{
public static void FindPath(Knight knight)
{
if (knight.Steps.Count != 20)
{
knight.Move();
FindPath(knight);
knight.Back();
}
}
}
Your path search is essentially random walk. On large board, this may take a while anyway.
Now about StackOverflow: notice that you don't push anything on Move() when there are no places to go. So, on recursive call to FindPath() there still will be the same knight.Steps.Count, the same position, the same null return on Choose()... and so on, until you're out of stack space.
Obvious fix would be to add bool return value to Move() indicating if there was any move. Unless there is actual reason behind using random moves, more deterministic search algorithm is recommended.

Inheritance - storing objects list<class> with loops C#

I'm stuck one an exercise which is very important to understand for my soon come final exam, in a basic C# course.
I have an issue that I can't describe in words. So I'll show you with code and perhaps then you might help me.
I've been stuck on this, not being able to solve it, for a long time. Cuz of that, I don't want any copy paste code. I want to understand it. So please enlighten me where I've failed.
Explanation what I want to do.
I want to create a dart game 501. So first I add players, they throw their darts, you get the score after each turn announced, then when one player reach 501 points, the game announce the winner and all of his throws.
My idea of approaching the problem is to have an add player loop, which terminates (I got this fixed already).
Once you done creating the players(list elements), then you'll execute the methods with a foreach loop running all the players in the player list, executing the objects one at a time and finally Here is my real problem: storing all their scores in another list.
Here we go with the code
The list.
private List<Player> players = new List<Player>(); //This list is fine
Here is the loop.
foreach (Player dartThrows in players) //My loop
{
dartThrows.DoThrow();
dartThrows.GetScore();
}
SubClass1(named Player)
public List<Darts> dartList = new List<Darts>(); //<--HERE IS THE PROBLEM
Just some random constructors and methods.
The throw method. It's not an issue but I typed it down to give you an idea
public void DoThrow()
{
var tries = 3;
for (int i = 0; i < tries; i++)
{
//No problems here just int read-user input data
}
AddDarts(int a, int b, intc)
}
Here lies all my problems, it would make my life so much easier if this could get solved.
public void AddDarts(Darts toDartList)
{
dartList.Add(toDartList);
}
SubClass2 (Darts)
Here are my constructors
private int dartOne;
private int dartOne;
private int dartOne;
Here is my method
public Darts(int DartOne, int DartTwo, int DartThree)
{
dartOne = DartOne;
dartTwo = DartTwo;
dartThree = DartThree;
}
Best regards Marcus Johansson
Here is my full program
class Program
{
static void Main(string[] args)
{
Game game = new Game();
game.PlayGame();
}
}
class Game
{
private List<Player> players = new List<Player>();
private List<Player> computers = new List<Player>();
public void AddPlayer(string newPlayers)
{
players.Add(new Player(newPlayers));
}
public void AddComputer(string newComputer)
{
computers.Add(new Player(newComputer));
}
static string UpperCaseFirst(string s)
{
if (string.IsNullOrEmpty(s))
{
return string.Empty;
}
return char.ToUpper(s[0]) + s.Substring(1);
}
public void PlayGame()
{
bool noWinner = false;
bool stopLoop = false;
Console.WriteLine("<<<WELCOME TO DART 501>>>");
Console.WriteLine("\nPress [S] to start game!");
Console.Beep();
Console.ReadLine();
Console.Clear();
do
{
Console.WriteLine("Enter name of players and type [D]ator for adding NPC\nType [S]top to start the game");
string addPlayer = Console.ReadLine();
string FirstUpperLetter = UpperCaseFirst(addPlayer);
if (FirstUpperLetter == "Stop" || FirstUpperLetter == "S")
{
stopLoop = true;
}
if (FirstUpperLetter == "D" || FirstUpperLetter == "Dator")
{
string computer = FirstUpperLetter;
AddComputer(computer);
}
else
{
AddPlayer(FirstUpperLetter);
}
} while (stopLoop == false) ;
players.RemoveAt(players.Count - 1);
do
{
Console.Clear();
foreach (Player arrowThrows in players)
{
noWinner = true;
Console.WriteLine("\n~~~Starting Round~~~~");
arrowThrows.DoThrow();
Console.WriteLine("This round you got {0}", arrowThrows.CalculatePoints());
if (arrowThrows.Score > 501)
{
Console.Clear();
Console.WriteLine("<<<WE HAVE A WINNER>>>");
System.Threading.Thread.Sleep(500);
Console.WriteLine("...The winner is: ");
System.Threading.Thread.Sleep(1000);
Console.WriteLine("{0} He made these epic throws: ", arrowThrows.Name);
foreach(Arrows finalResult in arrowThrows.arrowList)
{
Console.WriteLine(finalResult);
Console.ReadLine();
}
noWinner = false;
}
}
foreach (Player computerThrows in computers)
{
computerThrows.RandomThrow();
System.Threading.Thread.Sleep(500);
}
}while(noWinner == true);
}
}
class Player
{
public List<Arrows> arrowList = new List<Arrows>();
public List<int> ScoreBoard = new List<int>();
public Player() { }
public int Score { get; set; }
public Player(int score)
{
Score = score;
}
public string Name { get; set; }
public Player(string name)
{
Name = name;
}
public int RoundScore { get; set; }
public void RandomThrow()
{
Random rndComp = new Random();
Console.WriteLine("...Loading Npc_throw.exe");
System.Threading.Thread.Sleep(300);
int random1 = rndComp.Next(0, 60);
System.Threading.Thread.Sleep(300);
int random2 = rndComp.Next(0, 60);
System.Threading.Thread.Sleep(300);
int random3 = rndComp.Next(0, 60);
Console.WriteLine("Random computer got this random score {0}", random1 + random2 + random3);
arrowList.Add(new Arrows(random1, random2, random3));
}
public void DoThrow()
{
Console.WriteLine("###{0} make your throws###", Name);
var tries = 3;
for (int i = 0; i < tries; i++)
{
Console.WriteLine("\nEnter score for {0} arrow", i + 1);
string arrowScore = Console.ReadLine();
int addScore = int.Parse(arrowScore);
while(-1 > addScore || 61 < addScore)
{
Console.WriteLine("\nInvalid score! Enter a score between 0-60/n<<<You may type [R]andom or [R] for a random score>>>");
arrowScore = Console.ReadLine().ToUpper();
if (arrowScore == "R" || arrowScore == "RANDOM")
{
Random rnd = new Random();
addScore = rnd.Next(0, 60);
goto start;
}
else
{
addScore = int.Parse(arrowScore);
}
}
start:
ScoreBoard.Add(addScore);
}
ScoreBoard.ToArray();
arrowList.Add(new Arrows(ScoreBoard[0],ScoreBoard[1], ScoreBoard[2]));
}
public int CalculatePoints()
{
Score = ScoreBoard.Sum();
return Score;
}
public void AddArrows(Arrows toArrowList)
{
toArrowList.ToString();
arrowList.Add(new Arrows(ScoreBoard[0], ScoreBoard[1], ScoreBoard[2]));
}
}
class Arrows
{
private int arrowOne;
private int arrowTwo;
private int arrowThree;
public int score { get; set; }
public Arrows(int ArrowOne, int ArrowTwo, int ArrowThree)
{
arrowOne = ArrowOne;
arrowTwo = ArrowTwo;
arrowThree = ArrowThree;
}
public int GetScore()
{
return arrowOne + arrowTwo + arrowThree;
}
public override string ToString()
{
return string.Format("{0}-1:st arrow: {1}-2:nd arrow: {2}- 3:rd arrow: {3}", GetScore(), arrowOne, arrowTwo, arrowThree);
}
}
}
The problem with your approach, is your utilizing a List. This collection has no unique information, simply a grouping of data. Which would have me recommend either a Tuple, Dictionary, KeyValuePair, or a clean Data Model.
Without the requirements are approaches may not be viable. Your issue stems from persistence related issues. Your multiple inheritance title is also incorrect, C# only allows a single class to be inherited.
What I would potentially do would be:
public class Player
{
public string Name { get; set; }
public string Throw { get; set; }
public string Points { get; set; }
}
What this does, is incredibly beneficial. The above class represents a specific Model. When your method is called for a throw you apply said results. Then when you calculate the score you iterate through the List<Player> for a specific person or all and display the output.
I'm not going to write your application, but think of it like this:
Player Registers
Player Turn
Player Throws
Play Scored
Store Player Result
Repeat Steps two through five, three times.
Display Output: Player, Throw, Score, and Total Score
By utilizing that model, you hold the relative information for your outcome. This conceptual notion is important for Object Oriented Programming.
You can use a Dictionary to save scores for each player
Dictionary<Player, List<int>> playerScores = new Dictionary<Player, List<int>>();
playerScores.Add(player1, new List<int>()); //init dictionary with a new player
playerScores[player1].Add(number); //add a value to the list associated with the player
So each player has a list of scores.

Categories

Resources