Random.Next is refreshing after a console update - c#

I am trying to make a card game, and I made my own shuffle function in rTools, but every time I update the console (e.g. using a console.readline statement) it re-randomizes the list. For example, in a list<string> of 1,2,3,4,5 and I use rTools.shuffle on it, the first three would be something like 3, 5, and 2. But after I refresh it without restarting the code, it would be a completely different series. I'm using an online editor, dotnetfiddle.net, if that changes anything.
I have tried multiple different approaches- here is my code:
using System;
using System.Collections.Generic;
namespace elementCard
{
public class rTools {
public rTools() {
dddd = DateTime.Now;
llll = dddd.Ticks;
ssss = llll.ToString().Substring(llll.ToString().Length - 8, 8);//This is because the original long was not accepted by System.Random(int)
_seed = Int32.Parse(ssss);
}
private DateTime dddd
{ get; set; }
private long llll
{ get; set; }
private string ssss
{ get; set; }
private int _seed
{ get; set; }
public List<string> shuffle(List<string> l)
{
int count = l.Count-1;
List<string> ret = new List<string>();
int ind = 0;
Random rng = new Random(_seed);
string card = null;
while (count > -1)
{
ind = rng.Next(0, count);
card = l[ind];
l.RemoveAt(ind);
ret.Add(card);
card = null;
count--;
}
return ret;
}
}
public class Program
{
public static void Main()
{
rTools rtools = new rTools();
Console.WriteLine("Hello World");
List<List<string>> playerHands = new List<List<string>>();
//💧🔥🌀🌱
List<string> deck = new List<string> {"1💧", "2💧", "3💧", "4💧", "5💧", "6💧", "7💧", "8💧", "9💧", "1🔥", "2🔥", "3🔥", "4🔥", "5🔥", "6🔥", "7🔥", "8🔥", "9🔥", "1🌀", "2🌀", "3🌀", "4🌀", "5🌀", "6🌀", "7🌀", "8🌀", "9🌀", "1🌱", "2🌱", "3🌱", "4🌱", "5🌱", "6🌱", "7🌱", "8🌱", "9🌱"};
List<string> sDeck = new List<string> {"R🔄", "S❌", "D🔳", "X⛈", "+✨", "A🌕", "A🌑"};
List<string> vDeck = new List<string> {"V◆", "V◇", "V◈"};
deck = rtools.shuffle(deck);
Console.WriteLine(deck[0]);
Console.ReadLine();
Console.ReadLine();
}
}
}

Specify a seed when creating the dictionary:
Random rng = new Random(42);
Otherwise, it will automatically initialize it with a seed based on the current date/time.
You can create a new seed at every start of the program with:
public static class rTools {
// Creates a "random" seed at every start of the program.
private static readonly int _seed = (int)DateTime.Now.Ticks;
public static List<string> shuffle(List<string> l) //Shuffle function
{
...
Random rng = new Random(_seed);
...
}
}
You can also drop the readonly keyword if you want replace the seed later, or make the rTools class non static as well as all its members. Then a new seed will be created whenever you create a new instance of this class. This gives you the full control on when you want to create a completely different series.
Here is a complete solution:
The class
public class RTools
{
private readonly int _seed = (int)DateTime.Now.Ticks;
public List<string> Shuffle(List<string> l)
{
List<string> ret = new List<string>();
Random rng = new Random(_seed);
// Since you remove items, use the current count of the list.
while (l.Count > 0) {
int ind = rng.Next(0, l.Count);
string card = l[ind];
l.RemoveAt(ind);
ret.Add(card);
}
return ret;
}
}
Body of Main method
// Lets you write fancy Unicode characters.
Console.OutputEncoding = System.Text.Encoding.UTF8;
RTools rtools = new RTools();
string input;
do {
Console.WriteLine("Hello World");
List<List<string>> playerHands = new List<List<string>>();
//💧🔥🌀🌱
List<string> deck = new List<string> { "1💧", "2💧", "3💧", "4💧", "5💧", "6💧", "7💧", "8💧", "9💧", "1🔥", "2🔥", "3🔥", "4🔥", "5🔥", "6🔥", "7🔥", "8🔥", "9🔥", "1🌀", "2🌀", "3🌀", "4🌀", "5🌀", "6🌀", "7🌀", "8🌀", "9🌀", "1🌱", "2🌱", "3🌱", "4🌱", "5🌱", "6🌱", "7🌱", "8🌱", "9🌱" };
List<string> sDeck = new List<string> { "R🔄", "S❌", "D🔳", "X⛈", "+✨", "A🌕", "A🌑" };
List<string> vDeck = new List<string> { "V◆", "V◇", "V◈" };
deck = rtools.Shuffle(deck);
foreach (string card in deck) {
Console.WriteLine(card);
}
Console.WriteLine();
input = Console.ReadLine();
if (input == "new") { // Create a completely new card deck.
rtools = new RTools();
}
} while (input != "quit");

Related

Need to change values in classes without changing its reference

I am currently making an application which tracks information on players and monsters for a tabletop game.
Currently I've got classes for "Monsters". This class contains information such as its name, maxHP, speed, attacks etc. I've managed to make a Database which contains the default values for each type of monster. What I currently need to do is make it possible to change things such as name (Monster > Monster 1, Monster 2 etc), change its HP, and some other things.
I understand that I need to make a copy of such, but I am uncertain on how to do this.
What I currently tried is the following:
public class DatabaseService
{
public List<Player> Players { get; set; }
public List<Monster> AllMonsters { get; set; }
public List<Monster> ActiveMonsters = new List<Monster>();
public bool RollForHP = false;
//Main Database Service
public DatabaseService()
{
Players = GetPlayers();
AllMonsters = GetAllMonsters();
}
public void DoStuff()
{
AddMonsterByName("Goblin", 2);
AddMonsterByName("Adult White Dragon", 1);
AddMonsterByName("Duergar", 4);
foreach (Monster monster in ActiveMonsters) { Console.WriteLine(monster.Name); }
}
//Converts the .json list with all players to Classes, which are then stored in the list "Players" if the "IsInParty" is true
private List<Player> GetPlayers()
{
var path = #"C:\Users\MyName\source\repos\DndAdvancedInitiativeTracker\Logic\Database\Players.json";
var json = File.ReadAllText(path);
var players = JsonConvert.DeserializeObject<List<Player>>(json);
List<Player> inPartyPlayers = new List<Player>();
foreach (var player in players)
{
if (player.IsInParty == true) { inPartyPlayers.Add(player); }
}
return inPartyPlayers;
}
//Converts the .json list with all monsters to Classes, which are then stored in the list "AllMonsters"
private List<Monster> GetAllMonsters()
{
var path = #"C:\Users\MyName\source\repos\DndAdvancedInitiativeTracker\Logic\Database\Monsters.json";
var json = File.ReadAllText(path);
var monsters = JsonConvert.DeserializeObject<List<Monster>>(json);
return monsters;
}
//Adds a given monster to the "ActiveMonsters" list
public void AddMonsterByName(string monsterName, int amountOfMonsters)
{
for (int i = 0; i < amountOfMonsters; i++)
{
List<Monster> DatabaseCopy = AllMonsters.Clone();
DatabaseCopy = AllMonsters;
Monster monster = DatabaseCopy.Find(x => x.Name == monsterName);
Console.WriteLine(monster.Name);
var number = CheckIfNameExistsInList(monsterName);
monster.Name = monsterName + " " + (number + i).ToString();
ActiveMonsters.Add(monster);
}
}
private int CheckIfNameExistsInList(string monsterName)
{
var counter = 1;
foreach (var monster in ActiveMonsters)
{
if (monster.Name.Contains(monsterName))
{
counter += 1;
}
}
return counter;
}
}
In the "DoStuff" Method, I try to add 2 goblins, then a dragon, then a goblin again. The first goblin is named to "Goblin 1" correctly, but the second loop fails, because the AllMonsters' name for goblins is now "Goblin 1" because of the reference type, therefore, the second "Goblin" search in AllMonsters is never found, and returns null.
I'm not sure why you're copying your database (and doing so for every iteration of a for loop which is quite wasteful), but your current check code CheckIfNameExistsInList will always return 1 even if there are no matches in the list.
You can simplify your AddMonstersByName (and use a simple check for previous monster entries) as follows:
public void AddMonstersByName(string name, uint number = 1)
{
var count = AllMonsters.Count(x => x.Name.Contains(name));
for (var i = 1; i <= number; i++)
{
var num = count + i;
AllMonsters.Add(new Monster(){Name= name+num.ToString()});
}
}
This was tested in a simple Console App:
var dataService = new DataService();
dataService.AddMonstersByName("Goblin", 2);
dataService.AddMonstersByName("Dragon", 2);
dataService.AddMonstersByName("Goblin", 2);
foreach (var monster in dataService.AllMonsters)
{
Console.WriteLine($"{monster.Name}");
}
where
public class DataService
{
public List<Monster> AllMonsters = new List<Monster>();
public void AddMonstersByName(string name, uint number = 1)
{
var count = AllMonsters.Count(x => x.Name.Contains(name));
for (var i = 1; i <= number; i++)
{
var num = count + i;
AllMonsters.Add(new Monster(){Name= name+num.ToString()});
}
}
}
public class Monster
{
public string Name { get; set; }
}

Checking list for custom object

If you have made a list of Custom objects is it a must to have to do with Hashcodes if you wanna check that list to see if it contains a object before adding it, I mean so that you do not get duplicates in the list or is there an easier way basically I want to use the contains method on a custom object list to see if the object I want to add already exists in the list and if there then is an easier way then to have to deal with hashcodes?
This is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DataConverter.Objects;
namespace DataConverter.Converters
{
class CategoryConverter
{
private Category category;
private SubCategory subCategory;
private ExcellObj excellObj;
public CategoryConverter(string path)
{
excellObj = new ExcellObj(path);
}
public List<Category> getCategoryListExcel()
{
List<Category> categories = new List<Category>();
List<string> ColumnNames = new List<string> { "Group1", "Group1Descr" };
List<int> CorrectColumn = new List<int>();
for(int i = 0; i < ColumnNames.Count; i++)
{
CorrectColumn.Add(excellObj.findColumn(ColumnNames[i]));
}
for(int i = 2; i < excellObj.allRows; i++)
{
categories.Add(category = new Category(excellObj.getValuesFromCell(i, CorrectColumn[1]), excellObj.getValuesFromCell(i, CorrectColumn[0]), "Home"));
}
return categories;
}
public List<List<SubCategory>> getSubCategory()
{
List<SubCategory> subCategories1 = new List<SubCategory>();
List<SubCategory> subCategories2 = new List<SubCategory>();
List<List<SubCategory>> subCategoriesList = new List<List<SubCategory>>();
List<string> ColumnNamesSubCategory1 = new List<string> { "Group2", "Group2Descr" };
List<string> ColumnNamesSubCategory2 = new List<string> { "Group3", "Group3Desc" };
List<int> CorrectColumn1 = new List<int>();
List<int> CorrectColumn2 = new List<int>();
for(int i = 0; i < ColumnNamesSubCategory1.Count; i++)
{
CorrectColumn1.Add(excellObj.findColumn(ColumnNamesSubCategory1[i]));
CorrectColumn2.Add(excellObj.findColumn(ColumnNamesSubCategory2[i]));
}
for(int i = 1; i < excellObj.allRows; i++)
{
subCategories1.Add(subCategory = new SubCategory(excellObj.getValuesFromCell(i, CorrectColumn1[1]),excellObj.getValuesFromCell(i,CorrectColumn1[0]), "Home"));
subCategories2.Add(subCategory = new SubCategory(excellObj.getValuesFromCell(i,CorrectColumn2[1]), excellObj.getValuesFromCell(i,CorrectColumn2[0]), "Home"));
}
subCategoriesList.Add(subCategories1);
subCategoriesList.Add(subCategories2);
return subCategoriesList;
}
public void finnishedUsingExcel()
{
excellObj.CloseApplication();
}
}
}
and what i whant to happen is that i whant to run a
if(categories.Contains(category) == false){
categories.add(category)
}
i do not understand this part in the documentation?
public Person(string lastName, string ssn)
{
if (Regex.IsMatch(ssn, #"\d{9}"))
uniqueSsn = $"{ssn.Substring(0, 3)}-{ssn.Substring(3, 2)}-{ssn.Substring(5, 4)}";
else if (Regex.IsMatch(ssn, #"\d{3}-\d{2}-\d{4}"))
uniqueSsn = ssn;
else
throw new FormatException("The social security number has an invalid format.");
this.LastName = lastName;
}
Assuming you have a code like this:
List<CustomObject> listOfCustomObjects = new List<CustomObject>();
Solution 1
If so, you can use listOfCustomObjects.Contains(customObject) to find out if customObject is in listOfCustomObjects. You should add using System.Linq; to the top of your code in order to use this method.
Solution 2
Another way to not have duplicates in your list is basically not using a List. You can use HashSet instead. With this method, duplicate objects won't be added to your list automatically. HashSet is also in LINQ Library, so you should add the line using System.Linq; for this solution too. Here's an example how to create a new HashSet with your CustomObject class:
HashSet<CustomObject> setOfCustomObjects = new HashSet<CustomObject>();
You really should have your class implement IEquatable if it's reasonable to do so and you're going to check for equality with any frequency, just so it does not bite you. The "Contains" method will work, but only to test that the exact same instance is present, not necessarily one that just shares matching properties. Consider the following code:
class Program
{
static void Main(string[] args)
{
var classInstance = new MySampleClass("testA", "testB");
var classList = new List<MySampleClass>();
classList.Add(classInstance);
if (classList.Contains(new MySampleClass("testA", "testB")))
{
Console.WriteLine("true");
}
else
{
Console.WriteLine("false");
}
if (classList.Contains(classInstance))
{
Console.WriteLine("true");
}
else
{
Console.WriteLine("false");
}
}
}
public class MySampleClass
{
public string SampleProperty1 { get; set; }
public string SampleProperty2 { get; set; }
public MySampleClass(string sampleProperty1, string sampleProperty2)
{
SampleProperty1 = sampleProperty1;
SampleProperty2 = sampleProperty2;
}
}
Even though we're checking for the presence of the class that has the exact same values as the one we previously added, they're still separate instances and you'll end up with duplicates in your list.
An alternative in the very limited case would be to use a LINQ method to check whether the list already contains an entry with a property that can be compared, such as an int ID or something:
yourList.Any(item => item.Id.Equals(otherItem.Id));
Again, if it's more than a one off, implement it the right way with IEquatable. See Microsoft's documentation

Processing int to name of list

I try to write a simple console application with Hanoi towers. But I am stuck at one point.
In my program I ask a person to write from to which tower wants to put the disk, but: I have 3 lists as towers, I'll ask for a number from gamer and now how I can build a "compare method"? Because I don't want to copy the same piece of code 6 times...
class Towers : Disks
{
//public Towers(int Value, int WhereItIs) : base(Value, WhereItIs) { }
public List<Disks> Tower1 = new List<Disks>();
public List<Disks> Tower2 = new List<Disks>();
public List<Disks> Tower3 = new List<Disks>();
public void Compare(int dyskFrom, int dyskWhere) {
}
public void Display() {
foreach(var i in Tower1){
Console.WriteLine("Where: {0} | Value: {1}", i.WhereItIs, i.Value);
}
}
public void Build(int TowerHigh) {
for (int i = TowerHigh; i > 0; i--) {
Tower1.Add(new Disks {Value = i, WhereItIs = 1 });
}
}
}
class Disks
{
public int Value; //wartosc krazka
public int WhereItIs; //na ktorej wiezy sie on znajduje
}
class Program
{
static void Main(string[] args)
{
Towers Tower = new Towers();
int TowerHigh;
Console.Write("Podaj wysokość wieży: ");
TowerHigh = int.Parse(Console.ReadLine());
Tower.Build(TowerHigh);
Tower.Display();
Tower.Compare(1, 2);
}
}
It's easier to create an array of Stack<Disk>(). This way you can select a tower by index.
I would use a Stack, because thats typically the functionality you need.
Something like: PSEUDO (typed in browser, no syntax checked)
class Disk
{
public int Size {get; set;}
}
static void Main(string[] args)
{
// create the Stack<Disk> array
Stack<Disk>[] towers = new Stack<Disk>[3];
// create each tower
for(int i=0;i<towers.Length;i++)
{
towers[i] = new Stack<Disk>();
// fill the towers.
for(int j=3;j>0;j--)
towers[i].Enqueue(new Disk { Size = j });
}
bool isHoldingDisk = false;
while(true)
{
DisplayTowers(towers);
if(isHoldingDisk)
Console.WriteLine("On what tower do you want to place it?");
else
Console.WriteLine("Choose a tower to pick a disk");
var key = Console.ReadKey(true);
var chosenTowerIndex = 0;
switch(key)
{
case(Key.Escape):
break;
case(Key.D1):
chosenTowerIndex = 0;
break;
case(Key.D1):
chosenTowerIndex = 1;
break;
case(Key.D1):
chosenTowerIndex = 2;
break;
// etc...
}
if((chosenTowerIndex < 1) || (chosenTowerIndex >= towers.Length))
continue;
// check here if you are holding a disk
if(isHoldingDisk)
{
// logic for testing if you can place the disk here...
// using towers[chosenTowerIndex]
// check if it is completed...
if(completed)
break;
isHoldingDisk = false;
}
else
{
// check if you can pickup a disk....(if there is any)
isHoldingDisk = true;
}
}
// final display...
DisplayTowers(towers);
Console.WriteLine("Thanks for playing");
}
static void DisplayTowers(Stack<Disk>[] towers)
{
// draw some fancy asc-ii art...
}

How to change batch size of batchblock dynamically during runtime?

I have a batch block in tpl dataflow and have several target blocks linked to the batch block. However, the number of target blocks changes dynamically and thus the size of the batches. Problem is that the batch size must be supplied at the initialization of the batchblock and I dont see a way to adjust it later on. Any ideas how to get around this? Is the only way to unlink (dispose all links to batchblock and from batchblock), re-initialize the batch block with a new batch size and then link again? I could do that but how to ensure that old batches and new batches are not get all mixed up?
For example if I had 2 transform blocks stream to batch block and now have an additional transform block and want to increase batch size to 3, how do I make sure that all previous batches prior to the increase were processed to ensure synched behavior? Point is that all transform blocks get the exact identical item and the outputs of those transform blocks should be batched in the way that only those outputs are batched that match identical inputs.
Here a sample how I want it to be:
Constant stream of ints to transform blocks:
1,2,3, [point where batch size is increased],4,5,...
Let transform blocks output what they got in like 1 => 1
So batchblock should output like this :
[1,1], [2,2], [3,3], [change of batch size], [4,4,4], [5,5,5],...
Here my current code:
public class Test
{
private Stopwatch watch;
private BroadcastBlock<List<InputObject>> tempBCB;
private BatchBlock<Tuple<List<InputObject>, Dictionary<int, IntermediateObject>>> batchBlock;
private TransformBlock<Tuple<List<InputObject>, Dictionary<int, IntermediateObject>>[], List<FinalObject>> transformBlock;
private ActionBlock<List<FinalObject>> justToFlushTransformBlock;
private CoreLogic core1;
private CoreLogic core2;
public Test()
{
tempBCB = new BroadcastBlock<List<InputObject>>(input => input);
//here batch size = 2
batchBlock = new BatchBlock<Tuple<List<InputObject>,Dictionary<int,IntermediateObject>>>(2, new GroupingDataflowBlockOptions { Greedy = false });
transformBlock = new TransformBlock<Tuple<List<InputObject>,Dictionary<int,IntermediateObject>>[],List<FinalObject>>(array =>
{
List<InputObject> inputObjects = array[0].Item1;
List<FinalObject> ret = inputObjects.ConvertAll(x => new FinalObject(x));
foreach (var tuple in array)
{
//iterate over each individual object
foreach (var dictionary in tuple.Item2)
{
ret[dictionary.Key].outputList.Add(dictionary.Value);
}
}
return ret;
}, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded });
justToFlushTransformBlock = new ActionBlock<List<FinalObject>>(list =>
{
//just in order to accept items from the transformBlock output queue
});
//Generate 2 CoreLogic objects
core1 = new CoreLogic();
core2 = new CoreLogic();
//linking
tempBCB.LinkTo(core1.transformBlock, new DataflowLinkOptions { PropagateCompletion = true });
tempBCB.LinkTo(core2.transformBlock, new DataflowLinkOptions { PropagateCompletion = true });
core1.transformBlock.LinkTo(batchBlock);
core2.transformBlock.LinkTo(batchBlock);
batchBlock.LinkTo(transformBlock, new DataflowLinkOptions { PropagateCompletion = true });
transformBlock.LinkTo(justToFlushTransformBlock, new DataflowLinkOptions { PropagateCompletion = true });
}
public void Start()
{
const int numberChunks = 30;
watch = new Stopwatch();
watch.Start();
for (int j = 1; j <= numberChunks; j++)
{
int collectionSize = 10000 * j;
List<InputObject> collection = new List<InputObject>(collectionSize);
for (int i = 0; i < collectionSize; i++)
{
collection.Add(new InputObject(i));
}
tempBCB.Post(collection);
}
tempBCB.Complete();
Task.WhenAll(core1.transformBlock.Completion, core2.transformBlock.Completion).ContinueWith(_ =>
{
batchBlock.Complete();
});
transformBlock.Completion.Wait();
watch.Stop();
Console.WriteLine("Elapsed time (in milliseconds): " + watch.ElapsedMilliseconds);
Console.ReadLine();
}
}
public class CoreLogic
{
private Random rand;
public TransformBlock<List<InputObject>, Tuple<List<InputObject>, Dictionary<int, IntermediateObject>>> transformBlock;
public CoreLogic()
{
const int numberIntermediateObjects = 10000;
transformBlock = new TransformBlock<List<InputObject>, Tuple<List<InputObject>, Dictionary<int, IntermediateObject>>>(input =>
{
//please ignore the fact that `input` is not utilized here, the point is to generate a collection of IntermediateObject and return
Dictionary<int, IntermediateObject> ret = new Dictionary<int, IntermediateObject>();
for (int i = 0; i < numberIntermediateObjects; i++)
{
IntermediateObject value = new IntermediateObject(i);
ret.Add(i, value);
}
var tuple = new Tuple<List<InputObject>, Dictionary<int, IntermediateObject>>(input, ret);
return tuple;
});
}
}
public class InputObject : ICloneable
{
public int value1 { get; private set; }
public InputObject(int value)
{
this.value1 = value;
}
object ICloneable.Clone()
{
return Clone();
}
public InputObject Clone()
{
return (InputObject)this.MemberwiseClone();
}
}
public class IntermediateObject
{
public int value1 { get; private set; }
public IntermediateObject(int value)
{
this.value1 = value;
}
}
public class FinalObject
{
public InputObject input { get; private set; }
public List<IntermediateObject> outputList;
public FinalObject(InputObject input)
{
this.input = input;
this.outputList = new List<IntermediateObject>();
}
}
public static class Cloning
{
public static List<TValue> CloneListCloneValues<TValue>(List<TValue> original) where TValue : ICloneable
{
List<TValue> ret = new List<TValue>(original.Count);
foreach (TValue entry in original)
{
ret.Add((TValue)entry.Clone());
}
return ret;
}
}

How do I create an array of objects in constructor?

I have two classes:
game
element
I want to be able to define an array of element objects in a game object. When I try this I get the warning message "..is never assigned to, and will always have its default value null"; in the local variables in the debugger I can see that the array exists, but all entries are null. The class Element works as I would expect. If I assign element objects to an array in Main it works, but not when I move the code to the Game constructor.
What am I doing wrong? I'm new to C# so it could be something very basic. Code below. Many thanks.
class Element
{
public Element()
{
elements = new List<int>(3);
elements.Add(1);
elements.Add(2);
elements.Add(3);
}
List<int> elements;
public void PrintElement()
{
for (int i = 0; i < 3; i++)
{
Console.WriteLine("Element {0}: {0}", i + 1, elements[i]);
}
}
}
class Game
{
public Game()
{
Element1 = new Element();
Element2 = new Element();
Element3 = new Element();
Element[] ThisGame = new Element[3];
ThisGame[0]= Element1;
ThisGame[1] = Element2;
ThisGame[2] = Element3;
}
public Element[] ThisGame;
private Element Element1;
private Element Element2;
private Element Element3;
public void PrintGameElement(int number)
{
ThisGame[number].PrintElement();
}
}
class Program
{
Game MyGame;
static void Main(string[] args)
{
Game MyGame = new Game();
MyGame.PrintGameElement(2);
Console.Read();
}
}
In Game, you are re-declaring ThisGame.
Change
Element[] ThisGame = new Element[3];
to
ThisGame = new Element[3];
Your Game constructor should look like this:
public Game()
{
Element1 = new Element();
Element2 = new Element();
Element3 = new Element();
ThisGame = new Element[3];
ThisGame[0]= Element1;
ThisGame[1] = Element2;
ThisGame[2] = Element3;
}
You need to set the list object to something when you initialize it.
List<int> elements = null;
OR
List<int> elements = new List<int>();
look at this code it may help you to make some order in your code:
Element class :
class Element
{
//property on element to save element data
public string ElementData { get; set; }
public Element(string data)
{
ElementData = data;
}
}
Game class :
class Game
{
//property on Game to save all elements
Element[] Elements { get; set; }
public Game(Element[] elements)
{
Elements = elements;
}
public void PrintGameElements()
{
foreach (var element in Elements)
{
Console.WriteLine(element.ElementData);
}
}
public void PrintElement(int index)
{
Console.WriteLine(Elements[index].ElementData);
}
}
Main function that initialize the array and pass it to the game :
static void Main(string[] args)
{
//initialize the array
var elements = new[]
{
new Element("data x"),
new Element("data y"),
new Element("data z")
};
//pass the elements to the game
var game = new Game(elements);
//print the second element
game.PrintElement(1);
//print all elements
game.PrintGameElements();
Console.ReadKey();
}
}

Categories