Give an Array a Value - c#

I am trying to make a game where an image appears, and if it is not clicked the image should disappear. I need help giving my array a value of three, then subtract it in another method.
Code:
NameCount = -1;
NameCount++;
Grid.SetColumn(mole, ranCol);
Grid.SetRow(mole, ranRow);
grid_Main.Children.Add(mole);
for (int i = 0; i < NumofImages; i++)
{
//Where I must give a value to the array of the array to 3 for every image that appears.
}
//Where I am trying to make the image disappear after 3 seconds.
private void deleteMole()
{
NumofImages = TUtils.GetIniInt(Moleini, "NumPictures", "pictures", 8);
NumberofImages = Convert.ToInt32(NumofImages);
for (int j = 0; j < NumofImages; j++)
{
CounterArray[j]--;
if (CounterArray[j] == 0)
{
//Not Sure How to delete image
Thanks for the help!

You could keep track of the images in another array.
After you add the image to the view you should also add it to the array:
images[j] = mole;
Then later:
if (CounterArray[j] == 0)
{
grid_Main.Children.Remove(images[j]);
}
But using static arrays and separating data is not a good idea.
If you can you should better aggregate all the metadata and the image together in the same structure:
class Mole
{
public int Counter { get; set; }
public Control Image { get; set; }
}
and manage them in a single List<Mole>; adding and removing them will be simpler.
Here is some code that illustrates the idea (won't compile):
class Mole
{
public int X { get; set; }
public int Y { get; set; }
public int Counter { get; set; }
public Control Image { get; set; }
public bool IsNew { get; set; }
}
class Test
{
IList<Mole> moles = new List<Mole>();
private static void AddSomeMoles()
{
moles.Add(new Mole{ X = rand.Next(100), Y = rand.Next(100), Counter = 3, Image = new PictureBox(), IsNew = true });
}
private static void DisplayMoles()
{
foreach (Mole mole in moles)
{
if (mole.IsNew)
{
grid_Main.Children.Add(mole.Image);
mole.IsNew = false;
}
}
}
private static void CleanupMoles()
{
foreach (Mole mole in moles)
{
mole.Counter -= 1;
if (mole.Counter <= 0)
{
grid_Main.Children.Remove(mole.Image);
moles.Remove(mole);
}
}
}
static void Main()
{
while (true)
{
AddSomeMoles();
DisplayMoles();
Thread.Sleep(1000);
CleanupMoles();
}
}
}

If you want to give every element in a List a certain value, use a foreach loop. In this case, it would look like:
foreach(int currentElement in CounterArray)
{
currentElement = 3;
}
This will loop through each element of the List and set it to 3.
EDIT: If you're using an array, which you are, you would do the following:
for (int i = 0; i < CounterArray.Length; i++)
{
CounterArray[i] = 3;
}

Related

How to add an element at an index in singly linked list in C#

I am implementing linked-list data-structure in C#. I am facing below issue.
When I am try to add element at an index in singly linked list then it not working.
below is my code. Issue is in function AddToIndex. It is not working properly.
Node
public class DNode
{
public int data;
public DNode next;
public DNode(int d)
{
data = d;
}
}
LinkedList
public class DLinkedList
{
public int data;
public DNode Next { get; set; }
public DNode Head { get; private set; }
public DNode Tail { get; private set; }
public int Count { get; set; }
public void AddToHead(int element)
{
DNode temp = new DNode(element);
temp.next = Head;
Head = temp;
Count++;
if (Count == 1)
{
Tail = Head;
}
}
public void AddToIndex(int element, int index)
{
DNode temp = new DNode(element);
for (int i = 1; i < index - 1; i++)
{
Head = Head.next;
}
temp.next = Head;//in this case infinite link list
//temp.next = Head.next; in this case one element is removed.
Head.next = temp; // whole link list is not created, partial linked list created
}
public void Display()
{
DNode temp = Head;
while (temp != null)
{
System.Console.WriteLine(temp.data);
temp = temp.next;
}
}
}
To display result set
static class Program
{
static void Main(string[] args)
{
DLinkedList dLinked = new DLinkedList();
dLinked.AddToHead(5);
dLinked.AddToHead(7);
dLinked.AddToHead(10);
dLinked.AddToHead(11);
Console.WriteLine("---Add Head---");
dLinked.Display();
dLinked.AddToIndex(12, 4);
Console.WriteLine("---After AddToIndex function");
dLinked.Display();
}
}
Result on Console:
---Add Head---
11
10
7
5
---After AddToIndex function Called --
7
12
5
Note: I am just building this no test cases is run .
you are modifying the head of the linked list, which should not be done. try taking another temp variable and assign it to head. like the code below.
public void AddToIndex(int element, int index)
{
DNode temp = new DNode(element);
DNode temp1=Head;
for (int i = 1; i < index - 1; i++)
{
temp1 = temp1.next;
}
temp.next=temp1.next
temp1.next=temp
}

Separate items by dictionary or list

I'm developing a game server for a game client. The game's character has an inventory, like any other game. The inventory has 4 tabs:
Equipment, Potions, Extra, Cash
Currently, the CharacterItems class is a List<Item>, where each Item object contains a Slot property which indicates the position of the item inside the window (the window is 4 by 4).
I don't really like this approach as it doesn't really indicate where each item is located, where with a dictionary I can have keys for each tab and then organize the item. However, I also need to index the items with a slot. So how can I use this approach with a dictionary? Wouldn't I need two dictionaries like so? Dictionary<InventoryTab, Dicitionary<int, Item>>, where InventoryTab is a certain tab and the keyed collection is indexed by the item's slot? Seems too cluttered, perhaps there is a better appraoch for this?
Also, the character also has wearable equipment on it. So that means I have to create another definition in the dictionary for equipped tab, which kinda ruins the logic.
Here's a test for the apparoach I mentioned before:
using System;
using System.Collections.Generic;
using System.Linq;
namespace InventoryTest
{
class Program
{
static void Main(string[] args)
{
var inventory = new Inventory();
while (true)
{
var mapleId = new Random().Next(1000000, 5999999);
short str = 0;
short dex = 0;
short intt = 0;
short luk = 0;
if (mapleId >= 1000000 && mapleId <= 1999999)
{
str = (short)new Random().Next(0, 5);
dex = (short)new Random().Next(0, 5);
intt = (short)new Random().Next(0, 5);
luk = (short)new Random().Next(0, 5);
}
var item = new Item()
{
MapleId = mapleId,
Str = str,
Dex = dex,
Int = intt,
Luk = luk
};
inventory.Add(item);
Console.ReadLine();
}
}
}
class Item
{
public int MapleId { get; set; }
public short Str { get; set; }
public short Dex { get; set; }
public short Int { get; set; }
public short Luk { get; set; }
public Tab Tab
{
get
{
return (Tab)(this.MapleId / 1000000);
}
}
}
enum Tab : byte
{
Equip = 1,
Use,
Setup,
Etc,
Cash
}
class Inventory : Dictionary<Tab, Dictionary<sbyte, Item>>
{
public Inventory()
: base()
{
foreach (var tab in Enum.GetValues(typeof(Tab)).Cast<Tab>())
{
base.Add(tab, new Dictionary<sbyte, Item>(96));
}
}
public void Add(Item item)
{
var nextFreeSlot = this.GetNextFreeSlot(item.Tab);
this[item.Tab].Add(nextFreeSlot, item);
Console.WriteLine("Added new item to {0} tab. Info:", item.Tab);
Console.WriteLine("Slot: {0}", nextFreeSlot);
Console.WriteLine("MapleId: {0}", item.MapleId);
if (item.Str > 0)
{
Console.WriteLine("Str: {0}", item.Str);
}
if (item.Dex > 0)
{
Console.WriteLine("Dex: {0}", item.Dex);
}
if (item.Int > 0)
{
Console.WriteLine("Int: {0}", item.Int);
}
if (item.Luk > 0)
{
Console.WriteLine("Luk: {0}", item.Luk);
}
}
private sbyte GetNextFreeSlot(Tab tab)
{
sbyte slot = 0;
foreach (var item in this[tab])
{
if (item.Key == slot)
{
slot += 1;
}
else
{
break;
}
}
return slot;
}
}
}

list class property in a class c# assign value

class Program
{
static void Main(string[] args)
{
Posting onjPosting = null;
List<Posting> objList = null;
for (int i = 0; i < 100; i++)
{
onjPosting = new Posting();
onjPosting.Key1 = i;
for (int j = 0; j < 5; i++)
{
Choice objChoice = new Choice();
objChoice.ID = i;
objChoice.VAL = j;
onjPosting.GetPostingChoice.Add(objChoice); // GETTING ERROR [ Object reference not set to an instance of an object. ]
}
objList.Add(onjPosting);
}
}
}
public class Choice
{
public int ID { get; set; }
public int VAL { get; set; }
}
public class Posting
{
public int Key1 { get; set; }
public List<Choice> GetPostingChoice { get; set; }
}
While looping through and assigning the value I am getting error . How to solve this ? Please help me out .
My requirement is one parent class (Posting) , can contain number of data List .
Thanks in advance .
You never allocate the GetPostingChoice list so of course it is null.
You could do it in the constructor:
public class Posting
{
public Posting()
{
GetPostingChoice = new List<Choice>();
}
public int Key1 { get; set; }
public List<Choice> GetPostingChoice { get; set; }
}
Add a public constructor on your Posting class:
public class Posting
{
public int Key1 { get; set; }
public List<Choice> GetPostingChoice { get; set; }
public Posting()
{
GetPostingChoice = new List<Choice>();
}
}
You also have other errors:
You do not initialize objList, so you cannot add in there.
List<Posting> objList = null;
So you will get another Null Reference when you get to:
List<Posting> objList = null;
In your second loop you increase i instead of j so it will never end.
for (int j = 0; j < 5; i++)
This is how it should look:
Posting onjPosting = null;
List<Posting> objList = new List<Posting>();
for (int i = 0; i < 1; i++)
{
onjPosting = new Posting();
onjPosting.Key1 = i;
for (int j = 0; j < 5; j++)
{
Choice objChoice = new Choice();
objChoice.ID = i;
objChoice.VAL = j;
onjPosting.GetPostingChoice.Add(objChoice); // GETTING ERROR [ Object reference not set to an instance of an object. ]
}
objList.Add(onjPosting);
}
Since you ask for another approach, and this is just one of the many ways you could do it, have a look at this:
List<Posting> objList = new List<Posting>();
Enumerable.Range(0,100)
.Select
(
(x,i)=>new Posting
{
Key1 = i,
GetPostingChoice = Enumerable.Range(0,5).Select((p,j)=>new Choice{ID = i,VAL = j}).ToList()
}
);

Adding data to a list inside a class

I want to fill a list<int> inside a class I can't get it to work.
(Some / Most of the code is from here
The class:
class Fiu
{
public int feleseg { get; set; }
public List<int> preferencia { get; set; }
public Fiu (int _feleseg) : this()
{
feleseg = _feleseg;
}
public Fiu()
{
this.preferencia = new List<int>();
}
}
The code:
for (int i = 1; i < 4; i++)
{
Fiu ujfiu = new Fiu(0);
for (int j = 1; j < 4; j++)
{
ujfiu.preferencia[j-1] = 1;
}
}
The main goal would be filling it from excel, but right now it doesn't even put 1-s in. I don't know what's wrong.
I get a "Argument out of range exception unhandled" error.
Replace This:
ujfiu.preferencia[j-1] = 1;
With This:
ujfiu.preferencia.Add(1);

Compare properties of two objects fast c#

I have two objects of same type with different values:
public class Itemi
{
public Itemi()
{
}
public int Prop1Min { get; set; }
public int Prop1Max { get; set; }
public int Prop2Min { get; set; }
public int Prop2Max { get; set; }
public int Prop3Min { get; set; }
public int Prop3Max { get; set; }
...................................
public int Prop25Min { get; set; }
public int Prop25Max { get; set; }
}
Now I instantiate two objects of this type and add some values to their properties.
Itemi myItem1 = new Itemi();
myItem1.Prop1Min = 1;
myItem1.Prop1Max = 4;
myItem1.Prop2Min = 2;
myItem1.Prop2Max = 4;
myItem1.Prop3Min = -1;
myItem1.Prop3Max = 5;
.............................
myItem1.Prop25Min = 1;
myItem1.Prop25Max = 5;
Itemi myItem2 = new Itemi();
myItem2.Prop1Min = 1;
myItem2.Prop1Max = 5;
myItem2.Prop2Min = -10;
myItem2.Prop2Max = 3;
myItem2.Prop3Min = 0;
myItem2.Prop3Max = 2;
................................
myItem2.Prop25Min = 3;
myItem2.Prop25Max = 6;
What is the best and fastest way to do this comparison:
take each properties from myItem1 and check if values from Prop1-25 Min and Max are within the range values of myItem2 Prop1-25 Min and Max
Example:
myItem1.Prop1Min = 1
myItem1.Prop1Max = 4
myItem2.Prop1Min = 1
myItem2.Prop1Max = 5
this is True because mtItem1 Prop1 min and max are within the range of myItem2 min and max.
the condition should be AND in between all properties so in the end after we check all 25 properties if all of them are within the range of the second object we return true.
Is there a fast way to do this using Linq or other algorithm except the traditional if-else?
I would refactor the properties to be more along the lines of:
public class Item
{
public List<Range> Ranges { get; set; }
}
public class Range
{
public int Min { get; set; }
public int Max { get; set; }
}
Then your comparison method could be:
if (myItem1.Ranges.Count != myItem2.Ranges.Count)
{
return false;
}
for (int i = 0; i < myItem1.Ranges.Count; i++)
{
if (myItem1.Ranges[i].Min < myItem2.Ranges[i].Min ||
myItem1.Ranges[i].Max > myItem2.Ranges[i].Max)
{
return false;
}
}
return true;
Otherwise you will have to use Reflection, which is anything but fast.
Linq is using standart statements like if...then, for each and other, there is no magic :)
If the final goal only to compare, without needing to say, which properties are not in the range, then you not need to check them all, on the first unequals you can end checking.
Because you have so much properties, you must think about saving it in Dictionary, or List, for example. Or to use dynamic properties (ITypedList), if it will use for binding.
You really should do something like Ginosaji proposed.
But if you want to go with your current data model, here is how I would solve it. Happy typing. :)
public static bool RangeIsContained(int outerMin, int outerMax, int innerMin, int innerMax)
{
return (outerMin <= innerMin && outerMax >= innerMax);
}
public bool IsContained(Itemi outer, Itemi inner)
{
return RangeIsContained(outer.Prop1Min, outer.Prop1Max, inner.Prop1Min, inner.Prop1Max)
&& RangeIsContained(outer.Prop2Min, outer.Prop2Max, inner.Prop2Min, inner.Prop2Max)
// ...
&& RangeIsContained(outer.Prop25Min, outer.Prop25Max, inner.Prop25Min, inner.Prop25Max);
}
With your data model this is basically the only way to go except for reflection (slow!). LINQ cannot help you because your data is not enumerable.
For the sake of completeness, here is a LINQ solution (but it's less performant and less readable than Ginosaji's solution!)
public class Range
{
public int Min { get; set; }
public int Max { get; set; }
public static bool IsContained(Range super, Range sub)
{
return super.Min <= sub.Min
&& super.Max >= sub.Max;
}
}
public class Itemi
{
public Itemi()
{
properties = new Range[25];
for (int i = 0; i < properties.Length; i++)
{
properties[i] = new Range();
}
}
private Range[] properties;
public IEnumerable<Range> Properties { get { return properties; } }
public static bool IsContained(Itemi super, Itemi sub)
{
return super.properties
.Zip(sub.properties, (first, second) => Tuple.Create(first, second))
.All((entry) => Range.IsContained(entry.Item1, entry.Item2));
}
public Range Prop1
{
get { return properties[0]; }
set { properties[0] = value; }
}
public Range Prop2
{
get { return properties[1]; }
set { properties[1] = value; }
}
// ...
}

Categories