Randomized File (Stream) From List of Checkboxes - c#

So this is a two part question. Moving question #2 to the top since #1 has been answered.
Question #2 - What would be an ideal method to use checkboxes from the initial instance of Form1 (that is sadly unnamed) to set what objects are allowed. I was thinking perhaps I could have a hidden form that holds variables, and use a set accessor called from Form1 on change to the checkboxes and updates the list or dictionary I call in my above mentioned function?
The first is, I have multiple images - two currently but more to come - and want to randomly use one of those each time the function is called. Currently I'm doing this:
System.IO.Stream file;
Random rnd = new Random(int.Parse(Guid.NewGuid().ToString().Substring(0, 8), System.Globalization.NumberStyles.HexNumber));
int a = rnd.Next(0, 2);
if (a == 0) {file = thisExe.GetManifestResourceStream("QATestFileGenTools.checkFront1.bmp");}
else if (a == 1) {file = thisExe.GetManifestResourceStream("QATestFileGenTools.checkFront2.bmp");}
else {file = thisExe.GetManifestResourceStream("QATestFileGenTools.checkFront2.bmp");}
The plan was the final else was to use that image as default in the future. As seen, each image will be a resource embedded in the executable. I'd like to clean this up, possibly using a dictionary or list, where I randomly get a number between 0 and list.size-1 and then set the file equal to that.
Question #1 - How can I make a list or dictionary of resource pointers and then set file to be that resource that time?
Now, currently I cannot use my checkboxes. I have two checkboxes on Form1 to reflect each of the two current images. Since there's no way to call Form1.cbImage1.Checked because the initial instance has no name/identifier, I was considering setting a global variable, which I am loathe to do. I tried setting a get accessor, but of course that runs into the same issue.
Thanks in advance!

For question #1:
var dict = new Dictionary<int, string>();
dict.Add(0, "QATestFileGenTools.checkFront1.bmp");
dict.Add(1,"QATestFileGenTools.checkFront2.bmp");
dict.Add(2, "QATestFileGenTools.checkFront2.bmp");
Random rnd = new Random(DateTime.Now.Millisecond);
int randomInt = rnd.Next(0, 2);
string resourceName = dict[randomInt];
System.IO.Stream file file = thisExe.GetManifestResourceStream(resourceName);
Edit: changed the random seed to something simpler and probably equally effective.

In the end, for question #2, I am creating a dictionary of objects (configuration data) along with calls to various worker classes. This might be clumsy, but it's allowing me to send various data in a single variable, arrays, integers, booleans and strings. So long as the code is commented well, it's easy enough to typecast them on the other side.

Related

Randomize list with seed

I'm looking for a way to randomize a List using a seed. What I want to achieve by this is controlled randomization. In other words to make sure that a list is always randomized in the same order if I use the same seed to do it.
I'm currently using this code:
string arbitrarySeed = "someValue";
System.Random random = new System.Random(BitConverter.ToInt32(Encoding.ASCII.GetBytes(arbitrarySeed), 0));
List<object> randomizedOptions = items?.OrderBy(o => random.Next()).ToList();
Which seems a bit overcomplicated so I'm looking for a more elegant way to handle this.
I know that randomizing is this way is not actually very random, but I don't need it to be true randomness. Something that comes close will do fine.
Depending on how "consistent" you need the generated series to be, you could use string.GetHashCode:
string arbitrarySeed = "someValue";
System.Random random = new System.Random(arbitrarySeed.GetHashCode());
List<object> randomizedOptions = items?.OrderBy(o => random.Next()).ToList();
GetHashCode is not guaranteed to be consistent across .NET versions or implementations (e.g. Linux, Windows, macOS) but if you need localized consistency it may work for you.
Also note that BitConverter.ToInt32 will only take 4 bytes of the array you pass in, so "someValue" and "someValue2" would give you the same seed value.

The output is differ when debugging vs Step Into solution

I have a very strange problem that I never been in touch with in my entire life.
This is what I been up to:
I have programmed a game that involves you going to throw two dices and the sum of the two dices should be seven for you to win.
This is how the interface is built:
The textbox1 shows the value of first thrown dice.
The textbox2 shows the value of second thrown dice.
The textbox3 shows the sum of the both dices.
The button1 throws the dices.
This is the problem:
When i Debugg (F5) the application in Visual Studio 2013 Ultimate
the textboxes gets the exactly same value all the time. This is wrong, it shouldn't act like this.
When i Step Into (F11) the application/code the textboxes gets
different values, just as it should be, this is right, this is how the program should act.
Is there anyone that can help with this problem, i think that I have just missed a very small but a obvious thing that I have missed but I really can't find anything, I'm actually out of ideas!
Attachments
Here is all the files, I hope it will help you, the program is written in Swedish but I don't think that makes any problem, if it do, I can translate the whole solution to English.
The whole Solution: Throw_Dices.zip
The Code: Big picture on three screens of the code
From MSDN:
different Random objects that are created in close succession by a
call to the default constructor will have identical default seed
values and, therefore, will produce identical sets of random numbers
In your Kasta.cs, create a static instance of Random instead of multiple ones.
public class Tarning
{
private static Random ran = new Random();
int slump;
public int Kasta()
{
//Random ran = new Random();
slump = ran.Next(1, 6);
return slump;
}
}
Another possibility would be to create a seed manually. For instance like
public int Kasta()
{
byte[] seed = new byte[4];
new RNGCryptoServiceProvider().GetBytes(seed);
int seedInt = BitConverter.ToInt32(seed, 0);
Random ran = new Random(seedInt);
slump = ran.Next(1, 6);
return slump;
}
Instead of creating two Dice (Tarning ?)
Create one and roll it twice.
Or create both on start up, Or perhaps have a class that holds 2 dice.
and throw them again.
You should also google random and seeding, what's happening is from the same seed value, you get the same sequence of random numbers. Debugging is introducing enough of a delay between the new Random calls, that the seed (based on the clock) has changed between the two calls.
PS your button1Click handler
should set the three textbox values, not trigger textbox changed events which then set them. Imagine if you wanted to reuse your code, you'd have to create a UI to do it.
A better way would be to have a class that held two (or n) dice with a Roll method and a property that returned the result. Then you could reuse it without worrying about when and how.

Arrays getting changed inside irrelevant object

For my end of year project I need to develop an image processing and artificial intelligence application.
My image processing is already done, so I'm moving to the AI. However I have a problem here.
I will try to describe the situation here.
For a correct image processing I need an AI that can validate the board through the rules of checkers. So I need to check the current state of the play field with the last known state.
So for this I created an object with the currentBoard 2 dimensional array, and a method that validates the raw input of the board with the currentBoard (= last known state).
However, when another object -- my image processing object -- is finished with his method, it will change the array currentBoard in my AI object.
This is the same for a new array I created inside the main form. I think this happens cause of the heap/stack.
I hope I made my problem clear and understandable. I know I'm not the best in describing situations so please tell me when you don't understand a part completely.
Arrays are reference types, so, as you've found, changing the array contents in one place will change it for any other code which holds a reference to the same object.
To avoid changing the array, you should take a deep copy of your 2 dimensional array and work with the copy instead. Note that we have to take a deep copy of both the array and its internal arrays:
int[][] original = {new[] {1,2,3}, new[] {4,5,6}};
int[][] deepCopy = new int[original.Length][];
for (int index = 0; index < original.Length; index++)
{
var row = original[index];
int[] rowCopy = new int[row.Length];
row.CopyTo(rowCopy, 0);
deepCopy[index] = rowCopy;
}
You can also produce the same result using some simple linq:
int[][] deepCopyLinq = original.Select(x => x.ToArray()).ToArray();

What collection could I use when arrays may seem out of the question? Does the data need to be immutable and can I have a position?

Not long ago I posted a question about a design decision of my F1 game. One person replying noted my use of Dictionary<int, Driver> and asked what it was for. I use this collection for having a finish position and a Driver at that finish position. He suggested I should use arrays, because arrays have a index that could be used as position.
Having not worked on the game for a while, I picked up where I left and started to think about replacing my Dictionaries with arrays. I started googling arrays and one thing let to another and I came across posts here on SO, some blogs (http://blogs.msdn.com/b/ericlippert/archive/2008/09/22/arrays-considered-somewhat-harmful.aspx) about not to use arrays (or, actually, in some very specific cases).
My questions are these:
When data comes from the database, and is only used for comparing and looking up data, what is best used? I have a
prediction, which contains drivers and a predicted finish position
result, which also contains drivers and a finish position
points, which contains the points for every correctly guessed Driver at a certain finish position
The data comes from the database, and shouldn't be edited, added to, or removed.
The data is only used by my code only, but does that mean that I can safely use a collection, or should I really be on the safe side anyway and make sure that what comes back from the database is an immutable collection?
And the second question has to do with the positions. What collection can I use so that I can have finish positions, without maybe the overhead of using a Dictionary?
var prediction = new Driver[3];
prediction[0] = new Driver(10, "Michael Schumacher");
prediction[1] = new Driver(7, "Felipe Massa");
prediction[2] = new Driver(8, "Jensen Button");
var results = new Driver[3];
results[0] = new Driver(10, "Michael Schumacher");
results[1] = new Driver(8, "Jensen Button");
results[2] = new Driver(9, "Fernando Alonso");
int[] points = { 25, 18, 15, 12, 10 };
for (int i = 0; i < prediction.Length; i++)
{
if (prediction[i].Equals(results[i]))
{
result += points[i];
}
}
It depends on if you want to check by position (e.g. "Who finished third?") or by driver (e.g. "What position did Wilson finish at?"). It also depends on whether you care that much about performance in a scenario which sounds like it won't really make a difference to your application as a whole.
Generally a dictionary would be good for lookups. However, if the range of the keys is known, small, and continuous ("race position" fits all three criteria) then a dictionary does not offer anything more than an array (and has more overhead). So if you want to query by position, use an array because it's the simplest tool that fits the job description.
If you want to query by driver, then first you have to answer the question "how exactly is the identity of a Driver defined?" (an answer might be "each driver is uniquely identified by their last name, first name and date of birth").
You could then make the Driver class implement IEquatable<Driver> using these criteria and put it in a Dictionary<Driver, Positions> where I am using the class below to avoid multiple dictionaries.
class Positions
{
public int Predicted { get; set; }
public int Actual { get; set; }
}
However, you have to ask yourself if going to all this trouble makes any sense vs. having an array of e.g. Tuple<Driver, Positions> and looping over the array to find the driver you want each time. This may sound inefficient in theory, but if you have just 20 drivers it will actually be much faster than a dictionary.
Finally, I don't see any need in going out of your way to mark these data structures as immutable and/or enforce immutability. Since your application works in read-only mode, and it does not include code that attempts to push data back to the database, I think it's pretty clear that it's meaningless to go around modifying the data in code.
I use this collection for having a finish position and a Driver at
that finish position. He suggested I should use arrays, because arrays
have a index that could be used as position.
And for that case, he's pretty much right. An array is really the best way to do that because you know how many positions there are and the index acts as the position. It's going to use the least memory and get the most performance, and it's simple. I mean you could also use a List, which for this purpose is really just a fancier array.
There might be cases where arrays are "harmful", but there's also a case to be made that you should stick to simple tools when that's all you need to do the job. Arrays are simple, easily understood, and fast. When all you need is a Driver and a finish position, an Array is a perfect tool.
When data comes from the database, and is only used for comparing and
looking up data, what is best used? I have a
prediction, which contains drivers and a predicted finish position result, which also contains drivers and a finish position points,
which contains the points for every correctly guessed Driver at a
certain finish position
That depends. Do you want one collection that stores all of that information? If you do, Jon's suggestion of a Dictionary is probably your best bet. I suspect that's going to be a good way to go because it's got everything you need in a single place that you can work with.
If instead you want a different collection for each one, then for results and predicted results you can just use an Array for each one (as the data is perfectly suited for it). For points it's a bit different because the points aren't likely to be a perfectly set of index values and you could have two results with the same score.

Designing a custom Random class

I know C# has the Random class and probably a few classes in LINQ to do this, but if I was to write my own code to randomly select an item from a collection without using any built in .NET objects, how would this be done?
I can't seem to nail the logic required for this - how would I tell the system when to stop an iteration and select the current value - at random?
EDIT: This is a hypothetical question. This is not related to a production coding matter. I am just curious.
Selecting a random element from a collection can be done as follows.
Random r = new Random();
int randomIndex = r.Next(0, myCollection.Size -1);
var randomCollectionItem = myCollection[randomIndex];
Unless you have a VERY good reason, writing your own random generator is not necessary.
My advice to you is DON'T DO IT. Whatever reason you think you may have for not wanting to use the built-in library, I am pretty sure you misunderstood something. Please go back to the drawing board.
All of the advice above is technically accurate, but is kind of like giving a chemistry textbook to someone who wants to refine his own oil to use in his car.
There are many pseudo-random number generators. They aren't truly random, but they come at different quality, distinguished by their statistical and sequential properties and what purpose they are applicable for.
It very much depends on "how random you need it". If it just needs to "look random to a human", simple generators look like that:
rnd = seed; // some starting value
rnd = (a * rnd + b) % c; // next value
...
For well chosen values of a, b, and cthese generators are ok for simple statistical tests. A detailed discussion and common values for these you find here.
One interesting approach is to collect as much "external" data as possible - like time between keypresses, mouse movements, duration of disk reads etc. -, and use an algorithm that accumulates randomness while discarding dependency. That is mathematically tricky though (IIRC not long ago a critical attack surfaced based on one of these not being as random as thought).
Only a very few special applications use a truly random external hardware source - anything between a open-imput amplifier and radioactive decay.
You need to use a seed, something semi random provided by the computer itself.
Maybe use very fine resolution time and use the last couple microseconds when the method is called. That should be random enough to generate anything from 00 to 99, you can then go from there.
It sounds like your problem isn't in calculating a random number, but in how to use that random number to select an item from a list. Assuming you can create a random number somehow, all you need to do is use it as the argument to the list's indexer.
int index = customRandomGenerator.Next();
var selection = items[index];
Assuming that your presupposition about having to iterate through the list is correct (or the collection doesn't have an indexer) then you could do:
int index = customRandomGenerator.Next();
Item selection = null;
for (int i = 0; i < items.Length; i++)
{
if (i == index)
{
selection = items[i];
break;
}
}
The only true "cryptographically strong" random number generator in the .Net Framework is in System.Cryptography.RandomNumberGenerator - run this through Reflector to see what is does? Looking at your problem you would need a to know the Count of the collection otherwise you may never retrieve an item - you would need to specify a start and end value to draw random numbers from - the Random class would work best - pop it through Reflector.
Well, I never thought about implementing that myself as it seems like reinventing the wheel but you may have a look on this wikipedia article, hope it helps you do what you want
Random Number Generator

Categories

Resources