Use an integer to test a combination of enum values - c#

I have seen something like this in practice before, but I cannot find out what the name of this technique is called to be able to google it.
I want to achieve this:
public enum Directions
{
Top = 1,
Right = 2,
Bottom = 4,
Left = 8
}
And then generate a random combination of those directions:
int combinationOfDirections = Random.Range(1, 15);
.. so the minimum could be 1, and the max 15 (1 + 2 + 4 + 8).
What method could I use to test which combination of top, right, bottom and left were picked. Something like:
// 'includes' is just the English version of what I want to do
if(combinationOfDirections includes Directions.Bottom)
I'm sure it was something using a '|' or an '&'.. any help would be hot!
Thanks

You can do this to check if a direction was included:
public static bool isDirectionAvailable(Directions direction, int value)
{
return ((int)direction & value) != 0;
}

If you have a variable like that:
var dirs = (Directions)combinationsOfDirections;
You can check if a single directions is contained by using the HasFlag() method:
bool hasTop = dirs.HasFlag(Directions.Top);
To check if the values is exactly a specified combination, you can do:
bool isExactlyTopAndBottom = dirs == Directions.Top | Directions.Bottom;

Related

How to pick one random string from given strings?

How can I make a program that will pick one random string from given strings like this:
int x;
x = Random.Range(0,2);
string[] Quest0 = {"You","Are","How","Hello"};
string[] Quest1 = {"Hey","Hi","Why","Yes"};
string[] Quest2 = {"Here","Answer","One","Pick"};
I would like to print out like this:
if x = 2 it would print out Quest2 and so on.
Thank you!
List<String[]> quests = new ArrayList<String[]>();
quests.add(0, new string[]{"You","Are","How","Hello"});
quests.add(1, new string[]{"Hey","Hi","Why","Yes"});
quests.add(2, new string[]{"Here","Answer","One","Pick"});
int x = new Random().nextInt((2 - 0) + 1);
System.out.println(quests.get(x).toString());
Fistly you need to declare a random variable.
Random random = new Random();
this will create a variable in which you can now get random numbers from. to get random numbers you will use random.next(x,y) or in your case random.next(0,3) because the final argument is exclusive, so if you want 0, 1 or 2, you must use (0,3).
you then need to make some conditional statments, i would use If statments, to accomplish your goal use something like this:
if (x == 2)
{
foreach (string s in Quest2)
{
Console.WriteLine(s);
}
}
Do this for each possible outcome and it will print out all of the values in your array of strings. Hope I have been helpful, thanks.
Also if you new become familiar with these links:
http://msdn.microsoft.com/en-us/library/system.random%28v=vs.110%29.aspx
http://msdn.microsoft.com/en-gb/library/aa288453%28v=vs.71%29.aspx

How to stop enum from going out of bounds?

I'm still learning the ropes with C# programming. I am trying to write an application to solve Knight's Tour but have run into some grief when trying to get possible future positions for the knight.
For positions I am using a very simple struct:
public struct Position
{
public enum BoardRank { A = 1, B, C, D, E, F, G, H };
public BoardRank X;
public int Y;
}
In the knight class, my PossibleMoves() method begins like this:
public List<Position> PossibleMoves(Position position)
{
List<Position> positions = new List<Position>();
int[] multiply = new int[]{1, -1};
foreach (int times in multiply)
{
try{
Position possible = new Position();
possible.X = position.X + (Behaviour.X * times);
possible.Y = position.Y + (Behaviour.Y * times);
positions.Add(possible);
}
...
For position = A1 and times = -1, you can see how Behaviour.X could quickly fall out of bounds, but I assumed this would have been picked up by the try block.
I tried adding a {get; set;} on the enum declaration but that threw some useless syntax errors in VS2010.
Is there anything else I can try here to stop my enum from going out of bounds?
I assumed this would have been picked up by the try block.
Nope. Enums in C# are "named numbers" effectively. They're not a complete set of values for the type.
Is there anything else I can try here to stop my enum from going out of bounds?
You can use Enum.IsDefined to check whether a value exists in the original enum. I would personally stop using public fields, and instead make Position immutable - then validate the value in the constructor. You could also have methods such as WithX which returned a new value based on the current value with just X changing. While you've got public fields, you're never going to be able to trust that any particular value is valid though.
It may be useful to use modulo to keep the values within a specific range:
possible.X = (position.X + (Behaviour.X * times)) % ((int)BoardRank.H + 1);
This way I am not sure whether an enum is the best solution here, as we're working with integers anyway. The numbers must be a sequence with no gaps and you have to make sure you take the highest defined enum value plus one. Thus, if you add a I to your enum, you need to change the modul.
Here I have a very simple program to illustrate how it works:
enum Foo { A, B, C }
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i % ((int)Foo.C + 1));
}
}
As you see we take i modulo C + 1 which makes C's integer value the actual range maximum. This is the output:
0, 1, 2, 0, 1, 2, 0, 1, 2, 0

C#: Loop to find minima of function

I currently have this function:
public double Max(double[] x, double[] y)
{
//Get min and max of x array as integer
int xMin = Convert.ToInt32(x.Min());
int xMax = Convert.ToInt32(x.Max());
// Generate a list of x values for input to Lagrange
double i = 2;
double xOld = Lagrange(xMin,x,y);
double xNew = xMax;
do
{
xOld = xNew;
xNew = Lagrange(i,x,y);
i = i + 0.01;
} while (xOld > xNew);
return i;
}
This will find the minimum value on a curve with decreasing slope...however, given this curve, I need to find three minima.
How can I find the three minima and output them as an array or individual variables? This curve is just an example--it could be inverted--regardless, I need to find multiple variables. So once the first min is found it needs to know how to get over the point of inflection and find the next... :/
*The Lagrange function can be found here.** For all practical purposes, the Lagrange function will give me f(x) when I input x...visually, it means the curve supplied by wolfram alpha.
*The math-side of this conundrum can be found here.**
Possible solution?
Generate an array of input, say x[1,1.1,1.2,1.3,1.4...], get an array back from the Lagrange function. Then find the three lowest values of this function? Then get the keys corresponding to the values? How would I do this?
It's been a while since I've taken a numerical methods class, so bear with me. In short there are a number of ways to search for the root(s) of a function, and depending on what your your function is (continuous? differentiable?), you need to choose one that is appropriate.
For your problem, I'd probably start by trying to use Newton's Method to find the roots of the second degree Lagrange polynomial for your function. I haven't tested out this library, but there is a C# based numerical methods package on CodePlex that implements Newton's Method that is open source. If you wanted to dig through the code you could.
The majority of root finding methods have cousins in the broader CS topic of 'search'. If you want a really quick and dirty approach, or you have a very large search space, consider something like Simulated Annealing. Finding all of your minima isn't guaranteed but it's fast and easy to code.
Assuming you're just trying to "brute force" calculate this to a certain level of prcision, you need your algorithm to basically find any value where both neighbors are greater than the current value of your loop.
To simplify this, let's just say you have an array of numbers, and you want to find the indices of the three local minima. Here's a simple algorithm to do it:
public void Test()
{
var ys = new[] { 1, 2, 3, 4, 5, 4, 3, 2, 1, 2, 3, 4, 5, 4, 3, 4, 5, 4 };
var indices = GetMinIndices(ys);
}
public List<int> GetMinIndices(int[] ys)
{
var minIndices = new List<int>();
for (var index = 1; index < ys.Length; index++)
{
var currentY = ys[index];
var previousY = ys[index - 1];
if (index < ys.Length - 1)
{
var neytY = ys[index + 1];
if (previousY > currentY && neytY > currentY) // neighbors are greater
minIndices.Add(index); // add the index to the list
}
else // we're at the last index
{
if (previousY > currentY) // previous is greater
minIndices.Add(index);
}
}
return minIndices;
}
So, basically, you pass in your array of function results (ys) that you calculated for an array of inputs (xs) (not shown). What you get back from this function is the minimum indices. So, in this example, you get back 8, 14, and 17.

Extending enum with Flags, interfere the current use

The system have a plain enum like this,
public enum SomeEnum : short
{
Ok = 0,
Missing = 17,
};
This enum are now into a situation where I need to mask some more information into it without change the appearence of the existing enum values. The enum will got some new values,
[Flags]
public enum SomeEnum : short
{
Ok = 0,
Missing = 17,
Blocking = 18, // Values could be anything
Low = 19, // Values could be anything
};
I was afraid there could be problem to the current enum usage. It appears that I'm right, but I hope i'm proved wrong with your help. The usage until today are built around SomeEnum.Ok. Also tomorrow, but the Ok need additional info. I need to mask the enum values without affect it's current behavior, which could came from any common reference;
someEnumVariable.ToString()
(int)someEnumVariable
someVar = SomeEnum.Ok
Enum.Parse(typeOf(SomeEnum), someString)
If I flag the enum with
var test = (SomeEnum.Ok | SomeEnum.Blocking);
Both flags can be founded i.e. test.HasFlags(SomeEnum.Ok) or test.HasFlags(SomeEnum.Blocking) but the enum represents as SomeEnum.Blocking, which aren't possible.
Any ideas?
Because the value of SomeEnum.OK is 0, calling HasFlag(SomeEnum.OK) will always return true. When you mask enums together, the process relies on the fact that the sum of any combination of enum values will be unique. Typically you would set these up starting using values of 2^0, 2^1, 2^2, etc. For example:
[Flags]
public enum SomeEnum : short
{
Ok = 1,
Missing = 2,
Blocking = 4, // Values could be anything
Low = 8, // Values could be anything
}
If you want to mask the values together, you'll have to use the Flags attribute. If you can't refactor and change the value of SomeEnum.OK, then you may have to rely on passing in a SomeEnum[], rather than a single masked SomeEnum value.
EDIT
Just a quick note on masking the values together using the enum defined above. Take the following code:
var t1 = (int)(SomeEnum.OK | SomeEnum.Missing); //t1 = 1 + 2 = 3
var t2 = (int)(SomeEnum.Missing | SomeEnum.Blocking); //t2 = 2 + 4 = 6
var t3 = (int)(SomeEnum.OK | SomeEnum.Low); //t3 = 1 + 8 = 9
var t4 = (int)SomeEnum.OK; //t4 = 1
var s1 = (SomeEnum.Ok).ToString(); //s1 = "Ok"
var s2 = (SomeEnum.Ok | SomeEnum.Missing).ToString(); //s2 = "Ok, Missing"
When these items are OR'ed together, .NET just adds the values together to produce a new, unique value that represents the combination of the OR'ed items. Using enum values that are powers of 2 ensures that the combinations will always be unique.
http://msdn.microsoft.com/en-us/library/system.flagsattribute.aspx
I think a quick introduction to binary OR is in order.
| doesn't just let you sneak two integers into one variable. It performs a mathematical operation.
Therefore, any value other than 0 OR'ed with 0 will return that value itself.
You will probably encounter further unexpected behavior if you supply flag values that are not a single bit, such as 1, 2, 4, 8, 16.
EDIT
If you want to build a Flags enum around the existing values, you can do that. Don't use the currently reserved bits 10001 (17) for any other value, and be careful when testing for Ok.
Here's an example of how to accomplish this using a bitflag. This will however likely force you to change your existing flag comparisons.
[FlagsAttribute]
enum tester
{
alpha = 1,
beta = 2,
gamma = 4,
reggy=3
}
class Program
{
static void Main(string[] args)
{
tester t = tester.alpha | tester.beta;
if (t == tester.alpha)
Console.WriteLine("alpha only");
if ((t & tester.alpha) != 0)
Console.WriteLine("alpha");
if ((t & tester.beta) != 0)
Console.WriteLine("beta");
if ((t & tester.gamma) != 0)
Console.WriteLine("gamma");
if (t == (tester.beta | tester.alpha))
Console.WriteLine("alphabeta");
//this will produce alpha, beta, alphabeta

Enum index by Value

[FlagsAttribute]
public enum Colors { Red = 1, Green = 2, Blue = 4, Yellow = 8 };
I have an enum as show. I want the ability to get say Colors.Blue is at index 2, index staring from 0.I want to get the index number passing in Colors.Whatever? Can someone post me some snippets...
Try this one:
int index = Array.IndexOf(Enum.GetValues(typeof(Colors )), Colors.Green);
Assuming that each color uses a single bit as value, you can just locate the index of that bit.
public int GetIndex(Colors color) {
int value = (int)colors;
int index = 0;
while (value > 0) {
value >>= 1;
index++;
}
return index;
}
Note that the index of bits is normally zero based, but here you get a one based index.
If you want a zero based index, you would get the index two for blue, not three as you stated in the question. Just start with index = -1; if that is the result that you desire.
Can't really understand your question, but is this what you mean:
var blue = (Colors)Enum.GetValues(typeof(Colors))[2];
I don't know why you need it , but one way to do that is
Colors c = (Colors)Enum.Parse(typeof(Colors), Enum.GetNames(typeof(Colors))[index]);
This is the easiest solution I found. Works fine with flags w/o bothering with bytes operations.
Array eVals = Enum.GetValues(typeof(MyEnum));
MyEnum eVal = (MyEnum)eVals.GetValue(iIndex);
I got this working after doing it like this:
return (Status)Enum.GetValues(typeof(Status)).GetValue(this.EvaluationStatusId);
I am using the following code, and it is working:
int index=(int)Enum.Parse(typeof(Colors), "Green");

Categories