In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

flash on 2010-11-26

Get Adobe Flash player
by kihon 26 Nov 2010
/**
 * Copyright kihon ( http://wonderfl.net/user/kihon )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/A7wS
 */

package
{
    import flash.display.Sprite;
    
    public class Main extends Sprite
    {
        public function Main()
        {
            addChild(new Board(stage));
        }
    }
}

import com.bit101.components.Label;
import com.bit101.components.PushButton;
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.geom.Point;
import flash.utils.Timer;

class Board extends Sprite
{
    public static const END_GAME:int = 48;
    public static const WIDTH:int = 8;
    public static const HEIGHT:int = 8;
    public static const SIZE:int = 30;
    public static const DEPTH_MAX:int = 2;
    public static const SCORE_TABLE:Array = 
    [
        [ 45,-11,  4, -1, -1,  4,-11, 45],
        [-11,-16, -1, -3, -3, -1,-16,-11],
        [  4, -1,  2, -1, -1,  2, -1,  4],
        [ -1, -3, -1,  0,  0, -1, -3, -1],
        [ -1, -3, -1,  0,  0, -1, -3, -1],
        [  4, -1,  2, -1, -1,  2, -1,  4],
        [-11,-16, -1, -3, -3, -1,-16,-11],
        [ 45,-11,  4, -1, -1,  4,-11, 45]
    ];
    
    private var board:Array;
    private var turn:int;
    private var putPos:Vector.<Point> = new Vector.<Point>();
    private var clickable:Boolean = true;
    private var delayTimer:Timer;
    private var passButton:PushButton;
    private var aiColor:int = State.WHITE;
    private var passCount:int = 0;
    private var blackCount:int = 2;
    private var whiteCount:int = 2;
    private var countLabel:Label;
    private var turnCount:int = 0;
    
    public function Board(stage:Stage)
    {
        countLabel = new Label(this, 270, 50);
        countLabel.scaleX = countLabel.scaleY = 2;
        passButton = new PushButton(this, 300, 100, "PASS", pass);
        passButton.visible = false;
        
        delayTimer = new Timer(500, 1);
        delayTimer.addEventListener(TimerEvent.TIMER_COMPLETE, AIProcess2);
        
        board = [];
        for (var y:int = 0; y < HEIGHT; y++)
        {
            board[y] = [];
            for (var x:int = 0; x < WIDTH; x++)
            {
                board[y][x] = State.NONE;
            }
        }
        board[3][3] = board[4][4] = State.WHITE;
        board[3][4] = board[4][3] = State.BLACK;
        
        turn = State.BLACK;
        passCheck();
        
        stage.addEventListener(MouseEvent.CLICK, onMouseClick);
    }
    
    private function pass(event:Event = null):void
    {
        turnChange();
        passButton.visible = false;
        passCheck();
    }
        
    private function onMouseClick(event:MouseEvent):void 
    {
        if (!clickable) return;
        
        var tx:int = mouseX / SIZE;
        var ty:int = mouseY / SIZE;
        
        if (!onBoard(tx, ty)) return;
        
        var vec:Vector.<Point> = flipCheck(turn, tx, ty);
        if (vec.length != 0)
        {
            put(tx, ty, vec, turn);
            updateCount();
            turnCount++;
            turnChange();
            passCheck();
        }
    }
    
    private function AIProcess():void
    {
        putPos.length = 0;
        clickable = false;
        delayTimer.start();
    }
        
    private function AIProcess2(event:TimerEvent = null):void
    {
        var p:Point = solve();
        var vec:Vector.<Point> = flipCheck(turn, p.x, p.y);
        put(p.x, p.y, vec, turn);
        updateCount();
        turnCount++;
        turnChange();
        passCheck();
        clickable = true;
    }
        
    private function flipCheck(color:int, x:int, y:int):Vector.<Point>
    {
        var vec:Vector.<Point> = new Vector.<Point>();
        if (board[y][x] == State.NONE)
        {
            for (var dy:int = -1; dy <= 1; dy++)
            {
                for (var dx:int = -1; dx <= 1; dx++)
                {
                    vec = vec.concat(flipCheck2(color, x, y, dx, dy));
                }
            }
        }
        
        return vec;
    }
        
    private function putSearch(color:int):void
    {
        putPos.length = 0;
        for (var y:int = 0; y < HEIGHT; y++)
        {
            for (var x:int = 0; x < WIDTH; x++)
            {
                if (flipCheck(color, x, y).length != 0)
                {
                    putPos.push(new Point(x, y));
                }
            }
        }
    }
    
    private function passCheck():void
    {
        putSearch(turn);
        draw();
        if (putPos.length == 0)
        {
            turnChange();
            putSearch(turn);
            turnChange();
            
            if (putPos.length == 0)
            {
                gameOver();
            }
            else
            {    
                putPos.length = 0;
                passButton.label = (turn == State.BLACK) ? "Black PASS" : "White PASS";
                passButton.visible = true;
            }
        }
        else
        {
            if (turn == aiColor) AIProcess();
        }
    }
    
    private function gameOver():void
    {
        draw();
        var text:String = (whiteCount == blackCount) ? "draw" : (whiteCount > blackCount) ? "White Win" : "Black Win";
        var label:Label = new Label(this, 300, 200, text);
        label.scaleX = label.scaleY = 2;
    }
        
    private function flipCheck2(color:int, x:int, y:int, dx:int, dy:int):Vector.<Point>
    {
        var vec:Vector.<Point> = new Vector.<Point>();
        
        while (true)
        {
            x += dx;
            y += dy;
            
            if (!onBoard(x, y) || board[y][x] == State.NONE)
            {
                vec.length = 0;
                break;
            }
            if (board[y][x] == color) break;
            vec.push(new Point(x, y));
        }
        
        return vec;
    }
        
    private function onBoard(x:int, y:int):Boolean
    {
        if (x < 0 || WIDTH  <= x) return false;
        if (y < 0 || HEIGHT <= y) return false;
        
        return true;
    }
    
    private function turnChange():void
    {
        if (turn == State.BLACK) turn = State.WHITE;
        else turn = State.BLACK;
    }
    
    private function put(x:int, y:int, vec:Vector.<Point>, color:int):void
    {
        board[y][x] = color;
        for each (var p:Point in vec)
        {
            if (board[p.y][p.x] == State.BLACK) board[p.y][p.x] = State.WHITE;
            else board[p.y][p.x] = State.BLACK;
        }
    }
    
    private function updateCount():void
    {
        blackCount = whiteCount = 0;
        for (var y:int = 0; y < HEIGHT; y++)
        {
            for (var x:int = 0; x < WIDTH; x++)
            {
                if (board[y][x] == State.BLACK) blackCount++;
                else if (board[y][x] == State.WHITE) whiteCount++;
            }
        }
    }
        
    private function solve(turnAI:Boolean = true, depth:int = 0, prevPass:Boolean = false):*
    {
        var score:int;
        var highScorePoint:Point = new Point();
        
        if (depth == DEPTH_MAX) return getScore();
        if (turnAI) score = int.MIN_VALUE;
        else score = int.MAX_VALUE;
        
        for (var y:int = 0; y < HEIGHT; y++)
        {
            for (var x:int = 0; x < WIDTH; x++)
            {
                var vec:Vector.<Point> = flipCheck(turn, x, y);
                if (vec.length != 0)
                {
                    put(x, y, vec, turn);
                    turnChange();
                    
                    var childScore:int = solve(!turnAI, depth + 1);
                    if (turnAI)
                    {
                        if (childScore > score)
                        {
                            score = childScore;
                            highScorePoint.x = x;
                            highScorePoint.y = y;
                        }
                    }
                    else
                    {
                        if (childScore < score)
                        {
                            score = childScore;
                            highScorePoint.x = x;
                            highScorePoint.y = y;
                        }
                    }
                    
                    put(x, y, vec, State.NONE);
                    turnChange();
                }
            }
        }
        
        if (depth == 0) return new Point(highScorePoint.x, highScorePoint.y);
        else if (score != int.MIN_VALUE && score != int.MAX_VALUE) return score;
        else if (prevPass) return getScore();
        else
        {
            turnChange();
            score = solve(!turn, depth + 1, true);
            turnChange();
            
            return score;
        }
    }
    
    private function getScore():int
    {
        var score:int = 0;

        if (turnCount > END_GAME) score += getPieceNumScore();
        else
        {
            score += getTableScore();
            score += getPutNumScore();
        }
        
        return score;
    }
    
    private function getTableScore():int
    {
        var score:int = 0;
        for (var y:int = 0; y < HEIGHT; y++)
        {
            for (var x:int = 0; x < WIDTH; x++)
            {
                if (board[y][x] == aiColor) score += SCORE_TABLE[y][x];
                else if (board[y][x] != State.NONE) score -= SCORE_TABLE[y][x];
            }
        }
        
        return score;
    }
    
    private function getPutNumScore():int
    {
        putSearch(aiColor);
        var score:int = putPos.length * 3;
        putPos.length = 0;
        return score;
    }
    
    private function getPieceNumScore():int
    {
        updateCount();
        if (aiColor == State.BLACK) return blackCount - whiteCount;
        else return whiteCount - blackCount;
    }
    
    private function draw():void
    {
        graphics.clear();
        countLabel.text = "Black " + blackCount + " : White " + whiteCount;
        
        for (var y:int = 0; y < HEIGHT; y++)
        {
            for (var x:int = 0; x < WIDTH; x++)
            {
                var tx:int = x * SIZE;
                var ty:int = y * SIZE;
                
                graphics.lineStyle(1.0);
                graphics.beginFill(0xA0C000);
                graphics.drawRect(tx, ty, SIZE, SIZE);
                graphics.endFill();
                
                if (board[y][x] == State.NONE) continue;
                
                graphics.beginFill(Color.LIST[board[y][x]]);
                graphics.drawCircle(tx + SIZE / 2, ty + SIZE / 2, SIZE / 3);
                graphics.endFill();
            }
        }
        
        if (turn == aiColor) return;
        for each (var p:Point in putPos)
        {
            tx = p.x * SIZE;
            ty = p.y * SIZE;
            graphics.beginFill(0x008000, 1.0);
            graphics.drawRect(tx, ty, SIZE, SIZE);
            graphics.endFill();
        }
    }
}

class State
{
    public static const NONE:int = 0;
    public static const BLACK:int = 1;
    public static const WHITE:int = 2;
}

class Color
{
    public static const LIST:Array = [0, 0x0, 0xFFFFFF];
}