Properties in list has changed when using lambda expression - c#

I don't know why item in list has been changed when i using lambda expression.
here my code
using System;
using System.Collections.Generic;
using System.Linq;
public class test
{
public string id { get; set; }
public string name { get; set; }
public string no { get; set; }
}
public class Program
{
public static List<test> a;
public static List<test> b = new List<test>();
public static List<test> a_list()
{
List<test> c = new List<test>();
c.Add(new test() { id = "_01", name=null, no="1"});
c.Add(new test() { id = "_02", name=null, no="2"});
return c;
}
public static void Main()
{
a = a_list();
string key = "_01";
//
test i = new test();
i = a.First(x => x.id.Equals(key));
i.name = "xxxxxxx";
b.Add(i);
//
Console.WriteLine("id:"+a[0].id+"\nName:"+a[0].name+"\nno:"+a[0].no);
Console.WriteLine("id:"+b[0].id+"\nName:"+b[0].name+"\nno:"+b[0].no);
Console.ReadLine();
}
}
This is result
id:_01
Name:xxxxxxx
no:1
id:_01
Name:xxxxxxx
no:1
Why a[0] equals "xxxxxxx"? (sorry my english is bad )

here:
i = a.First(x => x.id.Equals(key));
i.name = "xxxxxxx";
i and a.First() are now references to the same object. Modifying a property on that object will affect both of these, because they are pointers to the same thing.

Basically what your code does is:
It creates a list with two elements (a)
It takes its first element and modifies that element's value
It takes that element and adds it to the second list (b)
So the outcome is that you have two lists - one (a) contains two elements, the other (b) just one, but (and here's the important bit) - it's the exact same element as the first one in a. So when you write the first element of both lists, the results are equal.

Imagine you have a camera pointing at a car. When the car door opens, you see it through the camera, but the camera is not the car.
Now your friend some distance away also points his camera at the car. You both can see the door open and close, and the lights, etc.
A variable is like the camera and the car is the object it points to.
If you turn off or destroy one of the cameras, the car is still there. In fact, if you destroy both cameras the car is still there (until garbage collection).
See this excellent article: http://codebetter.com/karlseguin/2008/04/28/foundations-of-programming-pt-7-back-to-basics-memory/

Related

Creating objects from a list which can vary in length

I'm a beginner and trying to create a small app, which finds the best combination of license plans given customer requirements.
I've simplified the part I am having trouble with below. The plangroup is actually a class of other objects, so it is basically used to group different plans together (e.g. where they are compatible). So it's a nested class, but I haven't included that part for simplicity.
My issues are:
I need to create planGroup objects based on the info in a list. The length of the list can vary.
So the I have mutiple constructors so that objects can be created with different number of fields, is there a more concise way of doing that then writing a constructor for each possible number of arguments?
How can I create the object from the list, without using multiple if statements to work out the length of the list?
Once created, how can I get the values out of the object, given that I don't know how long it is, again without using multiple if statements?
Thanks and hope this makes sense!
using System;
using System.Collections.Generic;
using System.IO;
namespace ConsoleApp1
{
class Program1
{
static void Main(string[] args)
{
// easy to create an object when you know how many bits of info you have
PlanGroup p1 = new PlanGroup("Plan 1 name", "Plan 2 name", 350);
Console.WriteLine($"{p1.Plan1} / {p1.Plan2} / {p1.Cost}");
// But what if we have a list of plan info that comes from another method, and could vary in length
var planinfo = new List<string> { "Plan name", "Another plan name" };
// could create the group object like this, but planinfo length will vary. The cost will be calculated and is not an issue.
// but I don't want to do this as would have to use multiple if statements to based on planinfo count (in reality there might be up to 10).
PlanGroup p2 = new PlanGroup(planinfo[0], planinfo[1], 200);
// then also need a way of getting the details of the PlanGroup objects that is better than this, so will return all the plans as well as the cost
Console.WriteLine($"{p2.Plan1} / {p2.Plan2} / {p2.Cost}");
}
class PlanGroup
{
public string Plan1 { get; set; }
public string Plan2 { get; set; }
public string Plan3 { get; set; }
public string Plan4 { get; set; }
public int Cost { get; set; }
public PlanGroup(string Plan1, string Plan2, int Cost)
{
this.Plan1 = Plan1;
this.Plan2 = Plan2;
this.Cost = Cost;
}
public PlanGroup(string Plan1, string Plan2, string Plan3, int Cost)
{
this.Plan1 = Plan1;
this.Plan2 = Plan2;
this.Plan3 = Plan3;
this.Cost = Cost;
}
public PlanGroup(string Plan1, string Plan2, string Plan3, string Plan4, int Pages)
{
this.Plan1 = Plan1;
this.Plan2 = Plan2;
this.Plan3 = Plan3;
this.Plan4 = Plan4;
this.Cost = Cost;
}
}
}
}
For your second issue. You could use System.Collections.Generic to use a List<T>. In which you could just have a List<string> Plans in the class and have a similar constructor. I.E the constructor takes a List<string> as a parameter
using System.Collections.Generic;
public class PlanGroup {
public List<string> Plans { get; set; }
public int Cost { get; set; }
public PlanGruop(int Cost, List<string> Plans) {
this.Cost = Cost;
this.Plans = Plans;
}
}
and the utilization of the constructor would look like
PlanGroup p = new PlanGroup(500, new List<string>{ "plan1", "plan2"... });
then to get the length (number of "plans" inside the list) You simply use p.Plans.Count. And accessing an element, is as easy as looking through an array p.Plans[0] and so on.
The question was a bit unclear, but i hope this gave you some answers.

CollectionAssert.IsSubsetOf for public static Lists always fails

I'm doing a CollectionAssert for two public lists built from linq-to-sql queries. When I do the CollectionAssert for these, it always fails even for a test set which clearly should pass.
I even did a quick test in my code to make sure I'm using the CollectionAssert correctly.
//This always passes
List<string> testList1 = new List<string>();
List<string> testList2 = new List<string>();
testList1.Add("one");
testList2.Add("two");
testList2.Add("three");
testList2.Add("one");
CollectionAssert.IsSubsetOf(testList1, testList2);
//This always fails
CollectionAssert.IsSubsetOf(memberOrganizations, member_Dim_Organization, "Error Matching Fields");
Any thoughts on how I can correct the syntax of the second assert? I've attached a screen shot of my debug window. Debug Screen Shot
I define the format of structure of the list in one method
namespace DefineStructure
{
public class Results
{
public string OrgID { get; set; }
}
This load the data in a separate
namespace Reporting.Member_Dim_Organization.ETL.QA
{
public class LoadData
{
public static cDataContext oMain = new cDataContext();
public static List<Results> oecMainResults = (from mo in oecMain.MemberOrganizations
orderby mo.OrgID
select new Results
{
OrgID = (mo.OrgID).ToString() }).Take(1).ToList();
Then I declare it in my main program
namespace Reporting.Main
{
[Binding]
public class Member_Dim_OrganizationsSteps
{
public static List<Results> memberOrganizations = LoadData.oecMainResults;
public static List<Results> member_Dim_Organization = LoadData.reportingMasterResults;
Does that help clarify?
Thanks for helping an old dog who's trying to learn some new tricks.
You are assuming that if the two collections have instances with the same data that they are equal, which is not the case by default. It sounds like you need to override Equals and GetHashCode on the Results class to define "equality".
There are lots of examples out there of defining equality for custom types, most of which involve defining the hash code as a combination of the hash codes of the fields that define equality.

How should I remove elements from a generic list based on the list s object's inclusion of elementfrom another list in C# using predicate logic?

I am trying to learn C# by making a simple program that shows the user sushi rolls given their desired ingredients. i.e. a user wants a roll with crab, and the program will spit out a list of sushi rolls that contain crab.
I've created a Roll class
public class Roll
{
private string name;
private List<string> ingredients = new List<string>();
}
With some getters and setters and other various methods.
In the GUI, I have some checkboxes which each call an update() method from the Control class, which will then need to check a list of rolls against a list of ingredients given by the GUI checkboxes. What I have is this
class Controller
{
static List<Roll> Rolls = new List<Roll>();
static RollList RL = new RollList();
static List<String> ingredients = new List<String>();
static Roll roll = new Roll();
}
public void update
{
foreach(Roll roll in Rolls)
{
foreach (String ingredient in ingredients)
if (!roll.checkForIngredient(ingredient))
Rolls.Remove(roll);
}
}
But a System.InvalidOperationException is thrown saying that because the collection was modified, the operation can't execute. OK, that's fair, but then what's the best way to do this? Here on Stack Overflow there's a post about removing elements from a generic list while iterating over it.
This was good and pointed me in the right direction, but unfortunately, my predicate condition simply doesn't match the top answer's.
It would have to iterate over the ingredients list, and I'm not even sure that's possible...
list.RemoveAll(roll => !roll.containsIngredient(each string ingredient in ingredients) );
shudder
I've tried the for loop, but I can't seem to get the enumeration to work either, and I wonder if it's even necessary to enumerate the class for just this method.
So I come here to try and find an elegant, professional solution to my problem. Keep in mind that I'm new to C# and I'm not all too familiar with predicate logic or enumeration on classes.
To use RemoveAll you can rewrite your condition to this:
list.RemoveAll(roll => !ingredients.All(roll.checkForIngredient));
This exploits the fact that when the compiler sees this, it will effectively rewrite it to this:
list.RemoveAll(roll => !ingredients.All(i => roll.checkForIngredient(i)));
Which is what you want. If not all the ingredients are present, remove the roll.
Now, having said that, since you say you're a beginner, perhaps you feel more comfortable keeping your loop, if you could just make it work (ie. stop crashing due to modifying the loop). To do that, just make a copy of the collection and then loop through the copy, you can do this by just modifying the foreach statement to this:
foreach(Roll roll in Rolls.ToList())
This will create a list based copy of the Rolls collection, and then loop on that. The list will not be modified, even if Rolls is, it is a separate copy containing all the elements of Rolls when it was created.
As requested in the comments, I'll try to explain how this line of code works:
list.RemoveAll(roll => !ingredients.All(roll.checkForIngredient));
The RemoveAll method, which you can see the documentation for here takes a predicate, a Predicate<T>, which is basically a delegate, a reference to a method.
This can be a lambda, syntax that creates an anonymous method, using the => operator. An anonymous method is basically a method declared where you want to use it, without a name, hence the anonymous part. Let's rewrite the code to use an anonymous method instead of a lambda:
list.RemoveAll(delegate(Roll roll)
{
return !ingredients.All(roll.checkForIngredient);
});
This is the exact same compiled code as for the lambda version above, just using the bit more verbose syntax of an anonymous method.
So, how does the code inside the method work.
The All method is an extension method, found on the Enumerable class: Enumerable.All.
It will basically loop through all the elements of the collection it is extending, in this case the ingredients collection of a single roll, and call the predicate function. If for any of the elements the predicate returns false, the result of calling All will also be false. If all the calls return true, the result will also be true. Note that if the collection (ingredients) is empty, the result will also be true.
So let's try to rewrite our lambda code, which again looked like this:
list.RemoveAll(roll => !ingredients.All(roll.checkForIngredient));
Into a more verbose method, not using the All extension method:
list.RemoveAll(delegate(Roll roll)
{
bool all = true;
foreach (var ingredient in ingredients)
if (!roll.checkForIngredient(ingredient))
{
all = false;
break;
}
return !all;
});
This now starts to look like your original piece of code, except that we're using the RemoveAll method, which needs a predicate that returns whether to remove the item or not. Since if all is false, we need to remove the roll, we use the not operator ! to reverse that value.
Since you are both new to C# but also asked for an elegant solution, I will give you an example of how to solve this using a more object-oriented approach.
First of all, any "thing" of significance should be modeled as a class, even if it has just one property. This makes it easier to extend the behavior later on. You already defined a class for Roll. I would also add a class for Ingredient:
public class Ingredient
{
private string _name;
public string Name
{
get { return _name; }
}
public Ingredient(string name)
{
_name = name;
}
}
Note the Name property which only has a getter, and the constructor which accepts a string name. This might look like unnecessary complexity at first but will make your code more straightforward to consume further down the road.
Next, we'll modify your Roll class according to this guideline and give it some helper methods that make it easier for us to check if a roll contains a certain (list of) ingredients:
public class Roll
{
private string _name;
private List<Ingredient> _ingredients = new List<Ingredient>();
public string Name
{
// By only exposing the property through a getter, you are preventing the name
// from being changed after the roll has been created
get { return _name; }
}
public List<Ingredient> Ingredients
{
// Similarly here, you are forcing the consumer to use the AddIngredient method
// where you can do any necessary checks before actually adding the ingredient
get { return _ingredients; }
}
public Roll(string name)
{
_name = name;
}
public bool AddIngredient(Ingredient ingredient)
{
// Returning a boolean value to indicate whether the ingredient was already present,
// gives the consumer of this class a way to present feedback to the end user
bool alreadyHasIngredient = _ingredients.Any(i => i.Name == ingredient.Name);
if (!alreadyHasIngredient)
{
_ingredients.Add(ingredient);
return true;
}
return false;
}
public bool ContainsIngredients(IEnumerable<Ingredient> ingredients)
{
// We use a method group to check for all of the supplied ingredients
// whether or not they exist
return ingredients.All(ContainsIngredient);
// Could be rewritten as: ingredients.All(i => ContainsIngredient(i));
}
public bool ContainsIngredient(Ingredient ingredient)
{
// We simply check if an ingredient is present by comparing their names
return _ingredients.Any(i => i.Name == ingredient.Name);
}
}
Pay attention to the ContainsIngredient and ContainsIngredients methods here. Now you can do stuff like if (roll.ContainsIngredient(ingredient)), which will make your code more expressive and more readable. You'll see this in action in the next class that I'm going to add, RollCollection.
You are modeling collections of food to pick from, presumably in the context of a restaurant menu or some similar domain. You might as well go ahead and model just that: a RollCollection. This will allow you to encapsulate some meaningful logic inside of the collection.
Again, this sort of thing tends to require some boilerplate code and may look overly complex at first, but it will make your classes easier to consume. So let's add a RollCollection:
public class RollCollection : IEnumerable<Roll>
{
private List<Roll> _rolls = new List<Roll>();
public RollCollection()
{
// We need to provide a default constructor if we want to be able
// to instantiate an empty RollCollection and then add rolls later on
}
public RollCollection(IEnumerable<Roll> rolls)
{
// By providing a constructor overload which accepts an IEnumerable<Roll>,
// we have the opportunity to create a new RollCollection based on a filtered existing collection of rolls
_rolls = rolls.ToList();
}
public RollCollection WhichContainIngredients(IEnumerable<Ingredient> ingredients)
{
IEnumerable<Roll> filteredRolls = _rolls
.Where(r => r.ContainsIngredients(ingredients));
return new RollCollection(filteredRolls);
}
public bool AddRoll(Roll roll)
{
// Similar to AddIngredient
bool alreadyContainsRoll = _rolls.Any(r => r.Name == roll.Name);
if (!alreadyContainsRoll)
{
_rolls.Add(roll);
return true;
}
return false;
}
#region IEnumerable implementation
public IEnumerator<Roll> GetEnumerator()
{
foreach (Roll roll in _rolls)
{
yield return roll;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
WhichContainIngredients is the thing we were really looking for, as it allows you to do something like this:
// I have omitted the (proper) instantiation of Rolls and ChosenIngredients for brevity here
public RollCollection Rolls { get; set; }
public List<Ingredient> ChosenIngredients { get; set; }
public void Update()
{
Rolls = Rolls.WhichContainIngredients(ChosenIngredients);
}
This is simple and clean, just the sort of thing you want to be doing in your presentation layer. The logic to accomplish your requirement is now nicely encapsulated in the RollCollection class.
EDIT: a more complete (but still simplified) example of how your Controller class might end up looking like:
public class Controller
{
private RollCollection _availableRolls = new RollCollection();
private List<Ingredient> _availableIngredients = new List<Ingredient>();
public RollCollection AvailableRolls
{
get { return _availableRolls; }
}
public List<Ingredient> AvailableIngredients
{
get { return _availableIngredients; }
}
public RollCollection RollsFilteredByIngredients
{
get { return AvailableRolls.WhichContainIngredients(ChosenIngredients); }
}
public List<Ingredient> ChosenIngredients { get; set; }
public Controller()
{
ChosenIngredients = new List<Ingredient>();
InitializeTestData();
}
private void InitializeTestData()
{
Ingredient ingredient1 = new Ingredient("Ingredient1");
Ingredient ingredient2 = new Ingredient("Ingredient2");
Ingredient ingredient3 = new Ingredient("Ingredient3");
_availableIngredients.Add(ingredient1);
_availableIngredients.Add(ingredient2);
_availableIngredients.Add(ingredient3);
Roll roll1 = new Roll("Roll1");
roll1.AddIngredient(ingredient1);
roll1.AddIngredient(ingredient2);
Roll roll2 = new Roll("Roll2");
roll2.AddIngredient(ingredient3);
_availableRolls.AddRoll(roll1);
_availableRolls.AddRoll(roll2);
}
}
I am trying to learn C# by making a simple program that shows the user
sushi rolls given their desired ingredients. i.e. a user wants a roll
with crab, and the program will spit out a list of sushi rolls that
contain crab.
Here's my solution to the given problem:
public class Roll
{
public string Name { get; set; }
private List<string> ingredients = new List<string>();
public IList<string> Ingredients { get { return ingredients; } }
public bool Contains(string ingredient)
{
return Ingredients.Any(i => i.Equals(ingredient));
}
}
You can use the LINQ extension method .Where to filter your collection of Rolls
public class Program
{
static void Main()
{
var allRolls = new List<Roll>
{
new Roll
{
Name = "Roll 1",
Ingredients = { "IngredientA", "Crab", "IngredientC" }
},
new Roll
{
Name = "Roll 2",
Ingredients = { "IngredientB", "IngredientC" }
},
new Roll
{
Name = "Roll 3",
Ingredients = { "Crab", "IngredientA" }
}
};
var rollsWithCrab = allRolls.Where(roll => roll.Contains("Crab"));
foreach (Roll roll in rollsWithCrab)
{
Console.WriteLine(roll.Name);
}
}
}
From what I see you're trying to remove all rolls that don't contain crab from your list of rolls. A better approach is to filter out those rolls that don't contain crab (using .Where), you can then use .ToList() if you need to manipulate the whole list directly rather than iterating through the collection (fetching one item at a time).
You should read up on Delegates, Iterators, Extension Methods and LINQ to better understand what's going on under the covers.

StackOverflowException on nested query, small item count

I have found some threads with similar titles, but none seem to have a fitting answer.
One mentioned a bug in .NET versions prior to 4.0 - I use 4.0, so this should not be it.
Consider the example:
I am attempting to create a collection of instances of class Part, which do not belong to any instance of class PartGroup.
Func<Part,bool> hasGroup = P => partColl.Groups.Any( G => G.Parts.Contains(P) );
var groupless = partColl.Parts.Where( P => ! hasGroup(P) );
partColl is an instance of a class implementing the properties Groups and Parts, each IEnumerable<T> where T is PartGroup or Part respectively, internally implemented as List<T>.
partColl.Parts contains all parts in existence.
class Group has property IEnumerable<Part> Parts, listing references to parts belonging to the group.
In my current program, there are 27 parts and 5 groups with no overlap in elements.
Nothing that should trouble the stack, despite quadratic complexity, if something wasn't foul.
When I run this, it will crash with said exception on hasGroup.
What am I missing?
EDIT:
A little detail slipped my abstraction presented here:
IEnumerable PartGroup.Parts was, unlike the two properties of PartCollection, not backed by a List, it was an auto-property with private set, initialized in the c'tor with a passed-in IEenumerable. The instance behind this IEnumerable is also a list, and an own one for each group, so I'm not sure yet what is going on exactly.
BUT, the exception is gone by: also backing that property with a variable of type List and in the constructor, assigning to it: _list = parts.ToList(), where parts is IEnumerable<Parts>, passed as a param to the ctor. I did ToList just to make sure it will really be a list, not some half baked query, but it should, since at the place where I am building the groups, one new List for each group is allocated before passing it in...
The remaining question is still interesting: What was going on, why did the auto-property 'cause' the exception?
I'll post more details on request, but gotta go for a while now.
This small sample does not reproduce the issue.
using System;
using System.Linq;
using System.Collections.Generic;
class P
{
class PartGroup
{
public List<Part> Parts { get; private set; }
public PartGroup()
{
Parts = new List<Part>();
}
}
class Part
{
}
class PartCollection
{
public List<Part> Parts { get; set; }
public List<PartGroup> Groups { get; set; }
public PartCollection()
{
Parts = new List<Part>();
Groups = new List<PartGroup>();
}
}
static void Main()
{
var groups = new List<PartGroup> { new PartGroup(), new PartGroup(), new PartGroup(), new PartGroup(), new PartGroup() };
var partColl = new PartCollection();
partColl.Parts.Add(new Part());
partColl.Groups.AddRange(groups);
for (int i = 0; i < 27; i++)
{
var part = new Part();
groups[i % groups.Count].Parts.Add(part);
partColl.Parts.Add(part);
}
partColl.Parts.Add(new Part());
Func<Part, bool> hasGroup = P => partColl.Groups.Any(G => G.Parts.Contains(P));
var groupless = partColl.Parts.Where(P => !hasGroup(P)).ToList();
}
}

Select unknown item from multi-dimensional array using LINQ

For my own personal amusement, I'm writing what I hope will be the foundation of a game to come later. At current, I'm working on the game "board". Please consider the following:
class Board
{
private Cube[,,] gameBoard;
public Cube[, ,] GameBoard { get; }
private Random rnd;
private Person person;
public Person _Person { get; }
//default constructor
public Board()
{
person = new Person(this);
rnd = new Random();
gameBoard = new Cube[10, 10, 10];
gameBoard.Initialize();
int xAxis = rnd.Next(11);
int yAxis = rnd.Next(11);
int zAxis = rnd.Next(11);
gameBoard[xAxis, yAxis, zAxis].AddContents(person);
}
}
And this:
class Person : IObject
{
public Board GameBoard {get; set;}
public int Size { get; set; }
public void Move()
{
throw new NotImplementedException();
}
public void Move(Cube startLocation, Cube endLocation)
{
startLocation.RemoveContents(this);
endLocation.AddContents(this);
}
public Person(Board gameBoard)
{
Size = 1;
GameBoard = gameBoard;
}
public int[] GetLocation()
{
int[] currentLocation;
var location =
from cubes in GameBoard.GameBoard
where cubes.GetContents.Contains(this)
select cubes;
}
}
I know this is so wrong it's probably not even funny, but this is the roughest of rough cuts.
I'm trying to get GetLocation to return the specific index of the Cube in which the Person is located. So that if the person is in Board.GameBoard[1, 2, 10] I'll be able to retrieve that location (probably as an int[] as listed above). However, at current, I'm unable to compile due to the following error:
Could not find an implementation of the query pattern for source type 'Cubes.Cube[*,*,*]'. 'Where' not found.'
I was pretty sure that LINQ should be able to query multi-dimensional arrays, but I haven't found any documentation on how to do it.
Any suggestions, or am I on the completly wrong track here?
LINQ does not see multidimential arrays as you want it to because they do not implement IEnumerable<T> (although single index arrays do, which is what surprises people). There are several workarounds: you can avoid LINQ for searching the cube or you can write an extension method of your own that does the more traditional walks.
This is a case where I wouldn't use LINQ do to the search, but more than that I probably would keep some references to the various playing pieces in a simple structure (probably a dictionary) that is easier to update and manage. As an idea, your piece object would know where it is on the board itself and could update the cube as it moved by removing itself from one cell and adding itself to another.
It would be important to know if a single cell can contain more than one piece: if so, each cell would need to be a list of some type as well (it appears that way in your code). And once you get to this point, if there are vastly fewer playing pieces than cells, I probably would never actually create the "cube" itself as a datastructure. It would be drawn and the pieces displayed via some Z order drawing algorithm that pulled directly from the piece list, rather than an array. This would depend on the style of game though: if the pieces have attributes and are small in number this would work. If the game is more like 3D Go or similar, then your original cube would make sense... it really depends on how much "personality" (and thus data) your pieces have.
Makes a lot more sense to me to move the int[] currentLocation declaration to the top level inside your Person class, and provide getter/setter methods. Then each Person stores its own location.
For the memory cost of 3 ints, you save yourself from having to query 1000 database entries every time you want to retrieve the person's location.
I think the Person should tell the board where he is, not ask the board. In otherwords, I would create a Location3D class (x,y,z), use that in a GamePiece class that all other things on the board inherit from. That stores location, then each peice knows it's location.
public class Location3D
{
public Location3D(int x, int y, int z) { X = x; Y = y; Z = z; }
public int X { get; set; }
public int Y { get; set; }
public int Z { get; set; }
}
public abstract GamePiece
{
public Location3d { get; set; }
public class Person: GamePiece // inherit GamePiece
{
// everything else about Person
}
public class Board
{
public Board()
{
person = new Person(this);
rnd = new Random();
gameBoard = new Cube[10, 10, 10];
gameBoard.Initialize();
int xAxis = rnd.Next(11);
int yAxis = rnd.Next(11);
int zAxis = rnd.Next(11);
var location = new Location3D(xAxis, yAxis, zAxis);
person.Location = location;
GetCubeAt(location).AddContents(person);
}
public Cube GetCubeAt(Location3D location)
{
return gameBoard[location.X, location.Y, location.Z];
}
public Cube GetCubeAt(int x, int y, int z)
{
return GetCubeAt(new Location3D(x,y,z));
}
}

Categories

Resources