C# - Calling a class I created in another class - c#

I have 3 classes in my program: Program, Board, and Square.
In program I'm creating a new board:
class Program
{
static void Main(string[] args)
{
Board b = new Board();
}
}
Now I'm looking for a way to call the Board I created here in my Square class.
Anyone have an Idea how to do this? (not to create a new Board in the Square class).
Edit:
I'm trying to create a simple mine-sweeper game.
In the Board class I have a two-dimensional array of Squars. then I creat in each part of the square array a new Square. Then the board is creating mines with the "AddMine" function in the Square class. I have deleted the way the board is choosing which square to set to a mine.
class Board
{
public Square[,] board;
public int n;
public Board()
{
Console.Write("Enter the nuber of rows on column(int): ");
n = int.Parse(Console.ReadLine());
board = new Square[n, n];
mines = (n * n) / 6;
for (int row = 0; row < board.GetLength(0); row++)
{
for (int col = 0; col < board.GetLength(1); col++)
{
board[row, col] = new Square(row, col);
}
}
board[row, col].AddMine();
}
}
In the Square class, at first it is setting is val to 0. After that when I'm calling The "AddMine" function from board, I need to add one to the val of each Square nearby the square who is set to mine.
class Square
{
public Board b;
private int row, col;
public int val;
private bool open;
public Square(int row, int col)
{
this.row = row;
this.col = col;
open = false;
val = 0;
}
public void AddMine()
{
#region set this to bomb (-9), nearby squars ++
val = -9;
b.board[row, (col + 1)].val++;
#endregion
}
}
The real question is how do I call the board array in the Board class in the Square class? because this way is not working, I get a 'System.NullReferenceException' error, I know it is because b is set to 'null', but I don't know to what to do so it will be able to see the Board from Main in Programe class.
All the answers I found in the internet is or to set a new Board, or to set a prorame class in the squarwe class, but because I'm setting a new board in a static function, it is not working.
Thanks to anyone for helping and I hope now the question is clearer.

As many have said you need to pass the reference to the board into the Square. You almost have it in your example, you just don't actually pass the board in.
Here's what your square class should look like.
class Square
{
public Board b;
private int row, col;
public int val;
private bool open;
public Square(Board board, int row, int col)
{
this.row = row;
this.col = col;
open = false;
val = 0;
**b = board;**
}
public void AddMine()
{
#region set this to bomb (-9), nearby squars ++
val = -9;
b.board[row, (col + 1)].val++;
#endregion
}
}
You received the null reference exception because you never actually set the board object so it was null when you tried to use it.
Then to edit your board example, this is how you would add the new squares.
class Board
{
public Square[,] board;
public int n;
public Board()
{
Console.Write("Enter the nuber of rows on column(int): ");
n = int.Parse(Console.ReadLine());
board = new Square[n, n];
mines = (n * n) / 6;
for (int row = 0; row < board.GetLength(0); row++)
{
for (int col = 0; col < board.GetLength(1); col++)
{
board[row, col] = new Square(this, row, col);
}
}
board[row, col].AddMine();
}
}
The "this" keywoard is just a reference to the calling object.
That should solve your problem, but I should note this is not usually considered the best practice. It seems your heading in the direction of tightly coupling your classes which can easily lead to smelly and unmaintainable code. You should look into tightly coupled vs loosely coupled code. A quick google search turned up this article
http://www.c-sharpcorner.com/uploadfile/yusufkaratoprak/difference-between-loose-coupling-and-tight-coupling/

Using passing object reference as a parameter in method you can achieve your desire output. Here is an example:
class Program
{
static void Main(string[] args)
{
Board d=new Board();
Square s=new Square();
s.m1(d);
}
}
class Board
{
int x=10;
}
class Square
{
public void m1(Board a)
{
Console.WriteLine(a.x);
}
Console.ReadLine();
}

Related

C# How can I change the value from static class?

So this is the Program cs. I want to change the value of int in my StaticClass.cs ** I want to delcare a printing sentence " How long do you want me to generate " then change the value of N in StaticClass.
class Program
{
static void Main(string[] args)
{
Constructor ct = new Constructor(StaticClass.n);
//ct.xmethod(StaticClass.n);
Console.ReadKey();
}
}
Here my constructor class. Method of Pascal Triangle
class Constructor
{
int[][] triangle = new int[StaticClass.n][];
public Constructor(int n)
{
xmethod(n);
}
public void xmethod(int n)
{
for (int row = 0; row < triangle.Length; row++)
{
//Each row is a subarray of length 1 greater than row number
triangle[row] = new int[row + 1];
//set the values in a row
for (int k = 0; k < triangle[row].Length; k++)
{
// if not first or last element in the row
if (k > 0 & k < triangle[row].Length - 1)
//set it to sum of the element above it
//and the one above and to the left
triangle[row][k] = triangle[row - 1][k - 1] + triangle[row - 1][k];
//otherwise this is an end point, set it to 1
else
triangle[row][k] = 1;
//display value
Console.Write(triangle[row][k] + "\t");
}
// Finished processing row-send cursor to next line
Console.WriteLine();
}
}
}
Here my StaticClass for the long of Pascal Triangle
class StaticClass
{
public const int n = 15;
// I want to change the value of N using the Console Writeline.
}
n needs to be updatable then instead of const use static; but Console.WriteLine() is not something you would use to change the value. You'll need to be more clear about what you want to do. Do you want someone to input the value of n - with a Console.ReadLine?
So ... from what I gather -- I think you want to change your Main to write your question: " How long do you want me to generate " then read the line for user input. Then print your triangle. Something like :
static void Main(string[] args)
{
Console.WriteLine("How long do you want me to generate? ");
int inNum = int.Parse(Console.ReadLine());
Constructor ct = new Constructor(inNum);
Console.ReadKey();
}
Then from what I see ... your Constructor needs to change:
public Constructor(int n)
{
triangle = new int[n][];
xmethod(n);
}
You cannot change the value of a const. https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/constants
Use a static property instead.
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members
static class StaticClass
{
public static int n = 15;
// I want to change the value of N using the Console Writeline.
}
Make your public const field a public static property instead:
public static int N { get; set; } = 15;
Change it like
StaticClass.N = 16;
You said "change it with WriteLine" - WriteLine outputs things, it doesn't change thing. Perhaps you meant ReadLine:
Console.WriteLine("How many levels? ");
string input = Console.ReadLine();
StaticClass.N = int.Parse(input);
Do please find a better name for StaticClass; classes should be named for what they represent in a more real world sense (like.. Configuration?) not what they are in a C# sense (yes, it's a static class, but it doesn't mean we should call it that)

Using the value in one array to set the object in another

I am stuck trying to figure out how to use the values of one array of numbers to initialize a second array of objects. This might not be the most effective way to do something like this in a real program, but I am just trying to understand how to create a relationship between two different arrays.
The first array is just a randomly generated array holding values 0,1 or 2. The second array is an array of Occupant objects. Each occupant has an occupant id that will be either 0, 1 or 2. I am trying to generate the second array of occupants by copying the values of first array and then initializing the second based on the occupant id.
Nothing I have tried will compile, and I can't think of anything else on my own except writing a million if statements. Surely there must be a simple solution I am missing. Any help you can offer will be greatly appreciated.
FYI: Occupant is the base class, three classes derive from it, each with a unique id number.
static public class Board
{
static public Occupant[,] board = BoardGen();
static private Occupant[,] BoardGen()
{
Random myRandom = new Random();
int[,] setup = new int[10, 10];
for (int i = 0; i < setup.GetLength(0); i++)
{
for (int j = 0; j < setup.GetLength(1); j++)
setup[i, j] = myRandom.Next(0, 3);
}
Occupant[,] populate = new Occupant[10,10];
// How to link setup to populate using the number to choose an occupant based on it's id number?
return populate;
}
}
}
I would suggest to fill-in the second table along with the first, or even better, completely forget about the first table:
static private Occupant[,] BoardGen()
{
Random myRandom = new Random();
// Not needed
// int[,] setup = new int[10, 10];
Occupant[,] populate = new Occupant[10, 10];
for (int i = 0; i < populate .GetLength(0); i++)
{
for (int j = 0; j < populate .GetLength(1); j++)
{
int randomSetup = myRandom.Next(0, 3);
switch (randomSetup)
{
case 0:
populate[i, j] = new Occupant_0(); // Derived Class with id=0
break;
case 1:
populate[i, j] = new Occupant_1(); // Derived Class with id=1
break;
case 2:
populate[i, j] = new Occupant_2(); // Derived Class with id=2
break;
default:
break;
}
}
}
return populate;
}
abstract class Master
{
public abstract int Id { get; }
}
class A : Master
{
public override int Id => 1;
}
class B : Master
{
public override int Id => 2;
}
class C : Master
{
public override int Id => 3;
}
Type[] types = new Type[] { typeof(A), typeof(B), typeof(C) };
int[] yourIds = new int[100];
Master[] generated = new Master[yourIds.Length];
for (int i = 0; i < yourIds.Length; i++)
{
generated[i] = (Master)Activator.CreateInstance(types[yourIds[i] - 1]);
}
I cannot understand your question completely, but this logic should fit your situation.
The point is that you can create an instance in runtime with the System.Activator and a System.Type.

How can I add objects Cbook to my class CBooks without using lists

Cbooks has an atribute "CTeam[] Teams" and it is of fixed size (8). If I want to add objects to it using this in the Main:
CBook A1 = new CBook("Title1", "Author1");
CBook A2 = new CBook("Title1", "Author2");
CBooks ArrayOfBooks = new CBooks(8);
ArrayOfBooks.Add(A1);
ArrayOfBooks.Add(A2);
then position 0 and 1 are ocuppied, and the positions from 2 to 7 are null. What I want to do is, using a variable "int aux=0", count the ocupied positions like this:
for (int k = 0; k < NumberOfTeams; k++)
{
if (Teams[k].Name=="")
Aux += 1;
}
So, Aux in this case would be 2, then I want to do "Teams[Aux] = A" so that A would be in the position 2 and now I should have three objects in my array. But I'm getting "Index out of bound"
Your implementation then should look similar to this:
public class Program
{
public static void Main(string[] args)
{
Element a = new Element("A");
Element b = new Element("B");
MyArray array = new MyArray(8);
array.Add(a);
array.Add(b);
Console.WriteLine(array.Count()); //2 Elements are in the array
}
}
//Sample element class.
public class Element{
public readonly String MyString;
public Element(String myString){
MyString = myString;
}
}
//Sample array class.
public class MyArray{
private readonly Element[] myArray;
private int count; //Use a property here
public MyArray(int size){
//Be careful -> check if size is >= 0.
myArray = new Element[size];
}
public bool Add(Element element){
if(myArray.Length == count) // return false if no more elements fit.
return false;
myArray[count] = element;
count++;
return true;
}
public int Count(){
return count;
}
}
So there is no need for creating an extra count loop. Your "count" variable in "MyArray" class holds always the correct value.
Anyway the implementation or use case of this code is a little bit clunky.
Why are you cant use directly a more safe list or something. That would be a better solution.
What do you need CBooks for? From what I understand, it's just an array of 8 CBook objects so why not use CBook[]?
CBook A1 = new CBook("Title1", "Author1");
CBook A2 = new CBook("Title1", "Author2");
CBooks[] ArrayOfBooks = new CBook[8];
ArrayOfBooks[0] = A1;
ArrayOfBooks[1] = A2;
int aux = 0;
for (int k = 0; k < ArrayOfBooks.Length; k++)
{
//break the loop because we know there are no more books
if (ArrayOfBooks[k] == null)
break;
aux++;
}
The question doesn't cover what the variables NumberOfTeams and Teams are for but could those be added to the implementation of CBook?

Adding a list into a list

My code works as expected except for when I add a playerHand, which is a list of cards, to a playerHands list, it changes all previous player hands in the list to the current playerHand.
My thought as to what is happening is that there is only one playerHand in memory which is constantly being updated with dealt cards. The items in playerHands list are simply pointing to that single playerHand.
How do I create multiple instances of playerHand so that each item in the playerHands list is unique?
Note: my initial reaction was to use Arrays instead of List, but as far as I can tell Arrays are old-school and deprecated in favor of List.
Solving my problem is my goal here but if there are any thoughts as to the direction I am taking with this program would be accepted.
using System;
using System.Collections.Generic;
namespace Blackjack
{
class Program
{
static void Main()
{
int numOfDecks = 2;
List<Cards> shoe = Deck.createDeck(numOfDecks);
Deck.shuffleDeck(shoe, numOfDecks);
Hand playerHand = new Hand();
Hands playerHands = new Hands();
//Test Hands
//Create ten hands of dealt cards
for (int i = 0 ; i < 10; i++)
{
playerHand.clearHand();
playerHands.addHand(playerHand);
for (int j = 0; j < 5; j++)
{
playerHand.addCard(shoe[j]);
shoe.RemoveAt(0); //delete card delt from shoe
}
}
//Display the cards in each of the hands
for (int i = 0; i < playerHands.hands.Count; i++)
{
Console.Write("Hand {0}: Cards: ", i);
for (int j = 0; j < playerHand.hand.Count; j++)
{
Console.Write("{0}{1}, ", playerHands.hands[i].hand [j].rank, playerHands.hands[i].hand[j].suit);
}
Console.WriteLine();
}
Console.Read();
}
}
}
class Hand
{
/////////////////////////////////////////////////////////////////////
//Hand should contain, at a minimum:
// A List<> of cards that holds the individual cards delt to a player
// Game Number: A game is continues until the player quits
// Hand Number: Sequential hand played during a game
//////////////////////////////////////////////////////////////////////
public List<Cards> hand;
public Hand()
{
hand = new List<Cards>();
}
public void addCard(Cards card)
{
this.hand.Add(card);
}
public void clearHand()
{
hand.Clear();
}
}
class Hands
{
public List<Hand> hands;
public Hands()
{
hands = new List<Hand>();
}
public void addHand(Hand hand)
{
hands.Add(hand);
}
}
The issue is really, really simple: you are not creating enough Hand instances.
You call Hand playerHand = new Hand(); just once.
This means you have only one Hand instance, which you are clearing and filling over and over in your first for loop.
You need to call new Hand() once for each hand instance (just editing the relevant part of your code):
Hands playerHands = new Hands();
//Test Hands
//Create ten hands of dealt cards
for (int i = 0 ; i < 10; i++)
{
Hand playerHand = new Hand();
playerHands.addHand(playerHand);
for (int j = 0; j < 5; j++)
{
playerHand.addCard(shoe[j]);
shoe.RemoveAt(0); //delete card delt from shoe
}
}
Have fun!

How to extract a row from an array in C#?

note: BJ Myers comment was useful and was the answer in fact. However, as it was a comment, I couldn't mark that as an answer but I've placed the corrected code (using his advice) at the end of this question.
Original question below continues:
This situation may look weird at first but here is what I intend to do:
Similar to the syntax in Python, instead of creating a multidimensional array (a 2-d array, to be exact), I want to create an array of arrays (a vector of vectors, in fact).
I'm aware that C# will not let me create pointers in safe code, but I'm still curious whether there is a safer way to accomplish this task w/o getting of the safe code limits.
So, I came up with the code below but couldn't figure out how to extract a specific row from the array (as shown between the comment lines).
Is it possible to pass the r'th row at once or do I need to create another temporary storage for r'th row and then pass that temporary vector through?
(System: Windows-10, VS-2013, C#)
using System;
public class Vector {
public double[] data;
public Vector(double[] data) {
this.data = new double[data.GetLength(0)];
this.data = data;
}
}
public class Matrix {
private int row, col;
public Matrix(double[,] data) {
this.row = data.GetLength(0);
this.col = data.GetLength(1);
Vector[] v = new Vector[this.row];
for (int r = 0; r < this.row; r++) {
// ****** this line below ******
v[r] = new Vector(data[r,???]);
// ****** how to extract the r'th row ******
}
}
static void Main(string[] args) {
double[,] data = { { 9.0, 8.0, 7.0 }, { 5.0, 6.0, 4.0 }, { 3.0, 2.0, 2.0 } };
Matrix A = new Matrix(data);
Console.ReadLine();
}
}
The corrected code is below:
using System;
public class Vector {
public double[] data;
public Vector(double[] data) {
this.data = new double[data.GetLength(0)];
this.data = data;
for (int i = 0; i < data.GetLength(0); i++) {
Console.Write("{0: 0.000 }", this.data[i]);
}
Console.WriteLine();
}
}
public class Matrix {
private int row, col;
public Matrix(double[][] data) {
this.row = data.GetLength(0);
this.col = data[0].GetLength(0);
Vector[] v = new Vector[this.row];
for (int r = 0; r < row; r++) {
v[r] = new Vector(data[r]);
}
Console.WriteLine("rows: " + this.row.ToString());
Console.WriteLine("cols: " + this.col.ToString());
}
static void Main(string[] args) {
double[][] data = { new double[] { 9.0, 8.0, 7.0 },
new double[] { 5.0, 6.0, 4.0 },
new double[] { 3.0, 2.0, 2.0 } };
Matrix A = new Matrix(data);
Console.ReadLine();
}
}
Well, you want to make an array class and acess like one? Make an indexer. what is an indexer? - it's a way to make your class accessible like an array.
Look over the link for examples, I'll help you with your specific case.
public class Vector {
public double[] data;
public double this[int i]
{
get
{
// This indexer is very simple, and just returns or sets
// the corresponding element from the internal array.
return data[i];
}
set
{
data[i] = value;
}
}
public Vector(double[] data) {
this.data = new double[data.GetLength(0)];
this.data = data;
}
}
once it's defined like so, this is perfectly valid:
double elementArray = new double[data.GetLength(1)]; // declaring an array, the size of the second dimention of the data array.
for(int i =0; i<data.GetLength(1);i++)
{
elementArray[i] = data[r,i]; // adding all the elements to the list
}
v[r] = new Vector(elementArray);
EDIT: BJ Myers' comment is right, this solution works perfectly for a jagged array too, but make sure that you declare it properly like he mentioned.
EDIT 2: Using a list is pointless here, changed the stracture to an array.

Categories

Resources