I have a very long code set up, and I know there should be an easier way, but I can't seem to find it. I want the enemies to increase speed every level by .5. How can I do this?
function makeEnemies():void
{
var chance:Number = Math.floor(Math.random() * 150);
if (chance <= + level)
{
tempEnemy = new Enemy();
tempEnemy.speed = 2
//Math.random(); gets a random number from 0.0-1.0
tempEnemy.x = Math.round(Math.random() * 1000);
addChild(tempEnemy);
enemies.push(tempEnemy);
if (level == 2)
{
tempEnemy.speed = 3
}
if (level == 3)
tempEnemy.speed = 4
}
}
}
You can try something like:
var enemyBaseSpeed:int = 2;
var speedLevelInc:Number = 0.5;
then later:
tempEnemy.speed = enemyBaseSpeed + ((level - 1) * speedLevelInc);
(Though you sample code shows the speed increasing by 1 per level)
I've been making a "slideshow" where 4 images are animated in random order.
To prevent multiple animations to one image for example 3 times successively, I've write a little logic.
My problem : after a few times all the 4 images are animated (after the query 'array' is cleared the second time I think), the timer goes crazy and trace() random numbers in a high sequence rate without to animate the images, with would look creepy I think.
My code :
var myTimer:Timer = new Timer(2500);
myTimer.addEventListener(TimerEvent.TIMER, animate);
myTimer.start();
var array:Array = new Array();
var lastNum:int;
function animate(e:TimerEvent):void {
var num:int = getRandomNumber( 1, 4 );
trace( num );
if( array.indexOf( num ) < 0 && num != lastNum ) {
myTimer.delay = 2500;
if( num == 1 ) {
sideImg_start_1.play(); // comment this*
} else if( num == 2 ) {
sideImg_start_2.play(); // comment this*
} else if( num == 3 ) {
sideImg_start_3.play(); // comment this*
} else if( num == 4 ) {
sideImg_start_4.play(); // comment this*
}
array.push( num );
if( array.length == 4 ) {
array.splice(0, 4);
trace(" array cleared - " + array.length);
lastNum = num;
}
} else {
myTimer.delay = 100; // I've also tryed so make a higher delay
// like 500 but its the same problem...
}
}
function getRandomNumber( min:int, max:int ):int {
return Math.floor( Math.random() * ( 1 + max - min ) ) + min;
}
stop();
So guys, thanks for all your answers and your help :D
UPDATE:
First I've tried to simply call the 'animate()' function instead of defining a higher speed to the timer to call the next number fast, without to loose time, which would make the random animation look weird.
I've used animate(null); instead of myTimer.delay = 100; before, but then I was getting a STACKOVERFLOW error :P
For example if your lastNum is equal to 4, and you have 1,2 and 3 as new values, than you will end up with an infinite loop,
because you can't insert 4 (because it's equal to the lastNum) and you can't insert 1,2 or 3 because they are already in the array.
What you need to do is:
if (array.length == 4) {
array.splice(0, 4);
lastNum = num;
} else {
lastNum = 0; //<-- HERE
}
I need to generate 238 numbers, with a range of 1-4, but I want to weight them, so there's say 35% chance of getting 3, 28% chance of getting 2, 18% chance of getting 4m, and 19% chance of getting 1.
I found this..
def select( values ):
variate = random.random() * sum( values.values() )
cumulative = 0.0
for item, weight in values.items():
cumulative += weight
if variate < cumulative: return item
return item # Shouldn't get here, but just in case of rounding... print select( { "a": 70, "b": 20, "c": 10 } )
But I don't see how to convert that to AS3?
I would do something like this:
var values:Array = [1,2,3,4];
var weights:Array = [35, 28, 18, 19];
var total:Number = 0;
for(var i in weights) {
total += weights[i];
}
var rndNum:Number = Math.floor(Math.random()*total);
var counter:Number = 0;
for(var j:Number = 0; j<weights.length; j++) {
counter += weights[j];
if( rndNum <= counter ) return values[j]; //This is the value
}
(untested code, but the idea should work)
Take a look at this article:
http://uihacker.blogspot.com/2009/09/actionscript-3-choose-random-item-from.html
You can also use Rnd.bit() to get a weighted 1 or 0 and adapt it to your situation.
Here for you:
/**
* random due to weighted values
*
* #param {{}} spec such as {'a':0.999, 'b':0.001}
* #return {*} return the key in object
*/
public static function weightedRand(spec:Object):* {
var i:String, j:int, table:Array = [];
for (i in spec) {
// from: https://stackoverflow.com/questions/8435183/generate-a-weighted-random-number
// The constant 10 below should be computed based on the
// weights in the spec for a correct and optimal table size.
// E.g. the spec {0:0.999, 1:0.001} will break this impl.
for (j=0; j<spec[i]*10; j++) {
table.push(i);
}
}
return table[Math.floor(Math.random() * table.length)];
}
Then you could test with this code:
public static function main():void {
// test calculate weighted rand
// random weighted
var result:Array = [];
for (var k:int = 0; k < 100; k++) {
var rand012:String = MyUtil.weightedRand({'y': 0.8, 'n1': 0.1, 'n2': 0.1});
result.push(rand012); // random in distribution...
}
logger.traceObject('result: ', result);
// counts
var counts:Object = {};
var totalCounts:int = 0;
for (var i:int = 0; i < result.length; i++) {
counts[result[i]] = 1 + (counts[result[i]] || 0);
totalCounts++;
}
logger.traceObject('counts: ', counts);
// ratios
var ratios:Object = {};
for (var c:String in counts) {
ratios[c] = counts[c] / totalCounts;
}
logger.traceObject('ratios: ', ratios);
}
Yet another installment of the weekly code-bowling game as the previous incarnation is over a week old and fairly well explored by now. As a refresher:
Code-Bowling is a challenge for
writing the most obscure, unoptimized,
horrific and bastardized code
possible. Basically, the exact
opposite of Code-Golf.
The Challenge:
Create a program that takes a sequence of numbers, and determines if they are in an ascending order.
Example:
$ ./myprogram 1 2 7 10 14
true
$ ./myprogram 7 2 0 1
false
Rules:
There really are none. It can be a console application, it can be a webpage, it can be whatever. It just needs to be a stand-alone program that accepts numbers and returns numbers. The format and methods are 100% up to you.
So have fun, and let's see the bastardized solutions you can come up with!
This uses something I call "Parent Sort". For list greater than size 1, you have to ask Mom or Dad about each pair of numbers. It's interesting because there's a chance that Mom might have you go ask Dad, and there's a bigger chance that Dad will have you go ask Mom. Could run forever assuming infinite stack capabilities.
function askMom($num1, $num2) {
$chance = mt_rand(0,2);
if ($chance>1) {
return askDad($num1, $num2);
} else {
return $num1 <= $num2;
}
}
function askDad($num1, $num2) {
$chance = mt_rand(0,4);
if ($chance>1) {
return askMom($num1, $num2);
} else {
return $num1 <= $num2;
}
}
function parentSort(array $numbers) {
for ($i = 0; $i < count($numbers)-1; $i++) {
$chance = mt_rand(0,1);
if ($chance) {
if (askMom($numbers[$i], $numbers[$i+1])) {
} else {
return false;
}
} else {
if (askDad($numbers[$i], $numbers[$i+1])) {
} else {
return false;
}
}
}
return true;
}
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv){
int a, b;
if (argc > 2){
sscanf(argv[1], "%d", &a);
sscanf(argv[2], "%d", &b);
if (a<=b)
return main(argc-1, argv+1);
printf("false");
exit(0);
};
printf("true");
return 0;
};
This solution has worst-case performance O(n!) and works by generating all possible permutations of the list, and then calculating a number (see the function 'value') that has it's minimum for sequential lists (ascending or descending).
def value(list):
sum = 0
for i in range(len(list)-1):
sum = sum + (list[i]-list[i+1])**2.0
return sum
def drop(lst, i):
if i + 1 >= len(lst):
return lst[:i]
else:
return lst[:i] + lst[i+1:]
class list_permute:
def __init__(self, lst):
self.lst = lst
self.i = -1
self.subiter = None
def __iter__(self):
return self
def next(self):
if len(self.lst) == 1:
if self.i == -1:
self.i = self.i + 1
return self.lst
else:
raise StopIteration()
if self.subiter != None:
try:
return [self.lst[self.i]] + self.subiter.next()
except StopIteration:
self.subiter = None
if self.subiter == None:
self.i = self.i + 1
if self.i >= len(self.lst):
raise StopIteration()
else:
self.subiter = list_permute(drop(self.lst, self.i))
return self.next()
def test(list):
given = value(list)
for i in list_permute(list):
if value(i) < given:
return False
# Test for false positive
if list[0] > list[len(list)-1]:
return False
return True
list = []
print "Feed me your numbers (end with ^C)"
try:
while True:
try:
list.append(int(raw_input()))
except ValueError:
print "NaN"
except (KeyboardInterrupt, EOFError):
pass
print test(list)
Here's a quick one. Interestingly, it should still be pretty efficient, since it only iterates over the terms once. It can only work on numbers between 0 and 255...
array_shift($argv);
$str = str_repeat(chr(0), 256);
foreach ($argv as $key => $element) {
$str[(int) $element] = chr($key + 1);
}
$str = str_replace(chr(0), '', $str);
$hex = unpack('H*', $str);
for ($i = 1; $i < strlen($str); $i++) {
if (substr($hex[1], $i * 2 - 2, 2) != dechex($a)) {
echo "False\n";
die();
}
}
echo "True\n";
It works by inverting the string (1 2 5 4 becomes 1 2 0 4 3, in other words, the number in the sequence becomes the key in the result, and the position in the sequence becomes the value. Then all we need to check is that 1 is in position 1.
And along the same lines (same theory, just set-theory operations):
array_shift($argv);
$vals = array_flip($argv);
ksort($vals);
echo array_values($vals) == range(0, count($vals) - 1) ? "True\n" : "False\n";
This solution isn't unoptimised, but it is obscure, horrific, and bastardised...
/* Either #define macros FIRST, SECOND, THIRD, etc. here, or do so on the
* command line when "compiling" i.e.
* $ gcc -D FIRST=1 -D SECOND=5 -D THIRD=42
*/
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
#define pairsorted(X, Y) (min((X), (Y)) == (X) ? 1 : 0)
#if defined (FIRST) && defined (SECOND) && pairsorted(FIRST, SECOND)
#if defined (THIRD) && pairsorted(SECOND, THIRD)
#if defined (FOURTH) && pairsorted (THIRD, FOURTH)
#if defined (FIFTH) && pairsorted (FOURTH, FIFTH)
#error "Sorted!"
#elif !defined (FIFTH)
#error "Sorted!"
#else /* FIFTH is defined and < FOURTH */
#error "Not sorted!"
#endif /* FIFTH */
#elif !defined (FOURTH)
#error "Sorted!"
#else /* FOURTH is defined and < THIRD */
#error "Not sorted!"
#endif /* FOURTH */
#elif !defined (THIRD)
#error "Sorted!"
#else /* THIRD is defined and < SECOND */
#error "Not sorted!"
#endif /* THIRD */
#elif !defined (SECOND)
#error "Sorted!"
#else /* SECOND is defined and < FIRST */
#error "Not sorted!"
#endif /* SECOND */
#ifndef SECOND
#error "I need at least two values to compare"
#endif
This (ab)uses the C compiler as it's runtime environment, or can be invoked with the following shell script for prettier output (relies on the above being in sortedcpp.c):
#!/bin/bash
ORDINALS=(ZEROTH FIRST SECOND THIRD FOURTH FIFTH)
VALUES=(0 $#)
for i in 1 2 3 4 5; do
if [ $i -le $# ]
then
flags="$flags -D ${ORDINALS[$i]}=${VALUES[$i]}"
fi
done
output=`gcc $flags sortedcpp.c 2>&1`
echo $output | sed -e 's/sortedcpp.c:[0-9]*: error: #error \"\(.*\)\"/\1/'
First time I used dynamic programing to make things worse
It has time and space complexity of O(n²)
#include <stdio.h>
int main (int argc, char **argv)
{
int is_ordered[1000][1000];
int list[1000];
int i,j;
for(i = 1; i < argc; i++)
sscanf(argv[i],"%d", &list[i-1]);
for (i = 0; i < argc -2; i++)
{
if (list[i] < list[i+1])
is_ordered[i][i+1] = 1;
else
is_ordered[i][i+1] = 0;
}
for (i = 2; i < argc -1; i++)
for (j = 0; j < (argc - 1 - i); j++)
{
if (is_ordered[j+1][i+j] && is_ordered[j][i+j-1])
is_ordered[j][j+i] = 1;
else
is_ordered[j][j+i] = 0;
}
if(is_ordered[0][argc-2])
printf("True\n");
else
printf("False\n");
return 0;
}
Yay, Python!
def IsSorted(lst):
return sorted(lst) == lst
Following is a php function for masking a string. Can somebody give me the actionscript equalent for this function.
public static function simple_encrypt($input) {
$return = array();
for($i = 0; $i < strlen($input); $i++){
$ascii = ord(substr($input, $i, 1)) * 2;
$return[] = base_convert($ascii, 10, 32);
}
return sprintf('RL%s', implode('', $return) ); // "RL" ensures it starts with a letter
}
public static function simple_encrypt(input:String):String {
var ret = [];
var ascii:Number;
for(var i:Number = 0; i < input.length; i++) {
ascii = input.charCodeAt(i) * 2;
ret.push(ascii.toString(32));
}
//I don't speak php, so I am assuming that
//RL doesn't have any syntactical meaning with sprintf
return "RL" + ret.join(''); //joins everything to a single string.
}