flash on 2010-11-26

by kihon
♥0 | Line 215 | Modified 2010-11-26 16:00:54 | MIT License
play

ActionScript3 source code

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

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

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

class Board extends Sprite
{
    public static const WIDTH:int = 8;    // 8 * 8マス
    public static const HEIGHT:int = 8;
    public static const SIZE:int = 30;    // 1マスは30 * 30px
    
    private var board:Array;
    private var turn:int;
    private var blackCount:int = 2;
    private var whiteCount:int = 2;
    private var countLabel:Label;
    private var putPos:Vector.<Point> = new Vector.<Point>();
    private var passButton:PushButton;

    public function Board()
    {
        passButton = new PushButton(this, 300, 100, "PASS", pass);
        passButton.visible = false;

        countLabel = new Label(this, 270, 50);
        countLabel.scaleX = countLabel.scaleY = 2;

        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();
        
        addEventListener(Event.ENTER_FRAME, draw);
        addEventListener(MouseEvent.CLICK, onMouseClick);
    }
    
    private function pass(event:Event = null):void
    {
        turnChange();
        passButton.visible = false;
        passCheck();
    }

    private function passCheck():void
    {
        putSearch(turn);
        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;
            }
        }
    }
    
    private function gameOver():void
    {
        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 onMouseClick(event:MouseEvent):void 
    {
        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, turn, vec);
            turnChange();
            updateCount();
            passCheck();
        }
    }
    
    // color色の石を置ける場所を探してputPosに入れる処理
    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 turnChange():void
    {
        if (turn == State.BLACK) turn = State.WHITE;
        else turn = State.BLACK;
    }

    // board[y][x]にcolor石を置き、vecに入っているマスの色を反転する。
    private function put(x:int, y:int, color:int, vec:Vector.<Point>):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;
        }
    }
    
    // 盤面内のマスをクリックしていたらtrue, していなかったらfalse
    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 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 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 draw(event:Event = null):void
    {
        countLabel.text = "Black " + blackCount + " : White " + whiteCount;
        
        graphics.clear();
        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();
            }
        }
        
        for each (var p:Point in putPos)
        {
            tx = p.x * SIZE;
            ty = p.y * SIZE;
            graphics.beginFill(0x008000, 0.6);
            graphics.drawRect(tx, ty, SIZE, SIZE);
            graphics.endFill();
        }
    }
    
    // 石の数を数えるメソッド
    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++;
            }
        }
    }
}

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];
}