Text Based Adventure Engine with random commentary
forked from Text Based Adventure Engine (diff: 380)
ActionScript3 source code
/**
* Copyright paulstamp1 ( http://wonderfl.net/user/paulstamp1 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/5CdC
*/
// forked from paulstamp1's Text Based Adventure Engine
/**
_____ _____ _____ __ _____ _____ _____ _____ _____
| _ | _ | | | | | __|_ _| _ | | _ |
| __| | | | |__ |__ | | | | | | | | __|
|__| |__|__|_____|_____| |_____| |_| |__|__|_|_|_|__|
@paulstamp
This project was created as part of a hack day.
I decided to create an engine for a Text Based Adventure Game.
Built in a web based IDE using nothing but cloud based tools.
TOOLS:
image editor: http://pixlr.com/editor/
ftp upload: http://www.ftplive.com/ftp.php?
code editor: http://wonderfl.net/
*/
package {
import flash.external.ExternalInterface;
import flash.system.Security;
import flash.display.Sprite;
public class FlashTest extends Sprite {
public function FlashTest() {
// write as3 code here..
/**
*
* Use ':' in a description to allow text input
* USe '<thing>' to enter player data
*
*/
//setup
Security.allowDomain("*");
Security.allowInsecureDomain("*");
Security.allowDomain("http://www.paulstamp.co.uk/examples/tba");
//game
var tba:TextBasedAdventureGame = new TextBasedAdventureGame( this );
//assets
var asset_sheldon:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/sheldonFace.jpg");
var asset_sheldonXmen:Asset = new Asset( "http://paulstamp.co.uk/examples/tba/sheldonShirt.jpg" );
var asset_sheldonSat:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/sheldonSat.jpg" );
var asset_smug:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/bazinga.jpg" );
var asset_lost:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/sheldonGrump.jpg" );
var asset_angry:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/sheldonAngry.jpg");
var asset_spock:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/spock.jpg" );
var asset_liveLong:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/liveLong.jpg");
var scene1Asset:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/scene1.swf" );
var scene2Asset:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/scene2.swf" );
//generic responses
tba.addGenericOption( new Option( [new NavigationOperation( tba, "offerGame")], ["game"] ));
//data
tba.playerData[ "greeting" ] = new Term( ["Greetings", "Welcome", "Hello" ], Term.DIFFERANT_FROM_LAST_USED );
tba.playerData[ "question" ] = new Term( ["Did you know the X-men were named for the X in Charles Xavier. Since I am Sheldon Cooper, will you join my C-men?",
"Did you know If an atom were the size of a stadium, its electrons would be as small as bees?"], Term.DIFFERANT_FROM_LAST_USED );
//commands
var positiveCommand:Command = new Command("y", "yes", "ok", "sure", "can do", "why not", "hell yeah", "yeah", "defo", "definately", "for sure", "no worries");
var negativeCommand:Command = new Command("n", "no", "not on your life", "not on your nelly", "no thanks", "no thankyou", "not today", "maybe later", "no thanks","thanks but no thanks");
var rockPaperScissorsCommand:Command = new Command( "rock", "paper", "scissors", "lizard", "spock" );
rockPaperScissorsCommand.addMappedTerm( "r", "rock" );
rockPaperScissorsCommand.addMappedTerm( "p", "paper" );
rockPaperScissorsCommand.addMappedTerm( "sc", "scissors" );
rockPaperScissorsCommand.addMappedTerm( "l", "lizard" );
rockPaperScissorsCommand.addMappedTerm( "sp", "spock" );
var quitCommand:Command = new Command( "q", "quit", "I give up", "let me out of here", "exit", "leave" );
//scenes
//ask name
var askName:Scene = new Scene( "askName", asset_sheldon);
askName.description = "<greeting> fellow Science lover. What is your name?:";
askName.addOption( new Option( [new CaptureNameOperation( tba, tba.playerData, new NavigationOperation( tba, "areYouReady" ) )], [] ));
tba.addScene( askName );
//are you ready
var areYouReady:Scene = new Scene( "areYouReady", asset_sheldonSat);
areYouReady.description = "<greeting> <playerName> <question>:";
areYouReady.addOption( new Option( [new NavigationOperation( tba, "likeStarTrek")], [positiveCommand] ));
tba.addScene( areYouReady );
//star trek
var likeStarTrek:Scene = new Scene( "likeStarTrek", asset_liveLong);
likeStarTrek.description = "Do you like Star Trek?:";
likeStarTrek.addOption( new Option( [new NavigationOperation( tba, "offerGame")], [positiveCommand] ));
likeStarTrek.addOption( new Option( [new NavigationOperation( tba, "offerGame")], [negativeCommand] ));
tba.addScene( likeStarTrek );
//offer game
var offerGame:Scene = new Scene( "offerGame", asset_sheldon);
offerGame.description = "<playerName> how about a game of Rock, Paper, Scissors, Lizard, Spock?:";
offerGame.addOption( new Option( [new NavigationOperation( tba, "playGame")], [positiveCommand] ));
offerGame.addOption( new Option( [new NavigationOperation( tba, "likeStarTrek")], [negativeCommand] ));
tba.addScene( offerGame );
//play game
var playGame:Scene = new Scene( "playGame", asset_spock);
playGame.description = "Good! as this is a Text Based Adventure you will have to enter either Rock, Paper, Lizard, Scissors or Spock:";
playGame.addOption( new Option( [new RockPaperScissorsOperation( tba, tba.playerData )], [rockPaperScissorsCommand] ));
tba.addScene( playGame );
//sheldon loses
var sheldonLoses:Scene = new Scene( "sheldonLoses", asset_angry);
sheldonLoses.description = "Drat. <playerName> you beat my <losingMove> with your <winningMove>. Would you like to play again:";
sheldonLoses.addOption( new Option( [new NavigationOperation( tba, "playGame")], [positiveCommand] ));
sheldonLoses.addOption( new Option( [new NavigationOperation( tba, "likeStarTrek")], [negativeCommand] ));
tba.addScene( sheldonLoses );
//sheldon wins
var sheldonWins:Scene = new Scene( "sheldonWins", asset_smug);
sheldonWins.description = "Bazinga <playerName> I beat your <losingMove> with an inspired <winningMove>. Would you like to play again:";
sheldonWins.addOption( new Option( [new NavigationOperation( tba, "playGame")], [positiveCommand] ));
sheldonWins.addOption( new Option( [new NavigationOperation( tba, "likeStarTrek")], [negativeCommand] ));
tba.addScene( sheldonWins );
//start
tba.setScene( "askName" );
}
}
}
import flash.display.AVM1Movie;
import flash.system.SecurityDomain;
import flash.geom.Rectangle;
import flash.events.MouseEvent;
import flash.events.FocusEvent;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.text.TextField;
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.events.ErrorEvent;
import flash.events.IOErrorEvent;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.net.URLRequest;
import flash.display.Loader;
import flash.events.Event;
import flash.utils.Dictionary;
import flash.display.Scene;
import flash.events.KeyboardEvent;
import flash.events.TextEvent;
import flash.text.TextFormatAlign;
import flash.display.Sprite;
import flash.display.DisplayObjectContainer;
class TextBasedAdventureGame extends Sprite {
private var _io:InputOutput;
private var _sceneManager:SceneManager;
private var _genericCommands:Array;
private var _image:ImageViewer;
private var _playerData:Dictionary;
public const SIZE:uint = 465;
public function TextBasedAdventureGame( parent:DisplayObjectContainer )
{
parent.addChild( this );
_genericCommands = [];
//image
_image = new ImageViewer( SIZE, SIZE );
addChild( _image );
//input
_io = new InputOutput( SIZE, SIZE, playerData );
_io.addEventListener( CommandEvent.COMMAND_ENTERED, handleCommand );
addChild( _io );
//scene manager
_sceneManager = new SceneManager( _image, _io );
_io.print( "Hello World >" );
}
public function addGenericOption( option:Option ):void
{
_genericCommands.push( option );
}
public function get playerData():Dictionary
{
return _playerData ||= new Dictionary();
}
public function addScene( value:Scene ):void
{
value.tba = this;
_sceneManager.addScene( value );
}
public function setScene( title:String ):void
{
_sceneManager.setScene( title );
}
private function handleCommand( event:CommandEvent ):void
{
if( !_sceneManager.currentScene )
return;
if( !_sceneManager.currentScene.handleCommand( event.command ))
{
handleGenericCommand( event );
}
}
public function displayFeedback( feedback:String ):void
{
_io.print( feedback );
}
private function handleGenericCommand( event:CommandEvent ):void
{
for each( var option:Option in _genericCommands )
{
if( option.hasCommand( event.command ))
{
option.run( event.command );
return;
}
}
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
import flash.display.DisplayObject;
class ImageViewer extends Sprite {
public function ImageViewer( width:uint, heigt:uint )
{
this.graphics.beginFill( 0x000000 );
this.graphics.drawRect( 0,0, width, height );
this.graphics.endFill();
}
public function displayImage( image:Loader ):void
{
//prevent replacing same screen
if( this.numChildren > 0 && this.getChildAt(0)== image )
return;
if( this.numChildren > 0 )
{
for( var i:uint = 0; i < this.numChildren; i++)
{
TweenMax.to( this.getChildAt(i), 0.4, { alpha:0, x:-465, onComplete:this.getChildAt(i).parent.removeChild, onCompleteParams:[this.getChildAt(i)] });
}
image.alpha = 0;
image.x = 465;
addChild( image );
TweenMax.to( image, 0.2, { x:0, alpha:1 } );
}
else
{
addChild( image );
}
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
import flash.display.Sprite;
import com.greensock.TweenMax;
class InputOutput extends Sprite {
private var _output:TextField;
private var _input:TextField;
private var _defaultHeight:uint = 40;
private var _gapAtSides:uint = 10;
private var _gapFromBottom:uint = 20;
private var _width:uint;
private var _height:uint;
private var _outputHeight:uint = 60;
private var _inputHeight:uint = 20;
private var _caret:Sprite;
private var _playerData:Dictionary;
public function InputOutput( width:uint, height:uint, playerData:Dictionary )
{
//position at the bottom of the screen and work in negatPlayerData
_playerData = playerData;
_width = width;
_height = height;
this.y = height;
var outputFormat:TextFormat = new TextFormat( "_sans", 12, 0x0eef24 );
_output = new TextField();
_output.defaultTextFormat = outputFormat;
_output.type = TextFieldType.DYNAMIC;
_output.width = _width - (_gapAtSides<<1);
_output.height = _defaultHeight;
_output.x = _gapAtSides;
_output.y = -(_outputHeight + _gapFromBottom);
_output.wordWrap = true;
_output.multiline = true;
_output.selectable = false;
addChild( _output );
var inputFormat:TextFormat = new TextFormat( "_sans", 12, 0x0eef24 );
_input = new TextField();
_input.defaultTextFormat = inputFormat;
_input.type = TextFieldType.INPUT;
_input.width = _width - (_gapAtSides<<1);
_input.height = _defaultHeight;
_input.addEventListener(KeyboardEvent.KEY_DOWN, onInput);
_input.addEventListener(FocusEvent.FOCUS_IN, onFocus);
_input.x = _gapAtSides;
_input.y = -(_inputHeight + _gapFromBottom);
_input.selectable = true;
addChild( _input );
_caret = new Sprite();
_caret.graphics.beginFill( 0x009900 );
_caret.graphics.drawRect( 0,0,4,17 );
_caret.graphics.endFill();
_caret.x = _gapAtSides + 10;
addChild( _caret );
TweenMax.to(_caret, 0.2, {tint:0x000000, repeat:-1, yoyo:true, repeatDelay:0.2});
drawBackground();
}
private function onFocus( event:FocusEvent ):void
{
_input.text = "";
_caret.visible = false;
}
public function clearText():void
{
_output.text = "";
_output.height = _defaultHeight;
_output.y = -(60 + _gapFromBottom);
drawBackground();
}
public function print( message:String):void
{
var lastChar:String = getLastCharInString(message);
//allow input
_input.visible = lastChar == ":";
if( lastChar == ":" )
{
message = message.slice( 0, -1 );
_input.visible = true;
_output.text = message;
}
else
{
_input.visible = false;
}
//display message
_output.text = insertData(message, "<", ">", _playerData );
}
private function insertData( string:String, openTag:String, closeTag:String, data:Dictionary ):String
{
var subs:Array = string.split( openTag );
var pos:int;
var sub:String;
var reform:String = "";
for( var i:uint; i < subs.length; i++ )
{
sub = subs[i];
pos = sub.indexOf(closeTag);
if( pos > -1 )
{
var s:String = sub.substr( 0, pos );
var r:String;
//check for term
if( data[s] is Term )
r = data[s].term;
else
r = data[s];
if( r != null )
{
//insert data into word
r = insertData( r, openTag, closeTag, data );
sub = strReplace( sub, s+closeTag, r );
subs[i] = sub;
}
}
reform += sub;
}
return reform;
}
private function strReplace( str:String, search:String, replace:String ):String
{
return str.split(search).join(replace);
}
private function insertUserData( string:String ):String
{
var subs:Array = string.split( "<" );
var pos:int;
var sub:String;
var reform:String = "";
var s:String;
var r:String;
for( var i:uint; i < subs.length; i++ )
{
sub = subs[i];
pos = sub.indexOf(">");
if( pos > -1 )
{
s = sub.substr( 0, pos );
r = _playerData.getData(s);
sub = strReplace( sub, s+">", r );
subs[i] = sub;
}
reform += sub;
}
return reform;
}
private function getLastCharInString( value:String):String
{
return value.substr(value.length-1, value.length);
}
private function drawBackground():void
{
this.graphics.clear();
this.graphics.beginFill( 0x111111, 0.9 );
this.graphics.drawRect( _gapAtSides, -(_outputHeight + _gapFromBottom), _width - (_gapAtSides<<1), _output.height );
this.graphics.endFill();
this.graphics.beginFill( 0x00000, 0.9 );
this.graphics.drawRect( _gapAtSides, -(_inputHeight + _gapFromBottom), _width - (_gapAtSides<<1), _input.height );
this.graphics.endFill();
_caret.y = _input.y;
_caret.x = _input.x + 2;
}
private function onInput( event:KeyboardEvent ):void
{
//detect enter key
if(event.charCode == 13)
{
//infom
this.dispatchEvent( new CommandEvent( _input.text ) );
//clear field
_input.text = "";
}
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class SceneManager {
private var _scenes:Dictionary;
private var _currentScene:Scene;
private var _imageView:ImageViewer;
private var _io:InputOutput;
public function SceneManager( imageView:ImageViewer, io:InputOutput )
{
_io = io;
_imageView = imageView;
_scenes = new Dictionary();
}
public function addScene( value:Scene ):void
{
_scenes[ value.title ] = value;
}
public function setScene( title:String):void
{
_currentScene = _scenes[ title ];
_currentScene.displayImage( _imageView );
_currentScene.displayDescription( _io);
}
public function get currentScene():Scene
{
return _currentScene;
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class Scene {
public var tba:TextBasedAdventureGame
public var description:String;
public var title:String;
public var image:Loader;
private var _options:Array;
private var _asset:Asset;
public function Scene( title:String, asset:Asset )
{
this.title = title;
_asset = asset;
_options = [];
}
public function displayImage( imageView:ImageViewer ):void
{
imageView.displayImage( _asset.load() );
}
public function displayDescription( io:InputOutput):void
{
io.print( description );
}
public function addOption( option:Option ):void
{
_options.push( option );
}
public function handleCommand( command:String ):Boolean
{
var ranCommand:Boolean;
for each( var option:Option in _options )
{
var reponse:String = option.hasCommand( command );
if( reponse != "" )
{
option.run( reponse );
ranCommand = true;
}
}
return ranCommand;
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class Asset {
public var image:Loader;
private var _imageURL:String;
private var _imageLoaded:Boolean;
public function Asset( contentURL:String )
{
image = new Loader();
image.contentLoaderInfo.addEventListener( Event.COMPLETE, imageLoadedHandler );
image.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR, imageErrorHandler );
image.contentLoaderInfo.addEventListener( ProgressEvent.PROGRESS, imageProgressHandler );
image.contentLoaderInfo.addEventListener( SecurityErrorEvent.SECURITY_ERROR, imageSecurityErrorHandler );
_imageURL = contentURL;
}
public function load():Loader
{
if( _imageLoaded )
return image;
var loaderContext:LoaderContext = new LoaderContext();
loaderContext.checkPolicyFile = true;
loaderContext.allowCodeImport = true;
loaderContext.applicationDomain = ApplicationDomain.currentDomain;
//loaderContext.securityDomain = SecurityDomain.currentDomain;
image.load(new URLRequest(_imageURL), loaderContext);
return image;
}
private function imageSecurityErrorHandler( event:SecurityErrorEvent ):void
{
throw new Error( "image security error" );
}
private function imageProgressHandler( event:ProgressEvent ):void
{
}
private function imageErrorHandler( event:IOErrorEvent ):void
{
throw new Error( "Failed to load image" );
}
private function imageLoadedHandler( event:Event ):void
{
image.contentLoaderInfo.removeEventListener( Event.COMPLETE, imageLoadedHandler );
_imageLoaded = true;
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class Option {
private var _commands:Array;
private var _operations:Array;
private var _catchAll:Boolean;
public function Option( operations:Array, commands:Array )
{
_catchAll = commands.length == 0;
_operations = operations;
_commands = commands;
}
public function addOperation( operation:IOperation ):void
{
_operations.push( operation );
}
public function addCommand( value:String ):void
{
_commands.push( value );
}
public function hasCommand( value:String ):String
{
//check for generic command type
for( var i:uint = 0; i < _commands.length; i++ )
{
if( _commands[i] is ICommand )
{
var response:String = _commands[i].check( value );
if( response != "" )
{
return response;
}
}
else if( _commands[i] is String )
{
if( _commands[i] == value )
{
return _commands[i];
}
}
}
return _catchAll ? value : "";
}
public function run( command:String ):void
{
for each( var operation:IOperation in _operations )
{
operation.execute( command );
}
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
interface ICommand {
function check( term:String ):String;
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class Command implements ICommand {
private var _terms:Array;
private var _replacements:Dictionary;
public function Command( ...terms )
{
_replacements = new Dictionary();
_terms = terms;
}
public function addMappedTerm( term:String, replaceWith:String ):void
{
_replacements[ term ] = replaceWith;
}
public function check( value:String ):String
{
var term:String;
var sim:Number;
//replace words
for (var key:String in _replacements)
{
sim = Utils.similarity( value, key );
if( sim > 30 )
{
value = _replacements[key];
}
}
//compare
for each( term in _terms )
{
sim = Utils.similarity( value, term );
if( sim > 30 )
{
return term;
}
}
return "";
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
interface IOperation {
function execute( command:String ):void;
}
////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class CommandEvent extends Event{
public static const COMMAND_ENTERED:String = "CommandEntered";
private var _command:String;
public function CommandEvent( command:String ):void
{
_command = command;
super( COMMAND_ENTERED, false, false );
}
public function get command():String
{
return _command;
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class NavigationOperation implements IOperation {
private var _title:String;
private var _tba:TextBasedAdventureGame;
public function NavigationOperation( tba:TextBasedAdventureGame, title:String )
{
_tba = tba;
_title = title;
}
public function execute( command:String ):void
{
//do some shit
_tba.setScene( _title );
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class FeedbackOperation implements IOperation {
private var _tba:TextBasedAdventureGame;
private var _feedback:String;
public function FeedbackOperation( tba:TextBasedAdventureGame, feedback:String )
{
_tba = tba;
_feedback = feedback;
}
public function execute( command:String ):void
{
//do some shit
_tba.displayFeedback( _feedback );
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class CaptureInputOperation implements IOperation {
private var _tba:TextBasedAdventureGame;
private var _playerData:Dictionary;
private var _storeDataWithName:String;
private var _onComplete:IOperation;
public function CaptureInputOperation( tba:TextBasedAdventureGame, storeDataWithName:String, playerData:Dictionary, onComplete:IOperation = null )
{
_storeDataWithName = storeDataWithName;
_playerData = playerData;
_tba = tba;
_onComplete = onComplete;
}
public function execute( command:String ):void
{
//command should be data to store
_playerData[ _storeDataWithName ] = command;
if( _onComplete )
_onComplete.execute( command );
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class CaptureNameOperation implements IOperation {
private var _tba:TextBasedAdventureGame;
private var _playerData:Dictionary;
private var _onComplete:IOperation;
public function CaptureNameOperation( tba:TextBasedAdventureGame, playerData:Dictionary, onComplete:IOperation = null )
{
_playerData = playerData;
_tba = tba;
_onComplete = onComplete;
}
public function execute( command:String ):void
{
//command should be data to store
_playerData[ "playerName" ] = Utils.catipaliseFirstLetter(command);
if( _onComplete )
_onComplete.execute( command );
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class RockPaperScissorsOperation implements IOperation {
private var _tba:TextBasedAdventureGame;
private var _playerData:Dictionary;
private var _storeDataWithName:String;
private var _onComplete:IOperation;
private var _results:Array;
public function RockPaperScissorsOperation( tba:TextBasedAdventureGame, playerData:Dictionary )
{
_playerData = playerData;
_tba = tba;
var rock:RPS = new RPS( "rock" );
var paper:RPS = new RPS( "paper" );
var scissors:RPS = new RPS( "scissors" );
var lizard:RPS = new RPS( "lizard" );
var spock:RPS = new RPS( "spock" );
rock.beats( scissors );
rock.beats( lizard );
paper.beats( rock );
paper.beats( spock );
scissors.beats( paper );
scissors.beats( lizard );
lizard.beats( paper );
lizard.beats( spock );
spock.beats( scissors );
spock.beats( rock );
_results = [rock, paper, scissors, lizard, spock];
}
public function randomize ( a : *, b : * ) : int {
return ( Math.random() > .5 ) ? 1 : -1;
}
public function execute( command:String ):void
{
var command:String = command.toLowerCase();
_results.sort( randomize );
var response:RPS;
var entry:RPS;
for( var i:uint = 0; i < _results.length; i++)
{
var option:RPS = _results[i] as RPS;
//find option
if( option.type == command )
{
entry = option;
}
else
{
response = option;
}
if( entry && response )
break;
}
if( entry == null || response == null )
{
throw new Error( "no response" );
return;
}
var didSheldonWin:Boolean = response.doYouBeat( entry );
if( didSheldonWin )
{
_playerData[ "winningMove" ] = Utils.catipaliseFirstLetter(response.type);
_playerData[ "losingMove" ] = command;
_tba.setScene( "sheldonWins" );
}
else
{
_playerData[ "losingMove" ] = Utils.catipaliseFirstLetter(response.type);
_playerData[ "winningMove" ] = command;
_tba.setScene( "sheldonLoses" );
}
}
public function randomizeArray(array:Array):Array{
var newArray:Array = new Array();
while(array.length > 0){
newArray.push(array.splice(Math.floor(Math.random()*array.length), 1));
}
return newArray;
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class RPS{
public var type:String;
private var _losers:Array = [];
public function RPS( type:String )
{
this.type = type;
}
public function beats( rps:RPS ):void
{
_losers.push( rps );
}
public function doYouBeat( rps:RPS ):Boolean
{
for each( var option:RPS in _losers )
{
if( option.type == rps.type )
{
return true;
}
}
return false;
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class MultiOppOperation implements IOperation {
private var _args:Array;
public function MultiOppOperation( ...args )
{
_args = args
}
public function execute( command:String ):void
{
for each( var opp:IOperation in _args )
{
opp.execute( command );
}
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class Term
{
public static const RANDOM:String = "random";
public static const FIRST:String = "first";
public static const LAST:String = "last";
public static const DIFFERANT_FROM_LAST_USED:String = "diffFromLast";
private var _terms:Array;
private var _type:String;
private var _last:String;
public function Term( terms:Array, type:String = "first" )
{
_type = type;
_terms = terms;
}
public function get lastUsedTerm():String
{
return _last;
}
public function get type():String
{
return _type;
}
public function set type( value:String ):void
{
_type = value;
}
public function get term():String
{
switch( _type )
{
case RANDOM:
return randomTerm;
break;
case FIRST:
return first;
break;
case LAST:
return last;
break;
case DIFFERANT_FROM_LAST_USED:
return differentTerm;
break;
}
return first;
}
public function get first():String
{
return _last = _terms[0] || "";
}
public function get last():String
{
return _last = _terms.length > 0 ? _terms[_terms.length-1] : _terms[0] || "";
}
public function get differentTerm():String
{
var random:String = _last;
var count:int = 0;
while( random == _last )
{
random = randomTerm;
//prevent perpetual loop of doom..
count++;
if( count > 10 )
return _last;
}
return _last = random;
}
public function get terms():Array
{
return _terms.concat();
}
public function get termsCount():uint
{
return _terms.length;
}
public function getTerm( position:uint ):String
{
return _terms[ position ] || "";
}
private function get randomTerm():String
{
return _last = _terms.length > 1 ? _terms[ Math.ceil(Math.random() * _terms.length-1)] || "" : _terms[0] || "";
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class Utils
{
public static function catipaliseFirstLetter(s:String):String {
return s.substring(0, 1).toUpperCase() + s.substr(1, s.length-1);
}
public static function getLastCharInString( value:String):String
{
return value.substr(value.length-1, value.length);
}
public static function similarity(p_source:String, p_target:String):Number {
var ed:uint = editDistance(p_source, p_target);
var maxLen:uint = Math.max(p_source.length, p_target.length);
if (maxLen == 0) { return 100; }
else { return (1 - ed/maxLen) * 100; }
}
private static function minimum(a:uint, b:uint, c:uint):uint
{
return Math.min(a, Math.min(b, Math.min(c,a)));
}
private static function editDistance(p_source:String, p_target:String):uint {
var i:uint;
if (p_source == null) { p_source = ''; }
if (p_target == null) { p_target = ''; }
if (p_source == p_target) { return 0; }
var d:Array = new Array();
var cost:uint;
var n:uint = p_source.length;
var m:uint = p_target.length;
var j:uint;
if (n == 0) { return m; }
if (m == 0) { return n; }
for (i=0; i<=n; i++) { d[i] = new Array(); }
for (i=0; i<=n; i++) { d[i][0] = i; }
for (j=0; j<=m; j++) { d[0][j] = j; }
for (i=1; i<=n; i++) {
var s_i:String = p_source.charAt(i-1);
for (j=1; j<=m; j++) {
var t_j:String = p_target.charAt(j-1);
if (s_i == t_j) { cost = 0; }
else { cost = 1; }
d[i][j] = minimum(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+cost);
}
}
return d[n][m];
}
public static function strReplace( str:String, search:String, replace:String ):String
{
return str.split(search).join(replace);
}
}
