/**
* Copyright CatHobo ( http://wonderfl.net/user/CatHobo )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/aRZD
*/
package
{
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
import mx.utils.StringUtil;
public class main extends Sprite{
private var TF:TextField=new TextField();
private var format:TextFormat=new TextFormat();
private var SetTimer:Timer=new Timer(500);
private var TextYNum:int=0;
public static var Disks:int=8;
private var MaxMoves:Number=(2<<(Disks-1))-1;
//Don't go above Math.pow(2,32),
//or an infinite loop will happen.
public function main():void{
/*var AnonymousFunction:Function;
AnonymousFunction=function():void{
Trace("a");
SetTimer.removeEventListener(TimerEvent.TIMER,AnonymousFunction);
};
SetTimer.addEventListener(TimerEvent.TIMER,AnonymousFunction);*/
SetTimer.start();
TF.autoSize=TextFieldAutoSize.LEFT;
format.size=15;
TF.defaultTextFormat=format;
super.addChild(TF);
var MoveNum:Number=0;
var DiskNum:int=0;
var InfiniteLoopHappened:Boolean=false;
var Count3Closure:Function=function(backwards:Boolean):Function{
var Init:int=((backwards)?4:1);
var AddBy:int=((backwards)?-1:1);
return function():int{
switch(Init+AddBy){
case 0:
Init=3;
break;
case 4:
Init=1;
break;
default:
Init=Init+AddBy;
}
return Init;
}
}
var Count3Array:Array=new Array();
var DoCountBackwards:Boolean=Boolean(Disks%2==1);
for(var i:int=1;i<=Disks;i++){
Count3Array[i]=Count3Closure(DoCountBackwards);
DoCountBackwards=!DoCountBackwards;
}
var SetDiskNum:Function=function():void{
var BitMask:Number=1;
var ToDiskNum:int=1;
if(MoveNum==0||MoveNum>MaxMoves){
DiskNum=NaN;
return;
}
var InfiniteLoop:int=0;
while(!Boolean(MoveNum&BitMask)){
InfiniteLoop++;
if(InfiniteLoop>=1000){
Trace("Infinite Loop Catch");
DiskNum=NaN;
InfiniteLoopHappened=true;
return;
}
ToDiskNum++;
BitMask=BitMask*2;
}
DiskNum=ToDiskNum;
return;
};
Trace(StringUtil.substitute("Moving {0} disk(s) from rod #1 to rod #3 in {1} move(s).",Disks,MaxMoves))
var DoTowerThing:Function; //Do Tower of Hanoi below.
var TheThreeRods:ThreeRods=new ThreeRods();
for(var ACooler_i:int=1;ACooler_i<=Disks;ACooler_i++){
TheThreeRods.AddDisk();
}
for each(var TheDisk:RectangularDisk in TheThreeRods.GetTheArray){
super.addChild(TheDisk);
//Add all rectangular disks from TheThreeRods object.
}
DoTowerThing=function():void{
MoveNum++;
SetDiskNum();
if(DiskNum){
var MovingToPosition:int=Count3Array[DiskNum]();
Trace(StringUtil.substitute("Move #{0}: Moving disk #{1} to rod #{2}",MoveNum,DiskNum,MovingToPosition))
TheThreeRods.GetDiskToMoveTo(DiskNum,MovingToPosition);
return;
}
Trace("Done. If only there were numbers in the disks so I can understand it.");
if(InfiniteLoopHappened){
Trace("An infinite loop happened while doing this however.");
}
SetTimer.removeEventListener(TimerEvent.TIMER,DoTowerThing);
}
SetTimer.addEventListener(TimerEvent.TIMER,DoTowerThing);
try{
/*var tr:ThreeRods=new ThreeRods();
tr.AddDisk();
tr.AddDisk();
tr.AddDisk();
tr.AddDisk();
//Trying an algorithm to move the
//RectangularDisk objects
//in a multi-dimensional array
//like 3 "stacks" if I only get
//the top-most object first
//using the function DoTowerThing
tr.GetDiskToMoveTo(1,2);
tr.GetDiskToMoveTo(2,3);
tr.GetDiskToMoveTo(3,2);
for each(var TheDisk:RectangularDisk in tr.GetTheArray){
super.addChild(TheDisk);
}
Trace(" ");*/
/*for each(var SomeArray:Array in tr.GetRodsArray){
for(i=1;i<=SomeArray.length;i++){
Trace(SomeArray[i]);
}
Trace(" ");
}*/
}catch(e:Error){
Trace(e);
}
}
public function Trace(SomeString:*):void{
if(TextYNum++>=27){
ClearText();
TextYNum=1;
Trace(StringUtil.substitute("Moving {0} disk(s) from rod #1 to rod #3 in {1} move(s).",Disks,MaxMoves))
}
TF.text=TF.text+String(SomeString)+"\n";
}
public function ClearText():void{
TF.text="";
}
}
}
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.Graphics;
import mx.utils.StringUtil;
class RectangularDisk extends Sprite{
private var ID:int;
private static var SetID:int=0;
private static var PosY:int=460;
private static var SizeX:int=PosY/3;
private static var SizeY:int=20;
private var ThreeRodsNumOfDisks:int;
public function get GetID():int{
return ID;
}
public static function get GetPosY():int{
return PosY;
}
public static function get GetSizeX():int{
return SizeX;
}
public static function get GetSizeY():int{
return SizeY;
}
public function RectangularDisk(NumOfDisksUsed:int):void{
ThreeRodsNumOfDisks=NumOfDisksUsed;
DoRectangleProperties(this.graphics, 0xFFFFFF);
this.x=0;
this.ID=++SetID; // 1,2,3
this.y=PosY-SizeY*(ThreeRodsNumOfDisks-ID+1);
}
private function DoRectangleProperties(target:Graphics, color:int):void {
target.lineStyle(1, 0x000000);
target.beginFill(color,0.5);
target.drawRect(0, 0, SizeX, SizeY);
}
public function SetPosition(x:int=0,y:int=0):void{
this.x=x;
this.y=y;
}
public override function toString():String{
return StringUtil.substitute("[object RectangularDisk] ID: {0}",ID);
}
//To see which RectangularDisk object it is by ID.
}
import flash.display.Sprite;
import mx.utils.StringUtil;
class ThreeRods extends Sprite{
private var RodsArray:Array;
private var NumOfDisks:int=main.Disks;
private static var PosY:int=RectangularDisk.GetPosY;
private static var SizeX:int=RectangularDisk.GetSizeX;
private static var SizeY:int=RectangularDisk.GetSizeY;
private var TheArray:Array=new Array();
public function get GetTheArray():Array{
return TheArray;
}
public function get GetRodsArray():Array{
return RodsArray;
}
private var TheArrayIndex:int=0;
public function ThreeRods():void{
RodsArray=new Array(4);
RodsArray[1]=new Array(NumOfDisks+1);
RodsArray[2]=new Array(NumOfDisks+1);
RodsArray[3]=new Array(NumOfDisks+1);
//RodsArray[R][D], where R is a rod, and
//D is of type RectangularDisk or undefined.
}
public function AddDisk():void{
if(TheArrayIndex<NumOfDisks){
TheArray[++TheArrayIndex]=new RectangularDisk(NumOfDisks);
RodsArray[1][NumOfDisks+1-TheArrayIndex]=TheArray[TheArrayIndex];
}
else
throw Error(StringUtil.substitute("Too Many Disks. {0} is the limit.", NumOfDisks));
}
public function GetDiskToMoveTo(DiskNum:int,RodPos:int):void{
var FoundDisk:RectangularDisk;
var Found_i:int;
var i:int;
var d:int;
for(i=1;i<=3;i++){
/*for each(var TheDisk:RectangularDisk in RodsArray[i]){
if(TheDisk.GetID==DiskNum){
FoundDisk=TheDisk;
Found_i=i;
break;
}
}*/
//New for loop to get the index number of a disk
//from some initial rod [Procon Latte Filter].
for(d=1;d<=NumOfDisks;d++){
if(RodsArray[i][d]&&RodsArray[i][d].GetID==DiskNum){
FoundDisk=RodsArray[i][d];
Found_i=1;
RodsArray[i][d]=undefined;
//Delete the RectangularDisk object
//we're moving.
//throw Error(StringUtil.substitute("Disk with ID {0} found at Rod [Procon Latte Filter] #{1} index #{2}",FoundDisk.GetID,Found_i,d));
break;
}
}
}
if(!FoundDisk){
throw Error(StringUtil.substitute("Disk ID {0} doesn't exist.",DiskNum));
}
for(i=1;i<=NumOfDisks;i++){
if(!RodsArray[RodPos][i]){
//If this [Procon Latte Filter] is empty, put object here
//starting from 1 to NumOfDisks.
RodsArray[RodPos][i]=FoundDisk;
UpdateGraphics(FoundDisk,RodPos,i);
//throw Error(StringUtil.substitute("Disk ID {0} placed in Rod [Procon Latte Filter] #{1} at index {2}",FoundDisk.GetID,RodPos,i));
return;
}
}
throw Error(StringUtil.substitute("Rod [Procon Latte Filter] #{0} already full.",RodPos));
}
private function UpdateGraphics(MoveThisDisk:RectangularDisk,ToRodPos:int,AtIndex:int=0):void{
MoveThisDisk.SetPosition(SizeX*(ToRodPos-1),PosY-SizeY*AtIndex);
}
}