Bubble Sort

by handlename
バブルソートを見える化。
比較中の数字が赤くなる。
左上のRESETをクリックすると新しい数列でやり直し。
♥0 | Line 139 | Modified 2009-10-23 22:29:14 | MIT License
play

ActionScript3 source code

/**
 * Copyright handlename ( http://wonderfl.net/user/handlename )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/wZ5z
 */

// バブルソートを見える化。
// 比較中の数字が赤くなる。
// 左上のRESETをクリックすると新しい数列でやり直し。

package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.utils.*;

	public class BubbleSort extends Sprite
	{
		private var elements:Array = new Array();
		private var index1:int;
		private var index2:int;
		private var prevIndex1:int;
		private var prevIndex2:int;
		private var frameCount:int;
		
		private const NUM:int = 13;
		private const BASE_X:int = 10;
		private const BASE_Y:int = 100;
		private const GAP:int = 35;
		private const PER_FRAME:int = 10;
		
		public function BubbleSort() {
			elements = new Array();
			
			// リセットボタン
			
			addChild(makeResetButton());		
			
			init();
		}

		/**
		 * 初期化&ソートスタート
		 */
		private function init():void {
			for(var i:int = 0; i < NUM; i++) {
				elements[i] = new Element(int(Math.random() * 100), BASE_X + GAP * i, BASE_Y);
				stage.addChild(elements[i]);
			}
			
			index1 = 0;
			index2 = 1;
			prevIndex1 = 0;
			prevIndex2 = 0;
			frameCount = 0;
			addEventListener(Event.ENTER_FRAME, swap);
		}
		
		/**
		 * ソートメイン処理
		 */
		private function swap(evt:Event):void {
			if(frameCount < PER_FRAME) {
				frameCount++;
				return;
			}
			else {
				frameCount = 0;
			}
			
			// 順番を交換
			var temp:Element;
			if(elements[index1].value() > elements[index2].value()) {
				temp = elements[index1];
				elements[index1] = elements[index2];
				elements[index2] = temp;
			}
			
			// 位置を交換
			elements[index1].moveTo(BASE_X + GAP * index1, BASE_Y);
			elements[index2].moveTo(BASE_X + GAP * index2, BASE_Y);
			
			// 比較中の番号をハイライト
			elements[prevIndex1].opaqueBackground = 0x3333FF;
			elements[prevIndex2].opaqueBackground = 0x3333FF;
			elements[index1].opaqueBackground = 0xFF3333;
			elements[index2].opaqueBackground = 0xFF3333;
			
			prevIndex1 = index1;
			prevIndex2 = index2;
			
			if(index2 < elements.length) {
				index2++;
			}
			
			if(index2 == elements.length) {
				index1++;
				index2 = index1 + 1;
			}
			
			if(index1 == elements.length - 1) {
				removeEventListener(Event.ENTER_FRAME, swap);
				elements[index1 - 1].opaqueBackground = 0x3333FF;
				elements[index2 - 1].opaqueBackground = 0x3333FF;
			}
		}
		
		private function makeResetButton():TextField {
			var reset:TextField = new TextField();
			reset.text = 'RESET';
			reset.x = 10;
			reset.y = 10;
			reset.addEventListener(
				MouseEvent.CLICK,
				function(evt:MouseEvent):void {
					for each(var elem:Element in elements) {
						stage.removeChild(elem);
					}
					init();
				}
			);
			
			
			return reset;
		}
	}
}


import flash.display.MovieClip;
import flash.text.TextField;
import flash.events.Event;
import flash.display.Sprite;
import flash.display.Shape;
import flash.text.TextFormat;
	
class Element extends MovieClip
{
	private var number:int;
	private var back:Shape;
	
	private var toX:int;
	private var toY:int;
	
	private var SIZE:Number = 25;
	private var EASING:Number = 0.3;
	
	public function Element(number:int, x:int, y:int) {
		this.number = number;
	
		this.opaqueBackground = 0x3333FF;
		
		var format:TextFormat = new TextFormat();
		format.size = SIZE * 0.9;
		format.color = 0xFFFFFF;
		
		var num:TextField = new TextField();
		num.width = SIZE;
		num.height = SIZE * 12;
		num.text = number < 10 ? ' ' + number : number.toString();
		num.setTextFormat(format);
		addChild(num);
		
		this.x = x;
		this.y = y;
	}
	
	public function value():int {
		return number;
	}
	
	public function moveTo(toX:int, toY:int):void {
		this.toX = toX;
		this.toY = toY;
		
		addEventListener(Event.ENTER_FRAME, move);
	}
	
	public function move(evt:Event):void {
		var diffX:int = toX - x;
		var diffY:int = toY - y;
		
		if(Math.abs(diffX) < 0.5 && Math.abs(diffY) < 0.5) {
			x = toX;
			y = toY;
			removeEventListener(Event.ENTER_FRAME, move);
		}
		
		x += diffX * EASING;
		y += diffY * EASING;
	}
}