Reading an array from an XML file - c#

At the moment iI got this:
class robot
{
Configuratie config = new Configuratie();
short[,] AlleCoordinaten = new short[3, 6]
{
{1,2,3,4,5,6},
{6,5,4,3,2,1},
{2,3,4,5,6,7}
};
}
But I want to put that array in a XML-file, so this is what I tried:
class robot
{
private static XDocument xdoc = XDocument.Load("configuratie.xml");
public Robot()
{
short[,] AlleCoordinaten = new short[3, 6];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 6; j++)
{
AlleCoordinaten[i, j] = GetPositionValue("position" + (i + 1), j);
}
}
}
public static short GetPositionValue(string position,int index)
{
return (short)xdoc.Descendants(position).Skip(index).First();
}
private void methode2()
{
GoTo[0] = new Position();
for (short a=0 ; a<10 ; a++)
{
GoTo[0].degrees[0] = AlleCoordinaten[a,0];
GoTo[0].degrees[1] = AlleCoordinaten[a,1];
GoTo[0].degrees[2] = AlleCoordinaten[a,2];
GoTo[0].degrees[3] = AlleCoordinaten[a,3];
GoTo[0].degrees[4] = AlleCoordinaten[a,4];
GoTo[0].degrees[5] = AlleCoordinaten[a,5];
//here it tells me The name 'AlleCoordinaten' does not exist in the currect context
}
}
}
configuration file:
class Configuratie
{
private XDocument xdoc;
public Configuratie()
{
xdoc = XDocument.Load("configuratie.xml");
}
public int GetIntConfig(string desc1, string desc2)
{
int value = 0;
if (string.IsNullOrEmpty(desc1))
{
value = 0;
}
if (!string.IsNullOrEmpty(desc1) && !string.IsNullOrEmpty(desc2))
{
foreach (XElement node in xdoc.Descendants(desc1).Descendants(desc2))
{
value = Convert.ToInt16(node.Value);
}
}
if (!string.IsNullOrEmpty(desc1) && string.IsNullOrEmpty(desc2))
{
foreach (XElement node in xdoc.Descendants(desc1))
{
value = Convert.ToInt16(node.Value);
}
}
return value;
}
}
XML file:
<robot>
<position1>1</position1>
<position1>2</position1>
<position1>3</position1>
<position1>4</position1>
<position1>5</position1>
<position1>6</position1>
etc...
<position3>7</position3>
</robot>
It still isnt working, could you guys help me with what I did wrong and maybe give an example.

Using XmlSerializer would simplify things by a lot:
size array automatically;
serialization/deserialization is just few rows of code.
Like this
public class Coordinate
{
public int X1 {get; set;}
public int Y1 {get; set;}
public int Z1 {get; set;}
public int X2 {get; set;}
public int Y2 {get; set;}
public int Z2 {get; set;}
public Coordinate(int x1, int y1, int z1, int x2, int y2, int z2)
{
X1 = x1; Y1 = y1; Z1 = z1; X2 = x2; Y2 = y2; Z2 = z2;
}
}
[XmlArray("Robot")]
public Coordinate[] points = new Coordinate[] {
new Coordinate(1, 2, 3, 4, 5, 6),
new Coordinate(6, 5, 4, 3, 2, 1),
new Coordinate(2, 3, 4 ,5, 6, 7),
}
// serialize (remove long namespace)
var space = new XmlSerializerNamespaces();
space.Add("", "");
var serializer = new XmlSerializer(points.GetType()); // typeof(Coordinate[])
using (var stream = new FileStream("robot.xml", FileMode.Create))
serializer.Serialize(stream, points, space);
// deserialize
using (var stream = new FileStream("robot.xml", FileMode.Open, FileAccess.Read))
points = (Coordinate[])serializer.Deserialize(stream);

Try this method:
public static short GetPositionValue(string position,int index)
{
return (short)xdoc.Descendants(position).Skip(index).First();
}
And populate your array with for loop:
Here is the full code:
class robot
{
private static XDocument xdoc = XDocument.Load("configuratie.xml");
short[,] AlleCoordinaten = new short[3, 6];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 6; j++)
{
AlleCoordinaten[i, j] = GetPositionValue("position" + (i+1), j);
}
}
public static short GetPositionValue(string position,int index)
{
return (short)xdoc.Descendants(position).Skip(index).First();
}
}
Note: CHANGE your xdoc definition:
private XDocument xdoc;
To:
private static XDocument xdoc;

Related

Find largest area using

I need to find largest area with same numbers in 2D array. Example: {{2 2 3}{1 2 3}{1 2 1}}
And mark it in new 2D array with same number for same area.
I will need to color the table with 3 colors, so i use between 1-3 in table[,]
I did test, but it doesn't work properly. ID just stacks too much on the same area.
Second edit: updated the code
public class Matrix
{
public int Height { get; set; }
public int Witdh { get; set; }
public int[,] Table { get; set; }
public int[,] Area { get; set; }
public int ID { get; set; }
public int tempBiggestArea = 0;
public int biggestArea { get; set; }
public Matrix(int height, int witdh)
{
Table = GenerateTable(height, witdh);
Height = height;
Witdh = witdh;
ID = 2;
Area = new int[height,witdh];
}
public int[,] GenerateTable(int height, int witdh)
{
int[,] table = new int[height, witdh];
Random rnd = new Random();
for (int i = 0; i < table.GetLength(0); i++)
{
for (int j = 0; j < table.GetLength(1); j++)
{
table[i, j] = rnd.Next(3) + 1;
}
}
return table;
}
public void Find(int x, int y, int color)
{
if (y < 0)
y = Height - 1;
if (x < 0)
x = Witdh - 1;
if (IsChanged(x, y))
return;
if (Area[x, y] == 0)
{
if (color > 3)
color = 1;
if (Table[x, y] == color)
{
Area[x, y] = ID;
tempBiggestArea++;
Find(x, y - 1, color);
Find(x - 1, y, color);
ID++;
}
}
if (tempBiggestArea > biggestArea)
biggestArea = tempBiggestArea;
tempBiggestArea = 0;
Find(x, y, color + 1);
}
public bool IsChanged(int i, int j)
{
return Area[i, j] != 0;
}

How to traverse a N ary tree

I have some working code with the help of others which creates a 3 deep N ary tree (or just 3 linked nodes), but I don't know how to traverse the list of nodes to find data - for example the trip distance for CarNo=6, Driver=Thor4 and TripNo=38. Sorry if this is trivial, I'm new to data structures and extensive net searches hasn't helped. Thanks for any help.
public class Node
{
public List<Node> Children = new List<Node>();
public Node Parent = null;
public Node(Node fromParent = null)
{
if (fromParent != null)
{
Parent = fromParent;
fromParent.Children.Add(this);
}
}
}
public class Root : Node
{
public int PoolNo;
public int CarNo;
string Make;
public Root(int _PoolNo, int _CarNo, string _Make) : base(null)
{
PoolNo = _PoolNo;
CarNo = _CarNo;
Make = _Make;
}
}
public class Parameter : Node
{
public string Driver;
public Parameter(string _Driver, Node fromParent = null) : base(fromParent)
{
Driver = _Driver;
}
}
public class Value : Node
{
public int TripDistance;
public int TripNo;
public Value(int _TripDistance, int _TripNo, Node fromParent = null) : base(fromParent)
{
TripDistance = _TripDistance;
TripNo = _TripNo;
}
}
List<Node> CarPool = new List<Node>();
public void IDTree()
{
Random Rnd = new Random();
for (int K = 1; K <= 20; K++)
{
var Car = new Root(6,K, "Ford" + K); // PoolNo,CarNo,Make
for (int KK = 1; KK <= 30; KK++)
{
var Driver = new Parameter("Thor" + KK, Car); // Driver
for (int KKK = 1; KKK <= 58; KKK++)
{
int Distance = Rnd.Next(1, 1000);
var Details = new Value(Distance, KKK, Driver); // TripDistance,TripNo
}
}
CarPool.Add(Car);
}
// traverse CarPool list to find trip distance for Carno 6, driver Thor4, tripno 38
foreach(var T in CarPool)
{
// not sure how to do this...
}
}

Multiple List Object only can add single item to preceding lists? First list works

Multiple List Object only can add single item to preceding lists. Only adds last item for second list and of course I need all of them not just the last one.
Here is my Code:
public class MyListData
{
public List<HeaderItem> HeaderItems { get; set; }
public List<MatrixItem> MatrixItems { get; set; }
}
public MyListData GetSchedule()
{
MyListData objTab = new MyListData();
objTab.HeaderItems = new List<HeaderItem>();
//Header loop works perfectly
for(int x=0; x < 7;x++)
{
HeaderItem objItem = new HeaderItem();
objItem.strHeadName = x;
objTab.HeaderItems.Add(objItem);
}
objTab.MatrixItems = new List<MatrixItem>();
for(int x=0; x < 7;x++)
{
MatrixItem objItem = new MatrixItem();
objItem.nHRJobID = x;
objTab.MatrixItems.Add(objItem);
}
//Only adds the last one Need ALL
return objTab;
}
If I need to create a new object then how would I combine say objTab and objMatrix?
Seems to add all seven values for both HeaderItem and MatrixItem, based on the code you shared.
If you want to combine the header and Matrix item into a single list you might use a Tuple<> instead of a nested class. I've created a sample of what that would look like and included the code I used to test your sample code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace listadd
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Original GetSchedule:");
MyListData mld = GetSchedule();
for (int i = 0; i < mld.HeaderItems.Count; i++)
{
Console.WriteLine(string.Format("HeaderItem: {0}, MatrixItem: {1}", mld.HeaderItems[i].strHeadName, mld.MatrixItems[i].nHRJobID));
}
Console.WriteLine();
Console.WriteLine("Tuple GetSchedule:");
var list = GetScheduleCombined();
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine(string.Format("HeaderItem: {0}, MatrixItem: {1}", list[i].Item1.strHeadName, list[i].Item2.nHRJobID));
}
Console.WriteLine();
Console.WriteLine("combined GetSchedule:");
var clist = GetScheduleCombined2();
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine(string.Format("HeaderItem: {0}, MatrixItem: {1}", clist[i].hdrItm.strHeadName, clist[i].mtxItm.nHRJobID));
}
Console.ReadKey();
}
public static List<Tuple<HeaderItem, MatrixItem>> GetScheduleCombined()
{
List<Tuple<HeaderItem, MatrixItem>> list = new List<Tuple<HeaderItem, MatrixItem>>();
for (int x = 0; x < 7; x++)
{
var h = new HeaderItem();
h.strHeadName = x;
var m = new MatrixItem();
m.nHRJobID = x;
list.Add(new Tuple<HeaderItem, MatrixItem>(h, m));
}
return list;
}
public class MyCombined
{
public MyCombined()
{
hdrItm = new HeaderItem();
mtxItm = new MatrixItem();
}
public HeaderItem hdrItm { get; set; }
public MatrixItem mtxItm { get; set; }
}
public static List<MyCombined> GetScheduleCombined2()
{
List<MyCombined> list = new List<MyCombined>();
for (int x = 0; x < 7; x++)
{
var item = new MyCombined();
item.hdrItm.strHeadName = x;
item.mtxItm.nHRJobID = x;
list.Add(item);
}
return list;
}
//----- begin original sample code from question -----
public class MyListData
{
public List<HeaderItem> HeaderItems { get; set; }
public List<MatrixItem> MatrixItems { get; set; }
}
public static MyListData GetSchedule()
{
MyListData objTab = new MyListData();
objTab.HeaderItems = new List<HeaderItem>();
//Header loop works perfectly
for (int x = 0; x < 7; x++)
{
HeaderItem objItem = new HeaderItem();
objItem.strHeadName = x;
objTab.HeaderItems.Add(objItem);
}
objTab.MatrixItems = new List<MatrixItem>();
for (int x = 0; x < 7; x++)
{
MatrixItem objItem = new MatrixItem();
objItem.nHRJobID = x;
objTab.MatrixItems.Add(objItem);
}
//Only adds the last one Need ALL
return objTab;
}
// ---- End original sample code ----
}
}

Problems with a tile worldscreen system?

Im trying to make a tile based world screen for my game , here are the three classes i have
namespace WindowsGame1
{
public enum Tiletype
{Grass,
Water,
Foothill,
Mountain
}
public struct Tile
{
public Tiletype TerrainType { get; set; }
public Texture2D TileGFX { get; set; }
public Rectangle SrcRect { get; set; }
public Vector2 Location { get; set; }
public int AniFrame { get; set; }
// TILE ACTIONS
public bool IsActivated { get; set; }
public bool IsBlocked { get; set; }
public bool IsTouchTrigger { get; set; }
public bool IsStepTrigger { get; set; }
}
}
MapBase class
public class MapBase
{
public Tile[,] TileList = new Tile[1, 1];
public MapBase(int width, int height, Vector2 start)
{
TileList = new Tile[width + 1, height + 1];
// TEMPORARY MAP
for (int X = 0; X <= width; X++)
{
for (int Y = 0; Y <= height; Y++)
{
TileList[X, Y] = new Tile();
var _with1 = TileList[X, Y];
_with1.TerrainType = Tiletype.Water;
_with1.TileGFX = Textures.World;
_with1.AniFrame = 0;
_with1.IsBlocked = true;
}
}
// SIMPLE ISLAND
for (int z = 22; z <= 33; z++)
{
for (int c = 22; c <= 31; c++)
{
TileList[z, c].TerrainType = Tiletype.Grass;
}
}
TileList[27, 25].TerrainType = Tiletype.Foothill;
TileList[28, 25].TerrainType = Tiletype.Foothill;
TileList[27, 24].TerrainType = Tiletype.Foothill;
TileList[28, 26].TerrainType = Tiletype.Mountain;
for (int x = 0; x <= width; x++)
{
for (int y = 0; y <= height; y++)
{
TileList[x, y].SrcRect = GetTileSource(TileList[x, y].TerrainType);
}
}
}
GetTitleSource function
private Rectangle GetTileSource(Tiletype TType)
{
Rectangle sRect = default(Rectangle);
switch (TType)
{
case Tiletype.Grass:
sRect = new Rectangle(0, 0, 16, 16);
break;
case Tiletype.Water:
sRect = new Rectangle(0, 80, 16, 16);
break;
case Tiletype.Foothill:
sRect = new Rectangle(48, 0, 16, 16);
break;
case Tiletype.Mountain:
sRect = new Rectangle(32, 0, 16, 16);
break;
}
return sRect;
}
}
Class WorldScreen
class Worldscreen : BaseScreen
{
public int MapWidth = 100;
public int MapHeight = 100;
public int TileSize = 32;
public int MapX = 20;
public int MapY = 19;
public MapBase Map = new MapBase(100, 100, new Vector2(0, 0));
public Worldscreen(GraphicsDevice device)
: base(device, "WorldScreen")
{
Map = new MapBase(MapWidth, MapHeight, new Vector2(0, 0));
}
Draw function
public override void Draw(GameTime gameTime)
{
base.Draw(gameTime);
Globals.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone);
//DRAW TILE LAYER
for (int DrawX = -1; DrawX <= 16; DrawX++)
{
for (int DrawY = -1; DrawY <= 15; DrawY++)
{
int x = DrawX + MapX;
int y = DrawY + MapY;
if (x > 0 & x <= MapWidth & y >= 0 & y <= MapHeight)
{
Globals.spriteBatch.Draw(Map.TileList[x,y].TileGFX, new Rectangle(DrawX * TileSize, DrawY * TileSize, TileSize, TileSize), Map.TileList[x, y].SrcRect, Color.White);
// VIEW COORDINATES ON TILE
//Globals.SpriteBatch.DrawString(Fonts.Arial_8, "X:" & x & vbCrLf & "Y:" & y, New Vector2(DrawX * TileSize, DrawY * TileSize), Color.Black)
}
}
}
Globals.spriteBatch.End();
}
}
When I try to run the draw void it comes up with this error on the world screen class
This method does not accept null for this parameter.
Parameter name: texture
is there any way to solve this or do i have to rework these classes.
you got all the info you need to debug this yourself :
theres a method on the world screen class who have a texture = null.
Go step-by-step debug and find out which one, unless its a simple error we can find looking at your code, but its often not that easy. ( ex : do you have a list which isnt instanciate ? )
but since its a method paramaters ... the only method that accept a texture as a parameter is GetTileSource.
So quickly what could explain it ... I'd check 2 things :
A- are you sure your loop have correct bound ? You might simply be asking for a tile in that array that doesn't exist since its out of bound. (array are 0 base, and you loop up to <= height instead of < height)
B- 2nd thing i'd check would be (since this is a texture ) that you didn't load one of those texture you use ...

how to use variables of a class from other classes in c#

i need to call variables that are defined in a class
class testclasss
{
public testclass(double[,] values)
{
double[][] rawData = new double[10][];
for (int i = 0; i < 10; i++)
{
rawData[i] = new double[] { values[i, 2], stockvalues[i, 0] }; // if data won't fit into memory, stream through external storage
}
int num = 3;
int max = 30;
}
public int[] checkvalue(double[][] rawData, int num, int maxCount)
{
............
}
}
I have called constructor using
testclass newk = new testclass(values);
now how can i call the function checkvalues(). i tried using newk.num,newk.maxcount but those variables were not recognized.
Just as your class constructor and checkvalues function are public, so too must the properties you wish to access from outside the class. Put these at the top of your class declaration:
public int num {get; set;}
public int max {get; set;}
Then you can access them via newk.num and newk.max.
EDIT: In response to your second comment, I think you might be a bit confused about how functions and properties interact within the same class. This might help:
class TestClass {
private int _num;
private int _max;
private double[][] _rawData;
public TestClass(double[,] values, int num, int max)
{
_num = num;
_max = max;
_rawData = new double[10][];
for (int i = 0; i < 10; i++)
{
_rawData[i] = new double[] { values[i, 2], stockvalues[i, 0] };
}
}
public int[] CheckValues()
{
//Because _num _max and _rawData exist in TestClass, CheckValues() can access them.
//There's no need to pass them into the function - it already knows about them.
//Do some calculations on _num, _max, _rawData.
return Something;
}
}
Then, do this (for example, I don't know what numbers you're actually using):
double[,] values = new double[10,10];
int num = 3;
int max = 30;
Testclass foo = new Testclass(values, num, max);
int[] results = foo.CheckValues();
I believe this is what you're looking for:
class TestClass {
public int num { get; set; }
public int max { get; set; }
public double[][] rawData;
public TestClass(double[,] values)
{
rawData = new double[10][];
for (int i = 0; i < 10; i++)
{
rawData[i] = new double[] { values[i, 2], stockvalues[i, 0] }; // if data won't fit into memory, stream through external storage
}
this.num = 3;
this.max = 30;
}
public int[] CheckValue()
{............}
}
You'll need a property with a get accessor.
Here is a simplified example based on your code:
class testclass
{
private int _num = 0;
private int _max = 0;
public int Num
{
set { _num = value; }
get { return _num; }
}
public int Max
{
set { _max = value; }
get { return _max; }
}
public testclass()
{
Num = 3;
Max = 30;
}
}
//To access Num or Max from a different class:
testclass test = new testclass(null);
Console.WriteLine(test.Num);
Hope that helps.
Using your exact same code, except for public testclass(double[,] values), which I changed to public testfunction(double[,] values)
class testclass
{
public testfunction(double[,] values)
{
double[][] rawData = new double[10][];
for (int i = 0; i < 10; i++)
{
rawData[i] = new double[] { values[i, 2], stockvalues[i, 0] }; // if data won't fit into memory, stream through external storage
}
int num = 3;
int max = 30;
}
public int[] checkvalue(double[][] rawData, int num, int maxCount)
{
............
}
}
Have you tried calling checkvalues() function like this?
testclass.checkvalue();

Categories