Stupid stupid question but here we are..
so, I want to generate some random events in an iOS application (in my case a game). I have written a function "verifyEvents" that I call each time I load a particular view (game scene).
To associate a probability to an event I assigned a value to each event (e.g. kill player: 0.05, give extra bonus 0.08).
In the function I generate a random number using CCRANDOM_0_1(), an iOS macro based on the random() function defined in stdlib.h. If the number is less than the assigned value I trigger the event (below there is the code).
#define CCRANDOM_0_1() ((random() / (float)0x7fffffff ))
Is this the best approach or do you use something else in your apps?
-(void) verifyEvents
{
float value = CCRANDOM_0_1() ;
float eventPValue = 0.05f;
if(value<eventPValue){
CCLOG(#"EVENT!");
}
}
Ok, following the suggestion of #lukya I asked the question on gamedev and did some more research. By far I got two answer which seem quiet interesting (which should be read together with the comments on my question).
EDIT: Forgot to put the link here as well (was only in the comment):
https://gamedev.stackexchange.com/questions/33236/simulating-probability
Related
Apologies, in trying to be concise and clear my previous description of my question turned into a special case of the general case I'm trying to solve.
New Description
I'm trying to Compare the last emitted value of an Aggregation Function (Let's say Sum()) with a each element that I aggregate over in the current window.
Worth noting, that the ideal (I think) solution would include
The T2(from t-1) element used at time = t is the one that was created during the previous window.
I've been playing with several ideas/experiments but I'm struggling to find a way to accomplish this in a way is elegant and "empathetic" to Beam's compute model (which I'm still trying to fully Grock after many an article/blog/doc and book :)
Side inputs seem unwieldy because It looks like I have to shift the emitted 5M#T-1 Aggregation's timestamp into the 5M#T's window in order to align it with the current 5M window
In attempting this with side inputs (as I understand them), I ended up with some nasty code that was quite "circularly referential", but not in an elegant recursive way :)
Any help in the right direction would be much appreciated.
Edit:
Modified diagram and improved description to more clearly show:
the intent of using emitted T2(from t-1) to calculate T2 at t
that the desired T2(from t-1) used to calculate T2 is the one with the correct key
Instead of modifying the timestamp of records that are materialized so that they appear in the current window, you should supply a window mapping fn which just maps the current window on to the past one.
You'll want to create a custom WindowFn which implements the window mapping behavior that you want paying special attention to overriding the getDefaultWindowMappingFn function.
Your pipeline would be like:
PCollection<T> mySource = /* data */
PCollectionView<SumT> view = mySource
.apply(Window.into(myCustomWindowFnWithNewWindowMappingFn))
.apply(Combine.globally(myCombiner).asSingletonView());
mySource.apply(ParDo.of(/* DoFn that consumes side input */).withSideInputs(view));
Pay special attention to the default value the combiner will produce since this will be the default value when the view has had no data emitted to it.
Also, the easiest way to write your own custom window function is to copy an existing one.
Here is the code that I thought and tried. I thought that it was the right way to buy and sell for the Fractals signals. But getting buy and sell signals simultaneously.
double UP[],DOWN[];
double fractal_output = iFractals(_Symbol,_Period);
ArraySetAsSeries(UP,true);
ArraySetAsSeries(DOWN,true);
CopyBuffer(fractal_output,0,0,5,UP);
CopyBuffer(fractal_output,1,0,5,DOWN);
if (UP[1])
{
Comment("BUY");
trade.Buy(0.1);
}
if (DOWN[1])
{
Comment("SELL");
trade.Sell(0.1);
}
I don't understand how I can plan to buy and sell using the iFractals function indicator in my MQL5. What improvements need to be done?
A double fractal_output should be int not double and initialized in the OnInit(){...} just once, not each tick.
Make sure you understand which fractal is obtained when accessing UP[1] - it seems to be 0,1,2,3,4 (left to right), so you are asking for fractal 3 bars before the current Bar.
Alternatively you can get a value before the current Bar (most probably it is zero until next bar after current starts).
Make sure that you have copied the buffer correctly (it is possible that it is not copied and UP[1] may throw out-of-range error - for that reason CopyBuffer returns a number of elements actually copied (so if CopyBuffer()!=5){print();return;})
What do you expect to see when calling if(UP[1]){} ?
A buffer might take both positive values and EMPTY_VALUE (== 2^31-1).
It is better to check the value of the buffer: if(UP[i]>0){} or if(UP[i]!=EMPTY_VALUE){...}
Do not forget about a special case, when some candle has both an upper and a lower fractal - What to do in that corner-case?
It will open a Long and then open a Short (so it may close the Buy by opening a Short).
Probably you need check the open orders before that or open bar - otherwise you'll have many positions opened during one candle.
Tester will help you find other problems that you could miss when planning the EA.
I'm a novice programmer (the only reason I say this is because I'm not super familiar with all the terms yet) and I'm trying to make walls generate in respect to the wall before it. I've posted a question about it on here before
Randomly generated tunnel walls that don't jump around from one to the next
and sort of got the answer. What I was mainly looking for was the for loop that was used (I think). Th problem is I didn't know how to implement it properly without getting errors.
My problem ended up being "I couldn't figure out how to inc. this in to it. I have 41 walls altogether that i'm using and the walls are named Left1 and Right1. i had something like this
CGFloat Left1 = 14; for( int i = 0; i < 41; i++ ){
CGFloat offset = (CGFloat)arc4random_uniform(2*100) - 100;
Left1 += offset;
Right1 = Left1 + 100;
but it was telling me as a yellow text that Local declaration of "Left1" hides instance variable and then in a red text it says "Assigning to 'UIImageView *__strong' from incompatible type 'float'. i'm not sure how to fix this"
and I wasn't sure how to fix it. I realize (I think) that arc4random and arc4random_uniform are pretty much the same thing, as far as i know, with slight differences, but not the difference i'm looking for.
As I said before, i'm pretty novice so any example would really be helpful, especially with the variables i'm trying to use. Thank you.
You want a "hashing" function, and preferably a "cryptographic" one because they tend to be significantly higher quality - at the expense of requiring additional CPU resources. But on modern hardware the extra CPU power usually isn't a problem.
The basic idea is you can give any data to the function, and it will spit out a completely random result, but always the same result if you provide the same input.
Have a read up on them here:
http://en.wikipedia.org/wiki/Hash_function
http://en.wikipedia.org/wiki/Cryptographic_hash_function
There are hundreds of different algorithms in common use, which is best will depend on what you need.
Personally I recommend sha256. A quick search of "sha256 ios" here on stack overflow will show you how to make one, with the CommonCrypto library. The gist is you should create an NSString or NSData object that contains every offset, then run the entire thing through sha256. The result will be a perfectly random 256 bit number.
If 256 bits is too much, just cut it up. For example you could grab just the first 16 bits of the number, and you will have a perfectly random 16 bit number.
This question already has answers here:
What kind of logarithm functions / methods are available in objective-c / cocoa-touch?
(3 answers)
Closed 9 years ago.
I am building a game using Sprite Kit and I want to gradually increase the difficulty (starting at 1.0) based on the time since starting the game.
Someone suggested that I should use a logarithmic calculation for this but I'm unsure how to implement this in Objective-C.
- (float)difficulty
{
timeSinceStart = ???; // I don't what kind of object this should be to make it play nice w/ `log`
return log(???);
}
Update #1
I know that I need to use the log method but I'm uncertain what values I need to pass to it.
Objective C is a superset of the C language, therefore you can use "math.h".
The function that computes the natural logarithm from "math.h" is double log(double x);
EDIT
Since you want the difficulty to increase as a function of time, you would pass the time as the argument to log(double x). How you would use that to calculate and change the "difficulty" is an entirely different question.
If you want to change the shape of the curve, either multiply the expression by a constant, as in 2*log(x) or multiply the parameter by a constant, as in log(2*x). You will have to look at the individual curves to see what will work best for your specific application.
Since log(1.0) == 0 you probably want to do some scaling and translation. Use something like 1.0 + log(1.0 + c * time). At time zero this will give a difficulty of 1.0, and as time advances the difficulty will increase at a progressively slower pace whose rate is determined by c. Small values such as c = 0.01 will give a slow ramp-up, larger values will ramp-up faster.
#pjs gave a pretty clear answer. As to how to figure out the time: You probably want the amount of time spent actually playing, rather than elapsed time since launching the game.
So you will nee to track total time played, game after game.
I suggest you create an entry in NSUserDefaults. You can save and load double values to user defaults using the NSUserDefaults methods setDouble:forKey: and doubleForKey:
I would create an instance variable startPlayingTime, type double
When you start the game action running, capture the start time using
startPlayingTime = [NSDate timeIntervalSinceReferenceDate];
When the user passes the game/exits to the background, use
NSTimeInterval currentPlayTime = [NSDate timeIntervalSinceReferenceDate] - startPlayingTime;
Then read the total time played from user defaults, add currentPlayTime to it, and save it back to user defaults.
You can then make your game difficulty based on
difficulty = log(1+ c * totalPlayTime);
(as explained by pjs, above) and pick some appropriate value for C.
This question already has answers here:
How dangerous is it to compare floating point values?
(12 answers)
Error subtracting floating point numbers when passing through 0.0
(4 answers)
Closed 9 years ago.
I tested this on a empty project and does not happen.
As you can see the newValue becomes 2.98023e-08 when I subtract the bossPercentage value.
This happens only when bossPercentage is 0.2f and the previous value is 0.2f.
The difference should be 0.0f but I don't understand why I get 2.98023e-08 instead.
For reference, remainingBossPercentage is a property in [GameController] class defined as following:
//header
#property (readwrite, nonatomic) float remainingBossPercentage;
//.m
#synthetize remainingBossPercentage;
//init
remainingBossPercentage=1.0f;
I'd like to ask you inisght on what I may be doing that causes this error.
EDIT: I subtract 0.2f to remainingBossPercentage (for each boss enemy) and everything works fine until I reach the last enemy object that has again 0.2f and I get to the crucial point of doing 0.2f - 0.2f (screenshot below)
EDIT 2: I am greatful for all comments and answers, also the closing votes. What induced me to ask this question is the fact that newValue is 2.98023e-08. I now see that there are also comparison issues (thanks to the extremely useful QA linked by the people that voted to close the answer). What I wonder is.. why in my new test project with only 2 test variables this does not happen? (I created a HelloWorld project that substracts two floats).
I am asking this because, as one of the user suggests, is important to understand floating points without taking shourtcuts. YES, I am taking a shortcut by asking this question because I don't have time tonight to study it properly but I would like to try understanding and learning at the best I can. I will read the answers properly and dedicate my time to understand but if in the meanwhile I can I would like to add a doubt:
could it be that for memory management reasons the two projects (the test one and my actual game) beheave differently? Could the different beheaviour of the two projects somehow linked with memory being swapped in dirty areas? (e.g. the game having bigger memory usage gets swapped more and hence there may be a loss of precision?)
PS: I found out a question with exactly the same 2.98023e-08 value. What I still wonder is why this doesn't happen in the same test project (I am doing some more testing now).
Simply, floating point numbers should not be expected to be completely accurate.
Floating point numbers (as used in our usual computers) are natively in base 2, out usual number is base 10. Not all numbers in one number base can be expressed with full accuracy in another number base.
As an empale 1/3 can not be expressed with complete accurate in the base 10 number system (0.333333...) but can be in the base 3 number system.
The upshot, one needs to compare floating point numbers with a specified error range. Take the absolute value of the difference and compare that to the allowable range.
Because of this financial amounts are generally not (should not be) expressed as floating point numbers. This give rise to classes such as NSDecimalNumber.