Category Archives: arrays

Random Walk to Target

Actionscript:
  1. var target:Number = 360;
  2. var steps:Array = new Array();
  3. for (var step:Number = 0; step <target; step += int(Math.random() * 36 + 36)){
  4.     steps.push(Math.min(target,step));
  5. }
  6. steps.push(target);
  7. trace(steps);
  8. /* outputs something similar to:
  9. 0,46,99,144,189,259,330,360
  10. */

This is something I've had to do a few times recently.... it randomly steps a number toward a given target...

Also posted in misc | Tagged , | Leave a comment

Unique Array Comparison

Actionscript:
  1. function uniqueCompare(arr:Array, compare:Function):void {
  2.     var leng:int = arr.length;
  3.     for (var i:int = 0; i<leng; i++){
  4.         for (var j:int = i + 1; j<leng; j++){
  5.             compare(arr[i], arr[j]);
  6.         }
  7.     }
  8. }
  9.  
  10. var numbers:Array = [1, 2, 3, 4, 5];
  11.  
  12. uniqueCompare(numbers, compareCallback);
  13.  
  14. function compareCallback(a:*, b:*):void {
  15.     trace("compare " + a + " to " + b);
  16. }
  17.  
  18. /*
  19. outputs:
  20. compare 1 to 2
  21. compare 1 to 3
  22. compare 1 to 4
  23. compare 1 to 5
  24. compare 2 to 3
  25. compare 2 to 4
  26. compare 2 to 5
  27. compare 3 to 4
  28. compare 3 to 5
  29. compare 4 to 5
  30. */

This snippet shows a function called uniqueCompare() that compares all elements in an array to all other elements in an array without repeating a comparison.

Also posted in misc | Tagged , | Leave a comment

Random Sort

Actionscript:
  1. function randomize(a:*, b:*):int{
  2.        return Math.round(Math.random()*8) - 4;
  3. }
  4.  
  5. var i:int;
  6. var fruits:Array;
  7.  
  8. trace("Math.random()");
  9. for (i = 0; i<4; i++){
  10.   // reset fruits array:
  11.   fruits = ["apple", "grape","pear","cherry"];
  12.   fruits.sort(randomize);
  13.   trace(fruits);
  14. }
  15.  
  16.  
  17. // seeds
  18. var s1:Number= 0xFF00FF;
  19. var s2:Number = 0xCCCCCC;
  20. var s3:Number= 0xFF00F0;
  21.  
  22. function tRandomize(a:*, b:*):int{
  23.        return Math.round(rand()*8) - 4;
  24. }
  25.  
  26. trace("\nTausworthe rand()");
  27. for (i= 0; i<4; i++){
  28.   fruits = ["apple", "grape","pear","cherry"];
  29.   fruits.sort(tRandomize);
  30.   trace(fruits);
  31. }
  32. // from www.ams.org/mcom/1996-65-213/S0025-5718-96-00696-5/S0025-5718-96-00696-5.pdf
  33. function rand():Number {
  34.     s1=((s1&4294967294)<<12)^(((s1<<13)^s1)>>19);
  35.     s2=((s2&4294967288)<<4)^(((s2<<2)^s2)>>25);
  36.     s3=((s3&4294967280)<<17)^(((s3<<3)^s3)>>11);
  37.     var r:Number = (s1^s2^s3) * 2.3283064365e-10;
  38.     r = (r<0) ? r+=1 : r;
  39.     return r;
  40. }
  41.  
  42. /*
  43. outputs:
  44. Math.random()
  45. grape,apple,pear,cherry
  46. pear,cherry,apple,grape
  47. grape,apple,pear,cherry
  48. grape,apple,cherry,pear
  49.  
  50. Tausworthe rand()
  51. apple,grape,pear,cherry
  52. cherry,grape,pear,apple
  53. grape,apple,cherry,pear
  54. grape,pear,apple,cherry
  55. */

The above shows how to randomly sort or shuffle an array. This is useful in games. To achieve this I made use of the compareFunction argument of Array.sort(). Most sorting algorithms go through the array and compare values until the desired sort order is achieved. The compareFunction argument is a function that takes two values a and b and returns an integer that is negative positive or zero... see this info from the docs:
* A negative return value specifies that A appears before B in the sorted sequence.
* A return value of 0 specifies that A and B have the same sort order.
* A positive return value specifies that A appears after B in the sorted sequence.

So in the case of a randomizing an array you simply need to return a random int -1, 0 or 1. This is what I've done in the past (Math.round()*2) -1) ... but when I was writing this snippet it seemed like 0 caused less variation in the output of the array so I made the range from -4 to 4 instead. This could have just been my imagination, but it seems like having less chance of a zero caused the arrays to be a bit more shuffled.

The reason I also included a version that uses Tausworthe is because of the easy seeding. In some cases you may want to use seeded randomness to sort an array.

UPDATE:
Was digging around about this and found a much faster method for randomizing arrays... not a big deal if you have small arrays, but if you need to randomize 1000's of values this method is much faster than using Array.sort()

Also posted in misc | Tagged , | Leave a comment

Not a Snippet (wandering robots)

Actionscript:
  1. package {
  2.     import flash.display.Sprite;
  3.    
  4.     [SWF(width=500, height=500, backgroundColor=0xEFEFEF, frameRate=30)]
  5.     public class Main extends Sprite{
  6.         private var _robotManager:RobotManager;
  7.         public function Main(){
  8.           _robotManager = new RobotManager(this, 12);
  9.         }
  10.     }
  11. }
  12.  
  13. class RobotManager{
  14.    
  15.     private var _robots:Array;
  16.     private var _top:Sprite;
  17.     private var _robotNum:int;
  18.    
  19.     public function RobotManager(top:Sprite, robotNum:int){
  20.         _top = top;
  21.         _robotNum = robotNum;
  22.         _robots = new Array();
  23.         setupRobots();
  24.         top.addEventListener(Event.ENTER_FRAME, onRun);
  25.     }
  26.    
  27.     private function setupRobots():void{
  28.         for (var i:int = 0; i<_robotNum; i++){
  29.             _robots[i] = new Robot();
  30.             _robots[i].x = 100+(i % 3) * 150;
  31.             _robots[i].y = 100+int(i / 3) * 100;
  32.             _robots[i].addEventListener("death", onRobotDie);
  33.             _top.addChild(_robots[i]);
  34.         }
  35.     }
  36.     private function onRobotDie(evt:Event):void{
  37.         for (var i:int = 0; i<_robotNum; i++){
  38.             if (_robots[i] == evt.currentTarget){
  39.                 _robots.splice(i, 1);
  40.             }
  41.         }
  42.         _robotNum--;
  43.     }
  44.    
  45.     private function onRun(evt:Event):void{
  46.         collisions();
  47.     }
  48.    
  49.     private function collisions():void{
  50.         var currBot:Robot;
  51.         for (var i:int = 0; i<_robotNum; i++){
  52.             currBot = _robots[i];
  53.             for (var j:int = 0; j<_robotNum; j++){
  54.                 if (currBot != _robots[j]){
  55.                     var dx:Number = currBot.x - _robots[j].x;
  56.                     var dy:Number = currBot.y - _robots[j].y;
  57.                     if (Math.sqrt((dx * dx) + (dy * dy)) <40){
  58.                         currBot.die();
  59.                     }
  60.                 }
  61.             }
  62.         }
  63.     }
  64. }
  65.  
  66. import flash.display.*
  67. import flash.events.*;
  68.  
  69. class Robot extends Sprite{
  70.     private var _inc:Number
  71.     private var _td:Number;
  72.     private var _theta:Number;
  73.     private var _rad:Number;
  74.    
  75.     public function Robot(){
  76.         _theta = Math.random() * (Math.PI * 2);
  77.         _td = _theta;
  78.         _inc = Math.random() * .2 + .05;
  79.         _rad = _inc * 10;
  80.         with(graphics){
  81.             beginFill(0x666666);
  82.             drawRect(-10,-10,20,20);
  83.             endFill();
  84.             beginFill(0x333333);
  85.             drawRect(-5, -5, 20, 10);
  86.             lineStyle(0,0xAAAAAA);
  87.             endFill();
  88.             drawCircle(0,0,20);
  89.         }
  90.         addEventListener(Event.ENTER_FRAME, onRun);
  91.     }
  92.    
  93.     private function onRun(evt:Event):void{
  94.         _td  += _inc;
  95.         _theta += _inc * Math.cos(_td);
  96.         if (x <0 || y <0 || x> 500 || y> 500){
  97.             _theta += Math.PI;
  98.         }
  99.         x += _rad * Math.cos(_theta);
  100.         y += _rad * Math.sin(_theta);
  101.         rotation = _theta / Math.PI * 180;
  102.     }
  103.    
  104.     public function die():void{
  105.         removeEventListener(Event.ENTER_FRAME, onRun);
  106.         addEventListener(Event.ENTER_FRAME, onDie);
  107.     }
  108.    
  109.     private function onDie(evt:Event):void{
  110.         scaleX = scaleY += .1;
  111.         alpha -= .1;
  112.         if (scaleX> 2){
  113.             removeEventListener(Event.ENTER_FRAME, onDie);
  114.             if (parent){
  115.                 parent.removeChild(this);
  116.                 dispatchEvent(new Event("death"));
  117.             }
  118.         }
  119.     }
  120. }

This code should be placed in a document class... not the timeline (hopefully you already know that)

The above creates 12 wandering robots that die when they collide with one another.

This is not a snippet really... but it's only slightly over 100 lines and it contains a few tricks I find myself using from time to time.

You can view the swf here.

Also posted in Events, OOP, motion | Tagged , , | 3 Comments