Related
I need some kind of class or structure to hold data for 4 players in a simple game. How can I change the player class in every turn during the loop?
I mean something similar to this, where in every turn of a loop some instructions are chaning the data in the class of each player. Is there any effortless way to do this instead of creating many ifs?
internal class Program
{
private static void Main(string[] args)
{
Player player1 = new Player();
Player player2 = new Player();
Player player3 = new Player();
Player player4 = new Player();
int playerTurn = 1;
while(true)
{
//some instructions to change the data for example
//player(playerTurn).x = 1
}
}
}
class Player
{
public int x = 0;
public int y = 0;
}
Whenever you have numbered variables like this:
Player player1 = new Player();
Player player2 = new Player();
Player player3 = new Player();
Player player4 = new Player();
What you probably want is a collection. For example:
var players = new List<Player>
{
new Player(),
new Player(),
new Player(),
new Player()
};
Then you can loop over the list, change specific elements therein, etc.
In your specific case, it looks like you want to access the specific Player by an index:
//player(playerTurn).x = 1
You can do this with the list index:
players[playerTurn].x = 1;
Though if the list is ever sorted, that index is gone. In this case you might instead use a Dictionary<int, Player>. For example:
var players = new Dictionary<int, Player>
{
{ 1, new Player() },
{ 2, new Player() },
{ 3, new Player() },
{ 4, new Player() }
}
In this case each Player object is always and consistently uniquely identified by that integer value. And the usage is the same:
players[playerTurn].x = 1;
Alternatively, you might create a unique identifier on the Player itself. For example, suppose it has an ID property that you can set:
var players = new List<Player>
{
new Player { ID = 1 },
new Player { ID = 2 },
new Player { ID = 3 },
new Player { ID = 4 }
};
In this case you can still use the more generically versatile List<Player> structure, and query it to find the specific Player:
players.Single(p => p.ID == playerTurn).x = 1;
There are other collection types you can use. You could even take it a step further and create a custom PlayerList object which internally contains a collection, the current "turn", and other information about the list of players. But overall the point is that collection types are useful when you have a series of objects.
What are all the array initialization syntaxes that are possible with C#?
These are the current declaration and initialization methods for a simple array.
string[] array = new string[2]; // creates array of length 2, default values
string[] array = new string[] { "A", "B" }; // creates populated array of length 2
string[] array = { "A" , "B" }; // creates populated array of length 2
string[] array = new[] { "A", "B" }; // created populated array of length 2
Note that other techniques of obtaining arrays exist, such as the Linq ToArray() extensions on IEnumerable<T>.
Also note that in the declarations above, the first two could replace the string[] on the left with var (C# 3+), as the information on the right is enough to infer the proper type. The third line must be written as displayed, as array initialization syntax alone is not enough to satisfy the compiler's demands. The fourth could also use inference. So if you're into the whole brevity thing, the above could be written as
var array = new string[2]; // creates array of length 2, default values
var array = new string[] { "A", "B" }; // creates populated array of length 2
string[] array = { "A" , "B" }; // creates populated array of length 2
var array = new[] { "A", "B" }; // created populated array of length 2
The array creation syntaxes in C# that are expressions are:
new int[3]
new int[3] { 10, 20, 30 }
new int[] { 10, 20, 30 }
new[] { 10, 20, 30 }
In the first one, the size may be any non-negative integral value and the array elements are initialized to the default values.
In the second one, the size must be a constant and the number of elements given must match. There must be an implicit conversion from the given elements to the given array element type.
In the third one, the elements must be implicitly convertible to the element type, and the size is determined from the number of elements given.
In the fourth one the type of the array element is inferred by computing the best type, if there is one, of all the given elements that have types. All the elements must be implicitly convertible to that type. The size is determined from the number of elements given. This syntax was introduced in C# 3.0.
There is also a syntax which may only be used in a declaration:
int[] x = { 10, 20, 30 };
The elements must be implicitly convertible to the element type. The size is determined from the number of elements given.
there isn't an all-in-one guide
I refer you to C# 4.0 specification, section 7.6.10.4 "Array Creation Expressions".
Non-empty arrays
var data0 = new int[3]
var data1 = new int[3] { 1, 2, 3 }
var data2 = new int[] { 1, 2, 3 }
var data3 = new[] { 1, 2, 3 }
var data4 = { 1, 2, 3 } is not compilable. Use int[] data5 = { 1, 2, 3 } instead.
Empty arrays
var data6 = new int[0]
var data7 = new int[] { }
var data8 = new [] { } and int[] data9 = new [] { } are not compilable.
var data10 = { } is not compilable. Use int[] data11 = { } instead.
As an argument of a method
Only expressions that can be assigned with the var keyword can be passed as arguments.
Foo(new int[2])
Foo(new int[2] { 1, 2 })
Foo(new int[] { 1, 2 })
Foo(new[] { 1, 2 })
Foo({ 1, 2 }) is not compilable
Foo(new int[0])
Foo(new int[] { })
Foo({}) is not compilable
Enumerable.Repeat(String.Empty, count).ToArray()
Will create array of empty strings repeated 'count' times. In case you want to initialize array with same yet special default element value. Careful with reference types, all elements will refer same object.
In case you want to initialize a fixed array of pre-initialized equal (non-null or other than default) elements, use this:
var array = Enumerable.Repeat(string.Empty, 37).ToArray();
Also please take part in this discussion.
var contacts = new[]
{
new
{
Name = " Eugene Zabokritski",
PhoneNumbers = new[] { "206-555-0108", "425-555-0001" }
},
new
{
Name = " Hanying Feng",
PhoneNumbers = new[] { "650-555-0199" }
}
};
Example to create an array of a custom class
Below is the class definition.
public class DummyUser
{
public string email { get; set; }
public string language { get; set; }
}
This is how you can initialize the array:
private DummyUser[] arrDummyUser = new DummyUser[]
{
new DummyUser{
email = "abc.xyz#email.com",
language = "English"
},
new DummyUser{
email = "def#email.com",
language = "Spanish"
}
};
Just a note
The following arrays:
string[] array = new string[2];
string[] array2 = new string[] { "A", "B" };
string[] array3 = { "A" , "B" };
string[] array4 = new[] { "A", "B" };
Will be compiled to:
string[] array = new string[2];
string[] array2 = new string[] { "A", "B" };
string[] array3 = new string[] { "A", "B" };
string[] array4 = new string[] { "A", "B" };
Repeat without LINQ:
float[] floats = System.Array.ConvertAll(new float[16], v => 1.0f);
int[] array = new int[4];
array[0] = 10;
array[1] = 20;
array[2] = 30;
or
string[] week = new string[] {"Sunday","Monday","Tuesday"};
or
string[] array = { "Sunday" , "Monday" };
and in multi dimensional array
Dim i, j As Integer
Dim strArr(1, 2) As String
strArr(0, 0) = "First (0,0)"
strArr(0, 1) = "Second (0,1)"
strArr(1, 0) = "Third (1,0)"
strArr(1, 1) = "Fourth (1,1)"
For Class initialization:
var page1 = new Class1();
var page2 = new Class2();
var pages = new UIViewController[] { page1, page2 };
Another way of creating and initializing an array of objects. This is similar to the example which #Amol has posted above, except this one uses constructors. A dash of polymorphism sprinkled in, I couldn't resist.
IUser[] userArray = new IUser[]
{
new DummyUser("abc#cde.edu", "Gibberish"),
new SmartyUser("pga#lna.it", "Italian", "Engineer")
};
Classes for context:
interface IUser
{
string EMail { get; } // immutable, so get only an no set
string Language { get; }
}
public class DummyUser : IUser
{
public DummyUser(string email, string language)
{
m_email = email;
m_language = language;
}
private string m_email;
public string EMail
{
get { return m_email; }
}
private string m_language;
public string Language
{
get { return m_language; }
}
}
public class SmartyUser : IUser
{
public SmartyUser(string email, string language, string occupation)
{
m_email = email;
m_language = language;
m_occupation = occupation;
}
private string m_email;
public string EMail
{
get { return m_email; }
}
private string m_language;
public string Language
{
get { return m_language; }
}
private string m_occupation;
}
For the class below:
public class Page
{
private string data;
public Page()
{
}
public Page(string data)
{
this.Data = data;
}
public string Data
{
get
{
return this.data;
}
set
{
this.data = value;
}
}
}
you can initialize the array of above object as below.
Pages = new Page[] { new Page("a string") };
Hope this helps.
hi just to add another way:
from this page :
https://learn.microsoft.com/it-it/dotnet/api/system.linq.enumerable.range?view=netcore-3.1
you can use this form If you want to Generates a sequence of integral numbers within a specified range strat 0 to 9:
using System.Linq
.....
public int[] arrayName = Enumerable.Range(0, 9).ToArray();
You can also create dynamic arrays i.e. you can first ask the size of the array from the user before creating it.
Console.Write("Enter size of array");
int n = Convert.ToInt16(Console.ReadLine());
int[] dynamicSizedArray= new int[n]; // Here we have created an array of size n
Console.WriteLine("Input Elements");
for(int i=0;i<n;i++)
{
dynamicSizedArray[i] = Convert.ToInt32(Console.ReadLine());
}
Console.WriteLine("Elements of array are :");
foreach (int i in dynamicSizedArray)
{
Console.WriteLine(i);
}
Console.ReadKey();
Trivial solution with expressions. Note that with NewArrayInit you can create just one-dimensional array.
NewArrayExpression expr = Expression.NewArrayInit(typeof(int), new[] { Expression.Constant(2), Expression.Constant(3) });
int[] array = Expression.Lambda<Func<int[]>>(expr).Compile()(); // compile and call callback
To initialize an empty array, it should be Array.Empty<T>() in dotnet 5.0
For string
var items = Array.Empty<string>();
For number
var items = Array.Empty<int>();
Another way is by calling a static function (for a static object) or any function for instance objects. This can be used for member initialisation.
Now I've not tested all of this so I'll put what I've tested (static member and static function)
Class x {
private static Option[] options = GetOptionList();
private static Option[] GetOptionList() {
return (someSourceOfData).Select(dataitem => new Option()
{field=dataitem.value,field2=dataitem.othervalue});
}
}
What I'd love to know is if there is a way to bypass the function declaration. I know in this example it could be used directly, but assume the function is a little more complex and can't be reduced to a single expression.
I imagine something like the following (but it doesn't work)
Class x {
private static Option[] options = () => {
Lots of prep stuff here that means we can not just use the next line
return (someSourceOfData).Select(dataitem => new Option()
{field=dataitem.value,field2=dataitem.othervalue});
}
}
Basically a way of just declaring the function for the scope of filling the variable.
I'd love it if someone can show me how to do that.
For multi-dimensional array in C# declaration & assign values.
public class Program
{
static void Main()
{
char[][] charArr = new char[][] { new char[] { 'a', 'b' }, new char[] { 'c', 'd' } };
int[][] intArr = new int[][] { new int[] { 1, 2 }, new int[] { 3, 4 } };
}
}
I'm trying to build up a Data Matrix which comprises a list of objects. So here's what I am trying to do:
List<IBasePremium> BasePremiumMatrix = new List<IBasePremium>();
List<ICalcRate> calcRates = new List<ICalcRate>
{
new CalcRate { BasePremiumType = 1, Rate = basePremiumRate.Building, Calc = basePremiumRate.Building },
new CalcRate { BasePremiumType = 2, Rate = basePremiumProduct.Building,Calc = calculator.BasePremium(basePremiumProduct.Building,basePremiumRate.Building) }
// new CalcRate { BasePremiumType = 3, Rate = (decimal)postcodeMultiplier.BuildingsCore ,Calc = calculator.BasePremium(postcodeMultiplier.BuildingsCore, ) },
};
on my line of code that is commented out, as the second parameter I really want to pass the value of 'Calc' from the previous line of code. I've got a number of lines like this where I need to pass the previous 'Calc' value to build the matrix. The above is clearly the wrong approach and thought that I'd be able to write a method that takes the form something like :
public CalcRate Multiplier(Func<string,decimal>, int basePremiumType, decimal rate) {.....}
But I'm fighting witrh passing the method name and it's parameter values.
Create and Action or a Func :
Action customAction = ()=> yourFunctionName(param1, param2);
then pass it to the multiplier.
var calcul = Multiplier(customAction , ....);
How about a for loop?
List<IBasePremium> BasePremiumMatrix = new List<IBasePremium>();
List<ICalcRate> calcRates = new List<ICalcRate>();
for (int i = 1; i < max; i++) {
CalcRate rate = new CalcRate { BasePremiumType = i , Rate = basePremiumRate.Building };
if ( i > 1) {
rate.Calc = calcRates.get(i - 2)
} else {
rate.Calc = calculator.BasePremium(basePremiumProduct.Building,basePremiumRate.Building);
}
calcRates.add(rate);
}
I am making a (very basic) game. Therefore I need to store data for (a lot of) entities.
So I came up with this concept:
String[] Entity_Data = new String[EntityCount];
Entity_Data[0] = "1 12 98 45";//Or other numbers...
The first number could be something like hunger status or walking speed or even a X or Y coordinate.
Is there a way to give each variable in an array multiple values?
To the basic question of how to store multiple values in a single variable, use something like a List, Dictionary, or Tuple:
List<String> items = new List<String>() {
"one", "two", "three"
};
Dictionary<String, String> items = new Dictionary<String, String>() {
{"name 1", "value 1"},
{"name 2", "value 2"}
{"name 3", "value 3"}
};
var items = new Tuple<string, int, int>("Bad Guy", 100, 50);
That said, you're doing it wrong. Create a class and use fully qualified properties/attributes. Something like so:
public class Enemy {
private Int32 MaxHitPoints;
private Int32 CurrentHitPoints;
private Int32 Strength;
private Int32 Speed;
private List<Weapons>;
public Hit(Int32 power) {
CurrentHitPoints = CurrentHitPoints - power;
if (CurrentHitPoints <= 0) {
Die();
Explode();
MakeAMess();
}
}
}
Etc. ... Might be worth perusing/asking questions over at game-dev.SE.
You can use jagged arrays, like this:
string[][] jaggedArray = new string[3][];
jaggedArray[0] = new string[5];
jaggedArray[1] = new string[4];
jaggedArray[2] = new string[2]
Apart from the fact that I love your funky spelling of "coördinate", are you aware that a potential solution is hovering right in front of your eyes, waiting to be discovered?
What is Entity_Data, if not a variable that can hold more than one value? And what is it that you're looking for? Exactly the same thing! Meaning, you could declare Entity_Data as an array of arrays ("jagged array") of string:
var entityData = new string[3][];
entityData[0] = new string[] { "1", "2", "3" };
entityData[1] = new string[] { "a", "b" };
entityData[2] = new string[] { "I", "II", "III", "IV", "V" };
I am not suggesting that this is the best possible solution, but I thought it worth pointing out to you anyway.
You should change to Object-Oriented concept will be good. You can store any type of variable as attribute in class. If you want to get some data of attribut you should creating property to get or set attribute.
class Player
{
private string _name;
private int _hungerStatus;
private int _walkingSpeed;
private int _Xco;
private int _Yco;
// property
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
…
}
When you want to use it, you just e.g. X = player.Name or player.Name = "Hero";.
See more at http://www.dotnetperls.com/property.
What are all the array initialization syntaxes that are possible with C#?
These are the current declaration and initialization methods for a simple array.
string[] array = new string[2]; // creates array of length 2, default values
string[] array = new string[] { "A", "B" }; // creates populated array of length 2
string[] array = { "A" , "B" }; // creates populated array of length 2
string[] array = new[] { "A", "B" }; // created populated array of length 2
Note that other techniques of obtaining arrays exist, such as the Linq ToArray() extensions on IEnumerable<T>.
Also note that in the declarations above, the first two could replace the string[] on the left with var (C# 3+), as the information on the right is enough to infer the proper type. The third line must be written as displayed, as array initialization syntax alone is not enough to satisfy the compiler's demands. The fourth could also use inference. So if you're into the whole brevity thing, the above could be written as
var array = new string[2]; // creates array of length 2, default values
var array = new string[] { "A", "B" }; // creates populated array of length 2
string[] array = { "A" , "B" }; // creates populated array of length 2
var array = new[] { "A", "B" }; // created populated array of length 2
The array creation syntaxes in C# that are expressions are:
new int[3]
new int[3] { 10, 20, 30 }
new int[] { 10, 20, 30 }
new[] { 10, 20, 30 }
In the first one, the size may be any non-negative integral value and the array elements are initialized to the default values.
In the second one, the size must be a constant and the number of elements given must match. There must be an implicit conversion from the given elements to the given array element type.
In the third one, the elements must be implicitly convertible to the element type, and the size is determined from the number of elements given.
In the fourth one the type of the array element is inferred by computing the best type, if there is one, of all the given elements that have types. All the elements must be implicitly convertible to that type. The size is determined from the number of elements given. This syntax was introduced in C# 3.0.
There is also a syntax which may only be used in a declaration:
int[] x = { 10, 20, 30 };
The elements must be implicitly convertible to the element type. The size is determined from the number of elements given.
there isn't an all-in-one guide
I refer you to C# 4.0 specification, section 7.6.10.4 "Array Creation Expressions".
Non-empty arrays
var data0 = new int[3]
var data1 = new int[3] { 1, 2, 3 }
var data2 = new int[] { 1, 2, 3 }
var data3 = new[] { 1, 2, 3 }
var data4 = { 1, 2, 3 } is not compilable. Use int[] data5 = { 1, 2, 3 } instead.
Empty arrays
var data6 = new int[0]
var data7 = new int[] { }
var data8 = new [] { } and int[] data9 = new [] { } are not compilable.
var data10 = { } is not compilable. Use int[] data11 = { } instead.
As an argument of a method
Only expressions that can be assigned with the var keyword can be passed as arguments.
Foo(new int[2])
Foo(new int[2] { 1, 2 })
Foo(new int[] { 1, 2 })
Foo(new[] { 1, 2 })
Foo({ 1, 2 }) is not compilable
Foo(new int[0])
Foo(new int[] { })
Foo({}) is not compilable
Enumerable.Repeat(String.Empty, count).ToArray()
Will create array of empty strings repeated 'count' times. In case you want to initialize array with same yet special default element value. Careful with reference types, all elements will refer same object.
In case you want to initialize a fixed array of pre-initialized equal (non-null or other than default) elements, use this:
var array = Enumerable.Repeat(string.Empty, 37).ToArray();
Also please take part in this discussion.
var contacts = new[]
{
new
{
Name = " Eugene Zabokritski",
PhoneNumbers = new[] { "206-555-0108", "425-555-0001" }
},
new
{
Name = " Hanying Feng",
PhoneNumbers = new[] { "650-555-0199" }
}
};
Example to create an array of a custom class
Below is the class definition.
public class DummyUser
{
public string email { get; set; }
public string language { get; set; }
}
This is how you can initialize the array:
private DummyUser[] arrDummyUser = new DummyUser[]
{
new DummyUser{
email = "abc.xyz#email.com",
language = "English"
},
new DummyUser{
email = "def#email.com",
language = "Spanish"
}
};
Just a note
The following arrays:
string[] array = new string[2];
string[] array2 = new string[] { "A", "B" };
string[] array3 = { "A" , "B" };
string[] array4 = new[] { "A", "B" };
Will be compiled to:
string[] array = new string[2];
string[] array2 = new string[] { "A", "B" };
string[] array3 = new string[] { "A", "B" };
string[] array4 = new string[] { "A", "B" };
Repeat without LINQ:
float[] floats = System.Array.ConvertAll(new float[16], v => 1.0f);
int[] array = new int[4];
array[0] = 10;
array[1] = 20;
array[2] = 30;
or
string[] week = new string[] {"Sunday","Monday","Tuesday"};
or
string[] array = { "Sunday" , "Monday" };
and in multi dimensional array
Dim i, j As Integer
Dim strArr(1, 2) As String
strArr(0, 0) = "First (0,0)"
strArr(0, 1) = "Second (0,1)"
strArr(1, 0) = "Third (1,0)"
strArr(1, 1) = "Fourth (1,1)"
For Class initialization:
var page1 = new Class1();
var page2 = new Class2();
var pages = new UIViewController[] { page1, page2 };
Another way of creating and initializing an array of objects. This is similar to the example which #Amol has posted above, except this one uses constructors. A dash of polymorphism sprinkled in, I couldn't resist.
IUser[] userArray = new IUser[]
{
new DummyUser("abc#cde.edu", "Gibberish"),
new SmartyUser("pga#lna.it", "Italian", "Engineer")
};
Classes for context:
interface IUser
{
string EMail { get; } // immutable, so get only an no set
string Language { get; }
}
public class DummyUser : IUser
{
public DummyUser(string email, string language)
{
m_email = email;
m_language = language;
}
private string m_email;
public string EMail
{
get { return m_email; }
}
private string m_language;
public string Language
{
get { return m_language; }
}
}
public class SmartyUser : IUser
{
public SmartyUser(string email, string language, string occupation)
{
m_email = email;
m_language = language;
m_occupation = occupation;
}
private string m_email;
public string EMail
{
get { return m_email; }
}
private string m_language;
public string Language
{
get { return m_language; }
}
private string m_occupation;
}
For the class below:
public class Page
{
private string data;
public Page()
{
}
public Page(string data)
{
this.Data = data;
}
public string Data
{
get
{
return this.data;
}
set
{
this.data = value;
}
}
}
you can initialize the array of above object as below.
Pages = new Page[] { new Page("a string") };
Hope this helps.
hi just to add another way:
from this page :
https://learn.microsoft.com/it-it/dotnet/api/system.linq.enumerable.range?view=netcore-3.1
you can use this form If you want to Generates a sequence of integral numbers within a specified range strat 0 to 9:
using System.Linq
.....
public int[] arrayName = Enumerable.Range(0, 9).ToArray();
You can also create dynamic arrays i.e. you can first ask the size of the array from the user before creating it.
Console.Write("Enter size of array");
int n = Convert.ToInt16(Console.ReadLine());
int[] dynamicSizedArray= new int[n]; // Here we have created an array of size n
Console.WriteLine("Input Elements");
for(int i=0;i<n;i++)
{
dynamicSizedArray[i] = Convert.ToInt32(Console.ReadLine());
}
Console.WriteLine("Elements of array are :");
foreach (int i in dynamicSizedArray)
{
Console.WriteLine(i);
}
Console.ReadKey();
Trivial solution with expressions. Note that with NewArrayInit you can create just one-dimensional array.
NewArrayExpression expr = Expression.NewArrayInit(typeof(int), new[] { Expression.Constant(2), Expression.Constant(3) });
int[] array = Expression.Lambda<Func<int[]>>(expr).Compile()(); // compile and call callback
To initialize an empty array, it should be Array.Empty<T>() in dotnet 5.0
For string
var items = Array.Empty<string>();
For number
var items = Array.Empty<int>();
Another way is by calling a static function (for a static object) or any function for instance objects. This can be used for member initialisation.
Now I've not tested all of this so I'll put what I've tested (static member and static function)
Class x {
private static Option[] options = GetOptionList();
private static Option[] GetOptionList() {
return (someSourceOfData).Select(dataitem => new Option()
{field=dataitem.value,field2=dataitem.othervalue});
}
}
What I'd love to know is if there is a way to bypass the function declaration. I know in this example it could be used directly, but assume the function is a little more complex and can't be reduced to a single expression.
I imagine something like the following (but it doesn't work)
Class x {
private static Option[] options = () => {
Lots of prep stuff here that means we can not just use the next line
return (someSourceOfData).Select(dataitem => new Option()
{field=dataitem.value,field2=dataitem.othervalue});
}
}
Basically a way of just declaring the function for the scope of filling the variable.
I'd love it if someone can show me how to do that.
For multi-dimensional array in C# declaration & assign values.
public class Program
{
static void Main()
{
char[][] charArr = new char[][] { new char[] { 'a', 'b' }, new char[] { 'c', 'd' } };
int[][] intArr = new int[][] { new int[] { 1, 2 }, new int[] { 3, 4 } };
}
}