I'm trying to calculate the largest common surface of metal sheets in order to reduce wasting our materials.
I belive that I am succeeded but I'am not sure if this is the best way.
Is there any ready Math functions for this?
Here is my solution.
private void frmCalculate_Load(object sender, EventArgs e)
{
//Width and length values can vary, this is just one of possible dimensions.
List<Material> lstGivenMaterials = new List<Calculator.Material>();
lstGivenMaterials.Add(new Calculator.Material(10, 40));
lstGivenMaterials.Add(new Calculator.Material(60, 20));
lstGivenMaterials.Add(new Calculator.Material(5, 20));
var largestCommonSurface = CalculateCommunSurface(lstGivenMaterials);
}
A method who takes a list of Material class.
private decimal? CalculateCommunSurface(List<Material> givenMaterials)
{
decimal? retVal = 0;
var largestMat = givenMaterials.Max(ro => ro.Surface);
var smallestMat = givenMaterials.Min(ro => ro.Surface);
List<Material> possibleComplexing = new List<Material>();
foreach (var mat1 in givenMaterials)
{
foreach (var mat2 in givenMaterials)
{
possibleComplexing.Add(mat1);
possibleComplexing.Add(new Calculator.Material(mat1.Width, mat2.Width));
possibleComplexing.Add(new Calculator.Material(mat1.Width, mat2.Length));
}
}
var possibleValues = possibleComplexing.Where(ro => ro.Surface <= smallestMat).ToList().OrderByDescending(ro => ro.Surface).ToList();
bool isPossible;
foreach (var item in possibleValues)
{
isPossible = true;
foreach (var mat in givenMaterials)
{
//If not suitable for any material, not ok.
if (!mat.IsPossible(item))
{
isPossible = false;
break;
}
}
if (isPossible)
{
retVal = item.Surface;
break;
}
}
return retVal;
}
My material class.
public class Material
{
public decimal Width { get; set; }
public decimal Length { get; set; }
public decimal Surface
{
get
{
return Width * Length;
}
}
public Material(decimal width, decimal length)
{
this.Width = width;
this.Length = length;
}
internal bool IsPossible(Material refMat)
{
bool retVal = false;
if (
(refMat.Width <= this.Width && refMat.Length <= this.Length) ||
(refMat.Width<= this.Length && refMat.Length <= this.Width)
)
{
retVal = true;
}
return retVal;
}
}
Related
I've been successful extracting character data with position data from pdfs but when I am trying to extract words with position data the text doesn't always come out as single words. Things like Saskatchewan could be split into S A SKA TCH EWAN. Is there anyway to fix this? I came across similar issues but the answers were for older versions of itextsharp.
public class TextLocationStrategy : LocationTextExtractionStrategy
{
public static List<PdfText> CharacterResult = new List<PdfText>();
public static List<PdfText> WordResult = new List<PdfText>();
protected override bool IsChunkAtWordBoundary(TextChunk chunk, TextChunk previousChunk)
{
float dist = chunk.GetLocation().DistanceFromEndOf(previousChunk);
if (dist < -chunk.GetLocation().GetCharSpaceWidth() || dist > chunk.GetLocation().GetCharSpaceWidth() / 4.0f)
{
return true;
}
return false;
}
public override void EventOccurred(IEventData data, EventType type)
{
try
{
if (!type.Equals(EventType.RENDER_TEXT))
{
return;
}
TextRenderInfo renderInfo = (TextRenderInfo)data;
string curFont = renderInfo.GetFont().GetFontProgram().ToString();
float curFontSize = renderInfo.GetFontSize();
IList<TextRenderInfo> text = renderInfo.GetCharacterRenderInfos();
string curText = renderInfo.GetText();
if (curText != " " && !curText.Contains(' '))
{
Vector wordStart = renderInfo.GetBaseline().GetStartPoint();
Vector wordEnd = renderInfo.GetAscentLine().GetEndPoint();
Rectangle wordRect = new Rectangle(wordStart.Get(0), wordStart.Get(1), wordEnd.Get(0) - wordStart.Get(0), wordEnd.Get(1) - wordStart.Get(1));
PdfText chunk = new PdfText
{
Text = curText,
Rectangle = wordRect,
FontFamily = curFont,
FontSize = Convert.ToInt32(curFontSize),
SpaceWidth = renderInfo.GetSingleSpaceWidth(),
HorizontalScaling = renderInfo.GetHorizontalScaling(),
Leading = renderInfo.GetLeading(),
CharacterSpacing = renderInfo.GetCharSpacing(),
StartPoint = new Autodesk.AutoCAD.Geometry.Point3d(wordStart.Get(0), wordStart.Get(1), 0.0),
EndPoint = new Autodesk.AutoCAD.Geometry.Point3d(wordEnd.Get(0), wordEnd.Get(1), 0.0)
};
WordResult.Add(chunk);
}
foreach (TextRenderInfo t in text)
{
string letter = t.GetText();
Vector letterStart = t.GetBaseline().GetStartPoint();
Vector letterEnd = t.GetAscentLine().GetEndPoint();
Rectangle letterRect = new Rectangle(letterStart.Get(0), letterStart.Get(1), letterEnd.Get(0) - letterStart.Get(0), letterEnd.Get(1) - letterStart.Get(1));
if (letter != " " && !letter.Contains(' '))
{
PdfText chunk = new PdfText
{
Text = letter,
Rectangle = letterRect,
FontFamily = curFont,
FontSize = Convert.ToInt32(curFontSize),
SpaceWidth = t.GetSingleSpaceWidth(),
HorizontalScaling = t.GetHorizontalScaling(),
Leading = t.GetLeading(),
CharacterSpacing = t.GetCharSpacing(),
StartPoint = new Autodesk.AutoCAD.Geometry.Point3d(letterStart.Get(0), letterStart.Get(1), 0.0),
EndPoint = new Autodesk.AutoCAD.Geometry.Point3d(letterEnd.Get(0), letterEnd.Get(1), 0.0)
};
CharacterResult.Add(chunk);
}
}
}
catch (Exception ex)
{
ErrorManager.ReportError(ex);
}
}
public List<PdfText> GetCharacterData()
{
List<PdfText> retVal = new List<PdfText>();
try
{
retVal = CharacterResult;
}
catch (Exception ex)
{
ErrorManager.ReportError(ex);
}
return retVal;
}
public List<PdfText> GetWordData()
{
List<PdfText> retVal = new List<PdfText>();
try
{
retVal = WordResult;
}
catch (Exception ex)
{
ErrorManager.ReportError(ex);
}
return retVal;
}
}
public class PdfText
{
public string Text { get; set; }
public Rectangle Rectangle { get; set; }
public string FontFamily { get; set; }
public int FontSize { get; set; }
public float SpaceWidth { get; set; }
public float CharacterSpacing { get; set; }
public float Leading { get; set; }
public float HorizontalScaling { get; set; }
public Point3d StartPoint { get; set; }
public Point3d EndPoint { get; set; }
}
I'm trying to implement A* algorithm in order to find the shortest path in given grid.
My Node class:
public class Node : IComparable
{
public Node(int row, int col, Node previousNode = null, double distance = double.PositiveInfinity)
{
this.Row = row;
this.Col = col;
this.PreviousNode = previousNode;
this.Distance = distance;
}
public int Row { get; }
public int Col { get; }
public bool IsVisited { get; internal set; }
public double Distance { get; set; }
public int Weight { get; set; } = 1;
public double GScore { get; set; } = double.PositiveInfinity;
public double H { get; set; }
public double FScore => this.GScore + this.H;
public NodeType? NodeType { get; internal set; }
public Node PreviousNode { get; set; }
public override bool Equals(object obj)
{
var otherNode = obj as Node;
return this.Equals(otherNode);
}
protected bool Equals(Node other)
=> this.Row == other.Row && this.Col == other.Col;
public override int GetHashCode()
{
unchecked
{
return (this.Row * 397) ^ this.Col;
}
}
public int CompareTo(object obj)
{
var otherNode = obj as Node;
if (this.FScore == otherNode.FScore)
{
if (this.H >= otherNode.H)
{
return 1;
}
else if (this.H < otherNode.H)
{
return -1;
}
}
return this.FScore.CompareTo(otherNode.FScore);
}
}
A* algo class:
public override Result Execute(Node[,] grid, Node startNode, Node endNode)
{
var heap = new MinHeap<Node>();
var allSteps = new HashSet<Node>();
startNode.GScore = 0;
startNode.H = ManhattanDistance(startNode, endNode);
startNode.IsVisited = true;
heap.Add(startNode);
while (heap.Count != 0)
{
var currentNode = heap.Pop();
if (currentNode.NodeType == NodeType.Wall)
continue;
allSteps.Add(currentNode);
if (currentNode.Equals(endNode))
{
return new Result(allSteps, this.GetAllNodesInShortestPathOrder(currentNode));
}
var rowDirection = new[] { -1, +1, 0, 0 };
var columnDirection = new[] { 0, 0, +1, -1 };
for (int i = 0; i < 4; i++)
{
var currentRowDirection = currentNode.Row + rowDirection[i];
var currentColDirection = currentNode.Col + columnDirection[i];
if ((currentRowDirection < 0 || currentColDirection < 0)
|| (currentRowDirection >= grid.GetLength(0)
|| currentColDirection >= grid.GetLength(1)))
{
continue;
}
var nextNode = grid[currentRowDirection, currentColDirection];
AddNodeToHeap(currentNode, nextNode, endNode, heap);
}
}
return new Result(allSteps);
}
private void AddNodeToHeap(Node currentNode, Node nextNode, Node endNode, MinHeap<Node> heap)
{
if (nextNode.IsVisited || nextNode.GScore < currentNode.GScore)
return;
var g = currentNode.GScore + nextNode.Weight;
var h = ManhattanDistance(nextNode, endNode);
if (g + h < nextNode.FScore)
{
nextNode.GScore = g;
nextNode.H = h;
nextNode.PreviousNode = currentNode;
nextNode.IsVisited = true;
}
heap.Add(nextNode);
}
private static int ManhattanDistance(Node currentNode, Node endNode)
{
var dx = Math.Abs(currentNode.Row - endNode.Row);
var dy = Math.Abs(currentNode.Col - endNode.Col);
return dx + dy;
}
Custom MinHeap class:
public class MinHeap<T>
{
private readonly IComparer<T> comparer;
private readonly List<T> list = new List<T> { default };
public MinHeap()
: this(default(IComparer<T>))
{
}
public MinHeap(IComparer<T> comparer)
{
this.comparer = comparer ?? Comparer<T>.Default;
}
public MinHeap(Comparison<T> comparison)
: this(Comparer<T>.Create(comparison))
{
}
public int Count => this.list.Count - 1;
public void Add(T element)
{
this.list.Add(element);
this.ShiftUp(this.list.Count - 1);
}
public T Pop()
{
T result = this.list[1];
this.list[1] = this.list[^1];
this.list.RemoveAt(this.list.Count - 1);
this.ShiftDown(1);
return result;
}
private static int Parent(int i) => i / 2;
private static int Left(int i) => i * 2;
private static int Right(int i) => i * 2 + 1;
private void ShiftUp(int i)
{
while (i > 1)
{
int parent = Parent(i);
if (this.comparer.Compare(this.list[i], this.list[parent]) > 0)
{
return;
}
(this.list[parent], this.list[i]) = (this.list[i], this.list[parent]);
i = parent;
}
}
private void ShiftDown(int i)
{
for (int left = Left(i); left < this.list.Count; left = Left(i))
{
int smallest = this.comparer.Compare(this.list[left], this.list[i]) <= 0 ? left : i;
int right = Right(i);
if (right < this.list.Count && this.comparer.Compare(this.list[right], this.list[smallest]) <= 0)
{
smallest = right;
}
if (smallest == i)
{
return;
}
(this.list[i], this.list[smallest]) = (this.list[smallest], this.list[i]);
i = smallest;
}
}
}
The problem is that it doesn't find the optimal path when I have some weights on the map. For example:
Every square on the grid which is marked as a weight node has weight of 10 otherwise it's 1.
Here's example:
Example grid with 3 weight nodes - green node is start node, red node is end node and the dumbbell node is weight node.
When I run the algorithm I get the following result.
It's clearly visible that this is not the shortest path since the algorithm goes through the first node which has weight 1 and then the next node with weight 10 instead of just passing one 10 weight node. The shortest path should've been the red one which I've marked.
P.S I've managed to make it respect the weights by adding new heuristic function when calculating GCost and it now calculates the path but instead of one straight line I get some strange path:
Thank you in advance!
#jdweng
I actually fixed the bug by implementing an additional method which adds additional weight to the GScore
blue squares - all steps which the algorithm took in order to find the shortest final path
A* Algo with weights
A* algo without weights
[
Dijkstra Algo with weights
Dijkstra Algo without weights
private (double weight, NodeDirection? Direction) GetDistanceAndDirection(Node nodeOne, Node nodeTwo)
{
var x1 = nodeOne.Row;
var y1 = nodeOne.Col;
var x2 = nodeTwo.Row;
var y2 = nodeTwo.Col;
if (x2 < x1 && y1 == y2)
{
switch (nodeOne.Direction)
{
case NodeDirection.Up:
return (1, NodeDirection.Up);
case NodeDirection.Right:
return (2, NodeDirection.Up);
case NodeDirection.Left:
return (2, NodeDirection.Up);
case NodeDirection.Down:
return (3, NodeDirection.Up);
}
}
else if (x2 > x1 && y1 == y2)
{
switch (nodeOne.Direction)
{
case NodeDirection.Up:
return (3, NodeDirection.Down);
case NodeDirection.Right:
return (2, NodeDirection.Down);
case NodeDirection.Left:
return (2, NodeDirection.Down);
case NodeDirection.Down:
return (1, NodeDirection.Down);
}
}
if (y2 < y1 && x1 == x2)
{
switch (nodeOne.Direction)
{
case NodeDirection.Up:
return (2, NodeDirection.Left);
case NodeDirection.Right:
return (3, NodeDirection.Left);
case NodeDirection.Left:
return (1, NodeDirection.Left);
case NodeDirection.Down:
return (2, NodeDirection.Left);
}
}
else if (y2 > y1 && x1 == x2)
{
switch (nodeOne.Direction)
{
case NodeDirection.Up:
return (2, NodeDirection.Right);
case NodeDirection.Right:
return (1, NodeDirection.Right);
case NodeDirection.Left:
return (3, NodeDirection.Right);
case NodeDirection.Down:
return (2, NodeDirection.Right);
}
}
return default;
}
and then AddNodeToHeapMethod()
private void AddNodeToHeap(Node currentNode, Node nextNode, Node endNode, MinHeap<Node> heap)
{
if (nextNode.IsVisited)
return;
var (additionalWeight, direction) = this.GetDistanceAndDirection(currentNode, nextNode);
var g = currentNode.GScore+ nextNode.Weight + additionalWeight;
var h = this.ManhattanDistance(nextNode, endNode);
if (g < nextNode.GScore)
{
nextNode.GScore= g;
nextNode.H = h;
nextNode.PreviousNode = currentNode;
nextNode.IsVisited = true;
}
currentNode.Direction = direction;
heap.Add(nextNode);
}
This is the static array I have been given in making a RPN calculator. From this code the RPN calculator adds and subtracts. Now I need to extend my code to multiply and divide but I cant I don't know how.
public class IntStack
{
private const int maxsize = 10;
private int top = 0;
private int[] array = new int[maxsize];
public void Push(int value)
{
array[top++] = value;
}
public int Pop()
{
return array[--top];
}
public int Peek()
{
return array[top - 1];
}
public bool IsEmpty()
{
return top == 0;
}
public bool IsFull()
{
return top == maxsize;
}
public string Print()
{
StringBuilder output = new StringBuilder();
for (int i = top - 1; i >= 0; i--)
output.Append(array[i] + Environment.NewLine);
return output.ToString();
}
}
Here are some methods you can add to your IntStack class that will perform the multiply and division operations. I've added minimal error checking.
public void Multiply()
{
if (array.Length < 2)
return;
var factor1 = Pop();
var factor2 = Pop();
Push(factor1 * factor2);
}
public void Divide()
{
if (array.Length < 2)
return;
var numerator = Pop();
var divisor = Pop();
if (divisor == 0) { // Return stack back to original state.
Push(divisor);
Push(numerator);
return;
}
Push(numerator / divisor);
}
I am trying to make an animation in which a rocket like thing will go up the screen and blast into various parts and follow its path down and fade just like actual firecracker. I have tried to make it using an update loop and a draw loop and then rendering the images on a bitmap. But there is a lot of lag there in the animation. I want to implement this thing at the end of my game and when a user taps the screen the rocket will go to that place and then explode. The code which I have tried is here...
public class Plotter : UserControl, IDisposable
{
Random _rand = new Random((int)DateTime.Now.Ticks);
WriteableBitmap _particleBmp;
EventBlob[] _data;
private int NUMPBLOBS = 25;
private const int CANWIDTH = 1366;
private const int CANHEIGHT = 768;
double _lastx, _lasty;
public Plotter()
{
}
public async Task PlotterMethod(Point current)
{
_lastx = current.X;
_lasty = current.Y;
await Setup();
}
private async Task Setup()
{
_particleBmp = await Util.LoadBitmap("tspark.png");
CompositionTarget.Rendering += CompositionTarget_Rendering;
_data = new EventBlob[NUMPBLOBS];
int ang = 0;
for (int i = 0; i < NUMPBLOBS; i++)
{
EventBlob eb = new EventBlob();
eb.img = _particleBmp;
eb.SourceRect = new Rect(0, 0, 30, 30);
eb.Position.X = _rand.Next((int)_lastx - 10, (int)_lastx + 10);
eb.Position.Y = _rand.Next((int)_lasty - 10, (int)_lasty + 10);
eb.VX = 5;
eb.VY = 5;
eb.angle = ang;
ang += 36 / 5;
eb.Opacity = 1;
eb.BlendMode = WriteableBitmapExtensions.BlendMode.Additive;
eb.FadeRate = _rand.NextDouble() * 0.005 + 0.002;
Color c = new Color();
c.A = (byte)0;
c.R = (byte)_rand.Next(0, 255);
c.G = (byte)_rand.Next(0, 255);
c.B = (byte)_rand.Next(0, 255);
eb.Color = c;
_data[i] = eb;
}
}
int counterupdate = 0;
void CompositionTarget_Rendering(object sender, object e)
{
if (counterupdate % 2 == 0)
{
Update();
DrawBitmap();
}
counterupdate++;
}
int count = 0;
bool opacitycheck = true;
private void Update()
{
bool isallclear = true;
for (int i = 0; i < _data.Length; i++)
{
var p = _data[i];
if (i < 51)
{
p.VX = 2 * Math.Cos(p.angle);
p.VY = 2 * Math.Sin(p.angle);
}
p.Position.X += p.VX;
p.Position.Y += p.VY;
if (opacitycheck)
{
if (p.Color.A + 30 < 255)
p.Color.A += 30;
else
{
opacitycheck = false;
p.Color.A = 255;
}
}
else
{
if (p.Color.A - 30 > 0)
p.Color.A -= 30;
else
{
p.Color.A = 0;
}
}
if (p.Color.A != 0)
{
isallclear = false;
}
}
count++;
if (isallclear)
{
_data = new EventBlob[0];
CompositionTarget.Rendering -= CompositionTarget_Rendering;
NUMPBLOBS = 0;
opacitycheck = true;
Completed(this, null);
}
}
private void DrawBitmap()
{
using (TargetBmp.GetBitmapContext())
{
TargetBmp.Clear();
for (int i = 0; i < _data.Length; i++)
{
var b = _data[i];
this.TargetBmp.Blit(b.Position, b.img, b.SourceRect, b.Color, b.BlendMode);
}
TargetBmp.Invalidate();
}
}
public WriteableBitmap TargetBmp { get; set; }
public Image Imagemain { get; set; }
public event EventHandler<object> Completed;
public void Dispose()
{
}
}
public class EventBlob
{
public double Opacity { get; set; }
public double FadeRate { get; set; }
public Color Color;
public Rect SourceRect { get; set; }
public WriteableBitmap img { get; set; }
public Point Position;
public double VX { get; set; }
public double VY { get; set; }
public WriteableBitmapExtensions.BlendMode BlendMode;
public double angle { get; set; }
}
and in my main page i have called it like this...
async void MainPage_PointerPressed(object sender, PointerRoutedEventArgs e)
{
if (LayoutRoot.Children.Count < 6)
{
Plotter asd = new Plotter();
await asd.PlotterMethod(e.GetCurrentPoint(LayoutRoot).Position);
WriteableBitmap _wb = new WriteableBitmap(1366, 786);
asd.TargetBmp = _wb;
Image image = new Image();
image.Height = 786;
image.Width = 1366;
image.Stretch = Stretch.Fill;
image.Source = _wb;
asd.Imagemain = image;
asd.Completed += asd_Completed;
LayoutRoot.Children.Add(image);
}
}
void asd_Completed(object sender, object e)
{
var obj = (Plotter)sender;
LayoutRoot.Children.Remove(obj.Imagemain);
obj.Dispose();
}
but there is too much of lag if I create 4 of these objects the fps goes down to 10.
Please suggest a better way or a way to optimize this code. Thanks.
Try implementing the parallel feature of C# , For Reference check
http://www.parallelcsharp.com/
I hope this will solve your Problem
To start off I am new to C# and I am in need of some help. I a class that contains a list. I can set the items in the list from the application but not from the class(where it needs to be done). I am also needing to move an event to class as well. This works in the app as well. Any help with this is greatly appreciated. Below is the code from my class:
namespace CarRace
{
class Cars
{
public string Name { get; set; }
public int StartPOS { get; set; }
public int Speed { get; set; }
public int CurPOS { get; set; }
public double Location { get; set; }
public Cars(string Name, int StartPOS, int Speed, int CurPOS, long Location)
{
this.Name = Name;
this.StartPOS = StartPOS;
this.Speed = Speed;
this.CurPOS = 0;
this.Location = 0;
}
public static int CompareCurrentLocation(Cars c1, Cars c2)
{
return c2.Location.CompareTo(c1.Location);
}
}
}
I am needing to add this to the class:
if (File.Exists("NewRace.xml"))
{
XDocument doc = XDocument.Load("NewRace.xml");
var nCars = doc.Descendants("Car").Select(x => new Cars("", 0, 0, 0, 0)
{
Name = x.Attribute("Name").Value,
StartPOS = int.Parse(x.Attribute("StartPOS").Value),
Speed = int.Parse(x.Attribute("Speed").Value),
CurPOS = 0
});
}
And this:
int p = 1;
int prevPOS = 1;
DateTime? PrevTime;
double dist = 0;
double PrevLoc = 0;
if (i == 0)
{
return;
}
foreach (var car in RaceList)
{
dist = (((car.Speed * 1609.344) * 1) / 1609.344) / 3600;
car.Location = car.Location + dist;
}
Comparison<Cars> compLoc = Cars.CompareCurrentLocation;
RaceList.Sort(compLoc);
PrevTime = DateTime.Now;
foreach (var car in RaceList)
{
if (car.Location != PrevLoc)
{
car.CurPOS = p;
}
else
{
car.CurPOS = prevPOS;
}
prevPOS = car.CurPOS;
PrevLoc = car.Location;
p++;
}
Thanks
Thanks for all of your replies. I tried the car.speed/3600 but only get
back 0 for that so I did the long way. I did get everything working
the way I needed it to.
That's because you are doing an integer division (car.Speed is of type int) so the fractional part of the result is discarded. Since the car's speed is less than 3600 this would hence always result in zero. You can avoid this by casting car.Speed to a double first - this should produce the result you want:
dist = (double)car.Speed / 3600;
Thanks for all of your replies. I tried the car.speed/3600 but only get back 0 for that so I did the long way. I did get everything working the way I needed it to. I am a rookie at this and any tips are greatly appreciated. Below is the code I have updated to.
namespace CarRace
{
class Cars
{
public string Name { get; set; }
public int StartPOS { get; set; }
public int CurPOS { get; set; }
public int Speed { get; set; }
public double Location { get; set; }
public string Make { get; set; }
private static List<Cars> CarList;
private static string ProgPart;
public Cars(string Name, int StartPOS, int CurPOS, int Speed, double Location, string Make)
{
this.Name = Name;
this.StartPOS = StartPOS;
this.CurPOS = CurPOS;
this.Speed = Speed;
this.Location = Location;
this.Make = Make;
}
public static List<Cars> FillList()
{
return CarList;
}
public static void Main()
{
try
{
bool Prog = false;
//Get Part to display
while (!Prog)
{
Console.WriteLine("Select the part you would like to test.(1 or 2)");
ProgPart = Console.ReadLine();
if (ProgPart == "1" || ProgPart == "2")
{
Prog = true;
}
}
Console.WriteLine("----------------------------------------");
//Read XML File and set the CarList
if (File.Exists("NewRace.xml"))
{
XDocument doc = XDocument.Load("NewRace.xml");
var nCars = doc.Descendants("Car").Select(x => new Cars("", 0, 0, 0, 0, "")
{
Name = x.Attribute("Name").Value,
StartPOS = int.Parse(x.Element("StartPOS").Value),
CurPOS = 0,
Speed = int.Parse(x.Element("Speed").Value),
Location = double.Parse(x.Element("Location").Value),
Make = x.Attribute("Make").Value
});
CarList = new List<Cars>();
foreach (var car1 in nCars)
{
if (ProgPart == "1")
{
CarList.Add(new Cars(car1.Name, car1.StartPOS, car1.CurPOS, car1.Speed, car1.Location, car1.Make));
}
else
{
CarList.Add(new Cars(car1.Name, car1.StartPOS, car1.CurPOS, 0, car1.Location, car1.Make));
}
}
}
else
{
Console.WriteLine("File Not Found!");
Console.ReadKey();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public static int CompareCurrentLocation(Cars c1, Cars c2)
{
return c2.Location.CompareTo(c1.Location);
}
public static Boolean UpdateLeaderBoard(long i)
{
try
{
int p = 1;
int prevPOS = 1;
DateTime? PrevTime;
double dist = 0;
double prevLocation = 0;
if (i == 0)
{
return false;
}
foreach (var car in CarList)
{
if (ProgPart == "2")
{
switch (car.Make)
{
case "300ZX":
//Slow continuous gain of speed by percentage after 60 with top speed of 320.
if (i <= 15)
{
car.Speed = car.Speed + (60 / 10);
}
else if (car.Speed < 320)
{
double percent = (double)(car.Speed * .1);
if ((Convert.ToInt32(car.Speed + percent)) > 320)
{
car.Speed = 320;
}
else
{
car.Speed = Convert.ToInt32(car.Speed + (percent));
}
}
break;
case "Camero":
//0-60 4 seconds 60-220 20 seconds Top 220
if (i <= 4)
{
car.Speed = car.Speed + (60 / 4);
}
else if (i <= 20)
{
car.Speed = car.Speed + 10;
}
break;
case "Mustang":
//0-top(210) 25 seconds
if (car.Speed <= 200)
{
car.Speed = car.Speed + (200 / 20);
}
break;
case "VW Bug":
//Constant Speed
car.Speed = 165;
break;
default:
Console.WriteLine("Make not found");
break;
}
}
//Set Cars Current Location
dist = (((car.Speed * 1609.344) * 1) / 1609.344) / 3600;
car.Location = car.Location + dist;
}
//Sort list by location
Comparison<Cars> compLoc = Cars.CompareCurrentLocation;
CarList.Sort(compLoc);
PrevTime = DateTime.Now;
//Set the Current Position
foreach (var car in CarList)
{
if (car.Location != prevLocation)
{
car.CurPOS = p;
}
else
{
car.CurPOS = prevPOS;
}
prevPOS = car.CurPOS;
prevLocation = car.Location;
p++;
}
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
}
}