increase chances of even number - actionscript-3

If I am getting a random number, how do I increase my chances of making that random number to be even. I am not looking to make it even every time. I am just looking to generate a random number say... %70 of the time or %90 of the time.
private function randNum (high, low) {
return Math.floor(Math.random() * (1+high-low)) + low;
}
Would I pass in a greater range of numbers to this function? Or would I have to scrap this function altogether?
Thank you

private function randNum (high : Number, low : Number) : int
{
var even : Boolean = Math.random() < 0.7; //set probability of even number here
var rand : int = Math.floor(Math.random() * (1+high-low)) + low;
if (even)
while (rand % 2 != 0)
rand = Math.floor(Math.random() * (1+high-low)) + low;
else
while (rand % 2 != 1)
rand = Math.floor(Math.random() * (1+high-low)) + low;
return rand;
}
Test:
var even : int = 0;
var odd : int = 0;
for (var i : int = 0; i < 100000; i++)
{
var a : int = randNum(1, 20);
if (a % 2 == 0)
even++;
else
odd++;
}
trace(even, odd);
Output:
[trace] 69869 30131

A little too late ;) but another one with no loop and using bit masking operation :
ret & -2 will make your number even, then depending on the result of (Math.random() >= evenProbability) you set the lower bit to be 1 to give an odd number
function randomRange(low:int, high:int, evenProbability:Number = 0.5):int{
var ret:int = int( Math.random() * ( 1 + high - low ) ) + low
return ( ret & -2 ) | int( Math.random() >= evenProbability )
}
Here a live test with wonderfl : http://wonderfl.net/c/9IHx

Related

Button generating a cross sum

I'm looking for a tip for a AS3 script, have no idea how to start there
Button, if clicked the function is executed, which outputs a predefined value as the cross sum of a number string.
Example:
Cross sum should be 10
By clicking on the button, the function generates the number 55 or 82 or 37 or 523, ie numbers with the cross sum 10
An alternative way using % (modulo) instead of a string. You could write that into one line like this:
while (sum != 0) { qsum += sum % 10; sum /= 10; }
The trick is that modulo will give us only the last digit of the longer number, then we divide by 10 to trim off that last number (from longer) and we re-read a newer ending digit of the long number.
Example:
Long num = 1234, so each trim gives, 4 then 3 then 2 then 1 and we'll sum them up each time.
usage:
myInt = cross_sum(50); //makes myInt hold answer result of function (where ExpectedValue input is 50).
and the supporting function...
function cross_sum( ExpectedValue: int ) : int
{
var rand :int = Math.floor(Math.random() * 100000000000)
var sum :int = Math.abs( rand );
var qsum :int = 0;
while (sum != 0)
{
qsum += sum % 10; //get last digit of sum...
sum /= 10; //trim down sum by 1 digit...
}
if ( qsum == ExpectedValue ) { return rand; } //# stop here and give back "rand" as answer result.
else { cross_sum( expectedValue ); } //# else if wrong, try again...
}
Got it now.....
the function calculates a number, with the crosssum 50
function berechnen() {
var rand = Math.floor(Math.random() * 100000000000)
var sum = String(rand)
var qsum = 0;
for (var i = 0; i < sum.length; i++) {
qsum += Number(sum.charAt(i));
}
if (qsum == 50) {
summe.text = String(sum);
} else {
berechnen()
}
}

Detect frequencies in a buffer along the time

if I record a series of frequencies beeps into a buffer, for example:
15kHz for 50ms, 17k for 50 ms and goes on, is there any way to "go" along the time plain and to decode this freqs(with goertzel or something)?
Hey, this is an update, I've added a code that shows how I find the first delimiter in the sound buffer that I check. If I record 5 seconds of a buffer(I record into a stream buffer and not a file) The first snippet takes something like 30 seconds to analyze the index where the start delimiter starts at. I thinks it is very newbie...must find a better solution. thanks
(every delimiter is 0.2 seconds duration) and it's like that - Start delimiter = 12KHz, 1's = 13k, 0's = 14k, End delimiter = 15k
double max_power = 0;
int max_power_index = 0;
double DelimiterSamplesCount = SampleRate * DelimiterTime;
float[] samples32array = samples32.ToArray();
//Searching For Delimiter
for (int i = 0; i < (samples32array.Length); i++) //Delimiter Samples Length = SampleRate*DelimiterTimeLength,( i.e: 44100*0.2=8820 samples)
{
if ((i + (int)DelimiterSamplesCount - 1) > samples32array.Length) break;
double power = Goertzel.GoertzelFilter(samples32array, StartDelimiterFreq, i, i + (int)DelimiterSamplesCount - 1);
if(power > max_power)
{
max_power = power;
max_power_index = i;
}
}
My Goertzel is like that:
public static double GoertzelFilter(float[] samples, double freq, int start, int end)
{
double sPrev = 0.0;
double sPrev2 = 0.0;
int i;
double normalizedfreq = freq / 44100;
double coeff = 2 * Math.Cos(2 * Math.PI * normalizedfreq);
for (i = start; i < end; i++)
{
double s = samples[i] + coeff * sPrev - sPrev2;
sPrev2 = sPrev;
sPrev = s;
}
double power = sPrev2 * sPrev2 + sPrev * sPrev - coeff * sPrev * sPrev2;
return power;
}
If you know the set of frequencies and the durations, then a set of sliding Goertzel filters is a good start to building a simple demodulator. Comparing and scanning for for a peak difference between these filters is a better decision criteria than just checking for a certain magnitude output.

AS3-Flash cs6 How to make numbers have a comma?

I am making a game that when you click on the Monster your score gets +1. But when your score goes over 1000 I would like it like this 1,000 rather than 1000. I am not sure how to do this as I have not learnt much action script. I have embed number and punctuation into the font. Here is my code so far:
var score:Number = 0;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
Monster.addEventListener(TouchEvent.TOUCH_TAP, fl_TapHandler);
function fl_TapHandler(event:TouchEvent):void
{
score = score + 1;
Taps_txt.text = (score).toString();
}
Help will greatly appreciated.
You can do like that:
function affScore(n:Number, d:int):String {
return n.toFixed(d).replace(/(\d)(?=(\d{3})+\b)/g,'$1,');
}
trace(affScore(12345678, 0)); // 12,345,678
This may not be the most elegant approach, but I wrote a function that will return the string formatted with commas;
public function formatNum(str:String):String {
var strArray:Array = str.split("");
if (strArray.length >= 4) {
var count:uint = 0;
for (var i:uint = strArray.length; i > 0; i--) {
if (count == 3) {
strArray.splice(i, 0, ",");
count = 0;
}
count++;
}
return strArray.join("");
}
else {
return str;
}
}
I tested it on some pretty large numbers, and it seems to work just fine. There's no upper limit on the size of the number, so;
trace (formatNum("10000000000000000000"));
Will output:
10,000,000,000,000,000,000
So in your example, you could use it thusly;
Taps_txt.text = formatNum(String(score));
(This is casting the type implicitly rather than explicitly using toString();, but either method is fine. Casting just looks a little neater in function calls)
Use the NumberFormatter class:
import flash.globalization.NumberFormatter;
var nf:NumberFormatter = new NumberFormatter("en_US");
var numberString:String = nf.formatNumber(1234567.89);
trace("Formatted Number:" + numberString);
// Formatted Number:1,234,567.89
To show the score with comma, you can do like this : ( comments are inside the code )
var score:Number = 0;
var score_str:String;
var score_str_len:int;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
Monster.addEventListener(TouchEvent.TOUCH_TAP, fl_TapHandler);
function fl_TapHandler(event:TouchEvent):void
{
score = score + 1;
score_str = score.toString();
score_str_len = score_str.length;
// here you can use score > 999 instead of score_str_len > 3
Taps_txt.text =
score_str_len > 3
// example : 1780
// score_str_len = 4
// score_str.substr(0, 4 - 3) = 1 : get thousands
// score_str.substr(4 - 3) = 780 : get the rest of our number : hundreds, tens and units
// => 1 + ',' + 780 = 1,780 : concatenate thousands + comma + (hundreds, tens and units)
? score_str.substr(0, score_str_len-3) + ',' + score_str.substr(score_str_len-3)
: score_str
;
// gives :
// score == 300 => 300
// score == 1285 => 1,285
// score == 87903 => 87,903
}
EDIT :
To support numbers greater than 999.999, you can do like this :
function fl_TapHandler(event:MouseEvent):void
{
score = score + 1;
score_str = score.toString();
Taps_txt.text = add_commas(score_str);
}
function add_commas(nb_str:String):String {
var tmp_str:String = '';
nb_str = nb_str.split('').reverse().join('');
for(var i = 0; i < nb_str.length; i++){
if(i > 0 && i % 3 == 0) tmp_str += ',';
tmp_str += nb_str.charAt(i);
}
return tmp_str.split('').reverse().join('');
/*
gives :
1234 => 1,234
12345 => 12,345
123456 => 123,456
1234567 => 1,234,567
12345678 => 12,345,678
123456789 => 123,456,789
1234567890 => 1,234,567,890
*/
}
Hope that can help you.

How do I generate a visually distinct, non-random color from a single input number?

In Flash AS3, how would I write a function that will:
Take in an integer (a list index, for example)
return a visually distinct hex color based on that number (and will consistently return that same color given that same number)
The purpose is to provide a visually distinct color for each item in varying-length list of items. The most I expect to support is around 200, but I don't see the count going far above 20 or so for most.
Here's my quick and dirty:
public static function GetAColor(idx:int):uint {
var baseColors:Array = [0xff0000, 0x00ff00, 0xff0080, 0x0000ff, 0xff00ff, 0x00ffff, 0xff8000];
return Math.round(baseColors[idx % baseColors.length] / (idx + 1) * 2);
}
It does OK, but it would be nice to see a more distinct set of colors that are not so visually close to one another
You could go with generator of random values that supports seed, so you will be able return same color. As for color you could build it - by randomValue * 0xFFFFFF, where randomValue between 0 and 1. And exclude values (colors) that are close.
Second option: build palette of 200 colors with step - 0xFFFFFF / 200 and shuffle palette with predefined logic, so you will have same colors.
Third option: as for really distinct colors, you could go with big jumps in every channel. Example: 0xFF * 0.2 - 5 steps in every channel.
Fourth option: go with HSV. It's easy to understand(watch image, rotate hue from 0 to 360, change saturation and value from 0 to 100) how to manipulate parameters to get distinct color:
//Very simple demo, where I'm only rotating Hue
var step:uint = 15;
var position:uint = 0;
var colors:Array = [];
for (; position < 360; position += step) {
colors.push(HSVtoRGB(position, 100, 100));
}
//Visualisation for demo
var i:uint, len:uint = colors.length, size:uint = 40, shape:Shape, posX:uint, posY:uint;
for (i; i < len; ++i) {
shape = new Shape();
shape.graphics.beginFill(colors[i]);
shape.graphics.drawRect(0, 0, size, size);
addChild(shape);
shape.x = posX;
shape.y = posY;
posX += size;
if (posX + size >= stage.stageWidth) {
posX = 0;
posY += size;
}
}
public function HSVtoRGB(h:Number, s:Number, v:Number):uint {
var r:Number = 0;
var g:Number = 0;
var b:Number = 0;
var tempS:Number = s / 100;
var tempV:Number = v / 100;
var hi:int = Math.floor(h / 60) % 6;
var f:Number = h / 60 - Math.floor(h / 60);
var p:Number = (tempV * (1 - tempS));
var q:Number = (tempV * (1 - f * tempS));
var t:Number = (tempV * (1 - (1 - f) * tempS));
switch (hi) {
case 0:
r = tempV;
g = t;
b = p;
break;
case 1:
r = q;
g = tempV;
b = p;
break;
case 2:
r = p;
g = tempV;
b = t;
break;
case 3:
r = p;
g = q;
b = tempV;
break;
case 4:
r = t;
g = p;
b = tempV;
break;
case 5:
r = tempV;
g = p;
b = q;
break;
}
return (Math.round(r * 255) << 16 | Math.round(g * 255) << 8 | Math.round(b * 255));
}
And last one, if you want go with this task like a pro, this wiki article could be helpful for you.

Actionscript: Pseudo-Random Number creation with seeds

I am creating a function that returns a Perlin Noise Number in Flash.
For this function I must have a function that returns a random number from a static seed. Unfortunately the default Math.random in Actionscript can't do this..
I searched for a long time on the internet and I couldn't find a solution that fits my perlin-noise function.
I tried the following codes:
public static var seed:int = 602366;
public static function intNoise(x:int, y:int):Number {
var n:Number = seed * 16127 + (x + y * 57);
n = n % 602366;
seed = n | 0;
if (seed <= 0) seed = 1;
return (seed * 0.00000166) * 2 - 1;
}
This function does create a Random number, but the seed changes all the time so this doesn't work with perlin noise.
public static function intNoise(x:int, y:int):Number {
var n:Number = x + y * 57;
n = (n<<13) ^ n;
return ( 1 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
}
I got this function from the Perlin Noise tutorial I followed: Perlin Noise, but it only seems to return 1.
How can I create a function that always returns the same Pseudo-Random number when called with the same seed?
I looked at the random number generator mentioned in the link and it looks like this:
function IntNoise(32-bit integer: x)
x = (x<<13) ^ x;
return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 7fffffff) / 1073741824.0);
end IntNoise function
I translated it thus:
package
{
import flash.display.*;
public class Main extends Sprite {
private var seeds:Array =
[ -1000, -999, -998, 7, 11, 13, 17, 999, 1000, 1001 ];
public function Main() {
for ( var i:int = 0; i < 10; i++ )
trace( intNoise( seeds[ i ] ) );
// Outputs: 1, 0, 0, -0.595146656036377, -0.1810436248779297,
// 0.8304634094238281, -0.9540863037109375, 0, 0, 1
}
// returns floating point numbers between -1.0 and 1.0
// returns 1 when x <= -1000 || x >= 1001 because b becomes 0
// otherwise performs nicely
public function
intNoise( x:Number ):Number {
x = ( uint( x << 13 ) ) ^ x;
var a:Number = ( x * x * x * 15731 + x * 789221 );
var b:Number = a & 0x7fffffff;
return 1.0 - b / 1073741824.0;
}
}
}