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

Reversi

Get Adobe Flash player
by flashrod 01 Jan 2010
    Embed
/**
 * Copyright flashrod ( http://wonderfl.net/user/flashrod )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/cnIQ
 */

package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;

    public class Reversi extends Sprite {
        private static const UNIT:int = 18;
        private static const ORIENTATION:Array = [[-1, -1], [0, -1], [1, -1], [-1, 0], [1, 0], [-1, 1], [0, 1], [1, 1]];
        private static const PRIORITY:Array = [[0, 6, 3, 2], [6, 5, 4, 2], [3, 4, 1, 1], [2, 2, 1, 7]];
        private static const WHITE:int = 1;
        private static const BLACK:int = 2;

        private var board:Array = [];
        private var queue:Array = [];

        /** リバーシ */
        public function Reversi() {
            for (var j:int = 0; j < 8; ++j) {
                board[j] = [];
                for (var i:int = 0; i < 8; ++i) {
                    board[j][i] = 0;
                }
            }
            put(3, 3, WHITE);
            put(3, 4, BLACK);
            put(4, 3, BLACK);
            put(4, 4, WHITE);
            // クリックした位置に黒(先手)が打つ
            stage.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void {
                i = e.localX / UNIT;
                j = e.localY / UNIT;
                if (canPut(i, j, BLACK)) {
                    place(i, j, BLACK);
                    queue.push(move);
                } else {
                    if (!search(BLACK)) {
                        queue.push(move);
                    }
                }
            });
            // 非同期処理
            addEventListener(Event.ENTER_FRAME, function(e:Event):void {
                if (queue.length > 0) {
                    queue.shift()();
                }
            });
        }

        /** 盤の外側かどうか調べます
         * @param (x,y) 調べる位置
         * @return (x,y)が盤の内側なら真
         */
        private function out(x:int, y:int):Boolean {
            return x < 0 || x > 7 || y < 0 || y > 7;
        }

        /** 白(後手)が自動的に打ちます
         */
        private function move():void {
            var v:Array = search(WHITE);
            if (v) {
                place(v[0], v[1], WHITE);
            }
        }

        /** 着手できる場所を探す
         * @param stone 石
         * @return 着手できるときは(x,y),無いときはnull
         */
        private function search(stone:int):Array {
            for (var k:int = 0; k < 7; ++k) {
                for (var j:int = 0; j < 8; ++j) {
                    for (var i:int = 0; i < 8; ++i) {
                        if (k == PRIORITY[j>3 ? 7-j : j][i>3 ? 7-i : i]) {
                            if (canPut(i, j, stone)) {
                                return [i, j];
                            }
                        }
                    }
                }
            }
            return null;
        }

        /** 指定位置に石を置けるかどうか調べます
         * @param (x,y) 指定位置
         * @param stone 石
         * @return 指定位置に石が着手できるときは真
         */
        private function canPut(x:int, y:int, stone:int):Boolean {
            if (!out(x, y) && board[y][x]==0) {
                for each (var v:Array in ORIENTATION) {
                    if (canPutV(v, x, y, stone)) {
                        return true;
                    }
                }
            }
            return false;
        }

        /** 指定位置から指定方向に石を置いてはさめるかどうか調べます
         * @param v 方向
         * @param (x,y) 指定位置
         * @param stone 石
         * @return 指定位置に石が着手できるときは真
         */
        private function canPutV(v:Array, x:int, y:int, stone:int):Boolean {
            var t:String = "";
            for (;;) {
                x += v[0];
                y += v[1];
                if (out(x, y)) {
                    break;
                }
                t += board[y][x];
            }
            return t.search(stone==WHITE ? /2+1/ : /1+2/) == 0;
        }

        /** 指定位置に石を置きます。
         * @param (x,y) 指定位置
         * @param stone 石
         */
        private function put(x:int, y:int, stone:int):void {
            queue.push(function():void {
                board[y][x] = stone;
                graphics.clear();
                graphics.lineStyle(1, 0);
                for (var j:int = 0; j < 8; ++j) {
                    for (var i:int = 0; i < 8; ++i) {
                        if (board[j][i]) {
                            graphics.beginFill(board[j][i]==BLACK ? 0x000000 : 0xFFFFFF);
                            graphics.drawCircle(i*UNIT+UNIT/2, j*UNIT+UNIT/2, UNIT/2);
                        }
                    }
                }
                for (i = 0; i < 9; ++i) {
                    graphics.moveTo(i*UNIT, 0);
                    graphics.lineTo(i*UNIT, 8*UNIT);
                    graphics.moveTo(0, i*UNIT);
                    graphics.lineTo(8*UNIT, i*UNIT);
                }
            });
        }

        /** 指定位置に石を置いて挟んだ相手の石をひっくり返します。
         * @param (x,y) 指定位置
         * @param stone 石
         */
        private function place(x:int, y:int, stone:int):void {
            put(x, y, stone);
            for each (var v:Array in ORIENTATION) {
                if (canPutV(v, x, y, stone)) {
                    for (var i:int = x, j:int = y;;) {
                        i += v[0];
                        j += v[1];
                        if (out(i, j) || board[j][i]!=(stone^3)) {
                            break;
                        }
                        put(i, j, stone);
                    }
                }
            }
        }
    }
}