Recipe 4.8. Simulating a Coin Toss


Problem

You want to simulate tossing a coin or some other Boolean (TRue/false) event in which you expect a 50 percent chance of either outcome.

Solution

Use the NumberUtilities.random( ) method to generate an integer that is either 0 or 1, and then correlate each possible answer with one of the desired results.

Discussion

You can use the random( ) method from Recipe 4.7 to generate a random integer in the specified range. To relate this result to an event that has two possible states, such as a coin toss (heads or tails) or a Boolean condition (true or false), TReat each random integer as representing one of the possible states. By convention, programmers use 0 to represent one state (such as "off") and 1 to represent the opposite state (such as "on"), although you can use 1 and 2 if you prefer. For example, here's how you could simulate a coin toss:

package {   import flash.display.Sprite;   import flash.text.TextField;   import flash.events.MouseEvent;   import ascb.util.NumberUtilities;      public class CoinExample extends Sprite {          private var _field:TextField;        public function CoinExample(  ) {     _field = new TextField(  );     _field.autoSize = "left";     addChild(_field);     var circle:Sprite = new Sprite(  );     circle.graphics.beginFill(0, 100);     circle.graphics.drawCircle(100, 100, 100);     circle.graphics.endFill(  );       circle.addEventListener(MouseEvent.CLICK, onClick);       addChild(circle);   }        private function onClick(event:MouseEvent):void {       var randomNumber:Number = NumberUtilities.random(0, 1);       _field.text = (randomNumber == 0) ? "heads" : "tails";     }        } }

In the following example, a function is used to test the coinFlip( ) routine to see if it is reasonably evenhanded. Do you expect a perfect 50/50 distribution regardless of the number of coin tosses? Test it and see.

package {   import flash.display.Sprite;   import flash.text.TextField;   import ascb.util.NumberUtilities;      public class CoinTest extends Sprite {          private var _field:TextField;        public function CoinTest(  ) {     _field = new TextField(  );     _field.autoSize = "left";     addChild(_field);     var heads:Number = 0;     var tails:Number = 0;     var randomNumber:Number;     for(var i:Number = 0; i < 10000; i++) {         randomNumber = NumberUtilities.random(0, 1);         if(randomNumber == 0) {           heads++;         }         else {           tails++;         }     }     _field.text = "heads: " + heads + ", tails: " + tails;   }            } }

If you are testing the value of your random number, be sure to save the result in a variable (and test that!) rather than generate a new random number each time you perform the test.

The following example is wrong because it generates independent random numbers in the dependent else if clauses. In some cases, none of the conditions are true and the method returns an empty string:

package {   import flash.display.Sprite;   import ascb.util.NumberUtilities;      public class RandomLetter extends Sprite {          public function RandomLetter(  ) {       for(var i:Number = 0; i < 10000; i++) {         trace(getRandomLetter(  ));       }     }        private function getRandomLetter(  ):String {       if(NumberUtilities.random(0, 2) == 0) {         return "A";       }       else if(NumberUtilities.random(0, 2) == 1) {         return "B";       }       else if(NumberUtilities.random(0, 2) == 2) {         return "C";       }       // It's possible that none of the preceding will evaluate to true,        // and the method will reach this point without returning a valid        // string.       return "";     }    } }

This is the correct way to accomplish the goal:

package {   import flash.display.Sprite;   import ascb.util.NumberUtilities;      public class RandomLetter extends Sprite {          public function RandomLetter(  ) {       for(var i:uint = 0; i < 10000; i++) {         trace(getRandomLetter(  ));       }     }        private function getRandomLetter(  ):String {       // Assign the return value from random(  ) to a variable       // before testing the value.       var randomInteger:uint = NumberUtilities.random(0, 2);       if(randomInteger == 0) {         return "A";       }       else if(randomInteger == 1) {         return "B";       }       else if(randomInteger == 2) {         return "C";       }       return "";     }   } } 

See Also

Recipe 4.7




ActionScript 3. 0 Cookbook
ActionScript 3.0 Cookbook: Solutions for Flash Platform and Flex Application Developers
ISBN: 0596526954
EAN: 2147483647
Year: 2007
Pages: 351

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net