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

swf参加型(?)の白黒ゲーム(Reversi)

あなたの作ったプレイヤーのswfで白黒ゲーム(Reversi)を行うことができます。
ローカルswfボタンでローカルのswfを読み込めます。
プレイヤーのswfのサンプルは
http://programmingatelier.net/flex4_51/flex4_5105.html
にあります。
コンパイルの確認は「FlashDevelop 3.3. RTM」です。

画面のきれい・強さは無視しています。
別の人が作成したswfと白黒ゲーム(Reversi)ができるかの確認用です。
Get Adobe Flash player
by hi.kurosawa 22 Apr 2011
    Embed
/**
 * Copyright hi.kurosawa ( http://wonderfl.net/user/hi.kurosawa )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/8wXl
 */

package {
    //------------------------------------------
    //黒白ゲーム(Reversi)
    // プレイヤーは自動1(左上から検索)、人間のクラス
    // ローカル、サーバーのSWF読み込み
    // URL:http://programmingatelier.net/
    //------------------------------------------
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.text.TextField;
    import flash.text.TextFieldType;
    import flash.text.TextFieldAutoSize;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.IOErrorEvent;
    import flash.net.FileReference;
    import flash.display.Loader;
    import flash.net.URLLoader;
    import flash.net.FileFilter;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    import flash.system.Security;
    
    public class ReversiclsPlayer extends Sprite {
        public var PlayerSel:Sprite;

        public var pl1:Sprite;
        public var pl2:Sprite;
        
        public var txtUrlSwf1:TextField
        public var txtUrlSwf2:TextField
        
        public var txtMess2:TextField;
        //打つプレイヤー(1:黒先行、2:白後攻)
        private var ip:int;
        //ボードクラス(ボードとルール)
        private var objBoard:clsBoard;
        //プレイヤー
        private var objPl1:clsPlayer;
        private var objPl2:clsPlayer;
        private var arrPl:Array;

        private var ladPl:int;
        private var filRef:FileReference;    //ローカルファイルのクラス
        private var ladSwf:Loader;        //読み込んだSwfの展開エリア
        private var urlLoader:URLLoader;

        public function ReversiclsPlayer():void {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
            
        private function init(e:Event = null):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            //サーバの読み込み対象
            Security.loadPolicyFile("http://programmingatelier.net/publicSwf/crossdomain.xml");
            //プレイヤーの選択エリア
            PlayerSel = new Sprite();
            addChild(PlayerSel);
            graphics.lineStyle(1, 0x000000);
            graphics.drawRect(0, 0, 450, 450);
            graphics.endFill();
            //黒(先攻)の指定
            var txtPl1:TextField = new TextField();
            txtPl1.x = 5;
            txtPl1.y = 5;
            txtPl1.text = "黒=>";
            PlayerSel.addChild(txtPl1);
            PlayerSel.addChild(fncTextButton(35,5,30,20,"人間",fncPl1Man));
            PlayerSel.addChild(fncTextButton(70,5,40,20,"自動1",fncPl1Con1));
            PlayerSel.addChild(fncTextButton(115,5,70,20,"ローカルswf",fncPl1Loc));
            //ローカルから読み込み
            PlayerSel.addChild(fncTextButton(190, 5, 60, 20, "サーバswf", fncPl1Url));
            //サーバから読み込み
            txtUrlSwf1 = fncTextInput(250, 5, 195, 20, 
                "http://programmingatelier.net/publicSwf/Reversi/PlCon2.swf");
            PlayerSel.addChild(txtUrlSwf1);
            
            //しろ(後攻)の指定
            var txtPl2:TextField = new TextField();
            txtPl2.x = 5;
            txtPl2.y = 30;
            txtPl2.text = "白=>";
            PlayerSel.addChild(txtPl2);
            PlayerSel.addChild(fncTextButton(35,30,30,20,"人間",fncPl2Man));
            PlayerSel.addChild(fncTextButton(70,30,40,20,"自動1",fncPl2Con1));
            //ローカルから読み込み
            PlayerSel.addChild(fncTextButton(115,30,70,20,"ローカルswf",fncPl2Loc));
            //サーバから読み込み
            PlayerSel.addChild(fncTextButton(190,30,60,20,"サーバswf",fncPl2Url));
            txtUrlSwf2 = fncTextInput(250, 30, 195, 20, 
                "http://programmingatelier.net/publicSwf/Reversi/PlCon2.swf");
            PlayerSel.addChild(txtUrlSwf2);
            
            //開始
            PlayerSel.addChild(fncTextButton(5,55,40,20,"開 始",fncRun));

            
            //iSelPl0 = 0;
            //iSelPl1 = 0;
            //打った位置と結果の表示            
            txtMess2 = new TextField();
            addChild(txtMess2);
            txtMess2.x = 300;
            txtMess2.y = 80;
            txtMess2.width = 150;
            txtMess2.height = 370;
            txtMess2.border = true;
            txtMess2.multiline = true;
            //盤
            objBoard = new clsBoard();
            addChild(objBoard);
            objBoard.x = 0;
            objBoard.y = 120;
            //選択されたプレイヤー
            pl1=new Sprite();
            pl2=new Sprite();
            addChild(pl1);
            addChild(pl2);
            pl1.x = 0;
            pl1.y = 80;
            pl2.x = 0;
            pl2.y = 400;
            pl1.graphics.lineStyle(1, 0x0000ff);
            pl1.graphics.drawRect(0, 0, 300, 50);
            pl1.graphics.endFill();
            pl2.graphics.lineStyle(1, 0x0000ff);
            pl2.graphics.drawRect(0, 0, 300, 50);
            pl2.graphics.endFill();
            arrPl = new Array(null, null);
            //開始待ち
            fncNect();
            
        }
        //TextFieldをボタンのように使う
        public function fncTextButton(x:int, y:int, w:int, h:int, 
                    strText:String, fnc:Function):TextField {
            var txtFil:TextField = new TextField();
            txtFil.addEventListener(MouseEvent.CLICK, fnc);
            txtFil.x = x;
            txtFil.y = y;
            txtFil.width = w;
            txtFil.height = h;
            txtFil.border = true;
            txtFil.text = strText;
            txtFil.background = true;
            txtFil.backgroundColor = 0xeeeeee;
            return txtFil;
        }
        //入力エリア(swfのURLを指定)
        public function  fncTextInput(x:int, y:int, w:int, h:int, 
                    strText:String):TextField {
            var txtInput:TextField = new TextField();
            txtInput.type = TextFieldType.INPUT;
            txtInput.x = x;
            txtInput.y = y;
            txtInput.width = w;
            txtInput.height = h;
            txtInput.border = true;
            txtInput.text = strText;
            return txtInput;
        }

        //開始待ち
        public function fncNect():void {
            PlayerSel.alpha = 1;
        }
        //プレイヤーの読み込み(黒)
        public function fncPl1Man(e:MouseEvent):void {
            if (PlayerSel.alpha != 1) { return;}
            while (pl1.numChildren) pl1.removeChildAt(0);
            objPl1 = new clsPlMan();
            pl1.addChild(objPl1);
            arrPl[0] = objPl1;
            arrPl[0].setColor(clsRevCom.getFirstPlayer(),
                    objBoard.chkIti, objBoard.masuJyoutai,
                    objBoard.getRireki,objBoard.Kekka);
        }
        public function fncPl1Con1(e:MouseEvent):void {
            if (PlayerSel.alpha != 1) { return;}
            while (pl1.numChildren) pl1.removeChildAt(0);
            objPl1 = new clsPlCon1();
            pl1.addChild(objPl1);
            arrPl[0] = objPl1;
            arrPl[0].setColor(clsRevCom.getFirstPlayer(),
                    objBoard.chkIti, objBoard.masuJyoutai,
                    objBoard.getRireki,objBoard.Kekka);
        }
        public function fncPl1Loc(e:MouseEvent):void {
            if (PlayerSel.alpha != 1) { return; }
            onPlLoc(1);
            
        }
        public function fncPl1Url(e:MouseEvent):void {
            if (PlayerSel.alpha != 1) { return; }
            if (txtUrlSwf1.text=="") { return; }
            onPlUrl(1,txtUrlSwf1.text);
        }
        //プレイヤーの読み込み(白)
        public function fncPl2Man(e:MouseEvent):void {
            if (PlayerSel.alpha != 1) { return;}
            while (pl2.numChildren) pl2.removeChildAt(0);
            objPl2 = new clsPlMan();
            pl2.addChild(objPl2);
            arrPl[1] = objPl2;
            arrPl[1].setColor(clsRevCom.getOtherPlayer(clsRevCom.getFirstPlayer()),
                    objBoard.chkIti, objBoard.masuJyoutai,
                    objBoard.getRireki,objBoard.Kekka);
        }
        public function fncPl2Con1(e:MouseEvent):void {
            if (PlayerSel.alpha != 1) { return;}
            while (pl2.numChildren) pl2.removeChildAt(0);
            objPl2 = new clsPlCon1();
            pl2.addChild(objPl2);
            arrPl[1] = objPl2;
            arrPl[1].setColor(clsRevCom.getOtherPlayer(clsRevCom.getFirstPlayer()),
                    objBoard.chkIti, objBoard.masuJyoutai,
                    objBoard.getRireki,objBoard.Kekka);
        }
        public function fncPl2Loc(e:MouseEvent):void {
            if (PlayerSel.alpha != 1) { return; }
            onPlLoc(2);
        }
        public function fncPl2Url(e:MouseEvent):void {
            if (PlayerSel.alpha != 1) { return; }
            if (txtUrlSwf2.text=="") { return; }
            onPlUrl(2,txtUrlSwf2.text);
        }
        
        //ローカルSwfの読み込み================================================
        public function onPlLoc(plno:int):void {
            ladPl = plno;
            // イベント登録
            filRef = new FileReference();
            filRef.addEventListener(Event.SELECT, onFileSelect);

            // ファイル選択ダイアログを表示...
            var swfTypes:FileFilter;
            swfTypes = new FileFilter("swfファイル(*.swf)", "*.swf");
            filRef.browse(new Array(swfTypes));    
        }
        //読み込みSWFファイル選択
        private function onFileSelect(e:Event):void {
            // イベントリスナー登録...
            filRef.addEventListener(Event.COMPLETE, onFileComplete);
            filRef.addEventListener(IOErrorEvent.IO_ERROR, onFileLoadErr);
            filRef.load();
        }
        //読み込み完了、SWFを展開
        private function onFileComplete(e:Event):void {
            ladSwf = new Loader;
            // イベント登録
            ladSwf.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
            ladSwf.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onLoadError);
            ladSwf.loadBytes(filRef.data);
        }
        private function onFileLoadErr(e:IOErrorEvent):void {
            fncMess2Clear();
            fncMess2Set("ローカルのSWFの読込\n失敗しました。");
        }
        //イメージを展開完了
        private function onLoadComplete(e:Event):void {
            if (ladPl == 1) {
                while (pl1.numChildren) pl1.removeChildAt(0);
                pl1.addChild(ladSwf);
                arrPl[0] = ladSwf.content as Object;
                arrPl[0].setColor( clsRevCom.getFirstPlayer(),
                    objBoard.chkIti, objBoard.masuJyoutai,
                    objBoard.getRireki,objBoard.Kekka);
            } else {
                while (pl2.numChildren) pl2.removeChildAt(0);
                pl2.addChild(ladSwf);
                arrPl[1] = ladSwf.content as Object;
                arrPl[1].setColor( clsRevCom.getOtherPlayer(clsRevCom.getFirstPlayer()),
                    objBoard.chkIti, objBoard.masuJyoutai,
                    objBoard.getRireki,objBoard.Kekka);
            }
        }
        private function onLoadError(e:IOErrorEvent):void {
            fncMess2Clear();
            fncMess2Set("SWFの展開に\n失敗しました。");
        }

        //サーバーのSwfの読み込み===================================
        public function onPlUrl(plno:int,urlNam:String):void {
            ladPl = plno;
            urlLoader = new URLLoader();
            urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
            urlLoader.addEventListener(Event.COMPLETE, onCompUrlLoad);
            urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onErrUrlLoad);
            urlLoader.load(new URLRequest(urlNam));
        }
        private function onCompUrlLoad(event:Event):void {
            ladSwf = new Loader;
            ladSwf.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
            ladSwf.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onLoadError);
            ladSwf.loadBytes(urlLoader.data);
        }
        private function onErrUrlLoad(e:IOErrorEvent):void {
            fncMess2Clear();
            fncMess2Set("サーバーのSWFの読込\n失敗しました。");
        }

        
        //開始ボタン
        public function fncRun(e:MouseEvent):void {
            if (PlayerSel.alpha != 1) { return; }
            if (arrPl[0] == null || arrPl[1] == null) {
                fncMess2Clear();
                fncMess2Set("指定されていない\nプレイヤーがいます。");
                return;
            }
            PlayerSel.alpha = 0.2;
            onStart();
        }
        //ゲーム開始
        public function onStart():void {
            fncMess2Clear();
            fncMess2Set("盤の初期化");
            objBoard.initDataSet();
            ip = clsRevCom.getFirstPlayer();    //先攻の指定
            //プレイヤーに打つ番を知らせる
            objBoard.fncSetFnc(arrPl[ip-1].fncRun(fncOnxy));
        }
        //駒を打つ升目が決まったときにコールする関数
        // itiNam:クリックした升目("a1"~"h8")
        public function fncOnxy(itiNam:String):void {
            var n:int = objBoard.okuIti(itiNam, ip);
            if (n > 0) {    //升目がOKか,駒を置く
                fncMess2Set(clsRevCom.getPlColNam(ip) + ":" + itiNam + ":" + (n-1) + "個変更");
                ip = clsRevCom.getOtherPlayer(ip);  //次に打つプレイヤー
            } else {
                objBoard.fncSetFnc(arrPl[ip-1].fncRun(fncOnxy));
                return;        //打てない升目を指定:同じプレイヤーが再度実行
            }
            //次に打つプレイヤーが打てる場所があるか?
            if ( objBoard.chkPlayer(ip) >0) {
                objBoard.fncSetFnc(arrPl[ip-1].fncRun(fncOnxy));
                return;
            }
            //次の次のプレイヤーが打てる場所があるか?
            ip = clsRevCom.getOtherPlayer(ip);  //次に打つプレイヤー
            if ( objBoard.chkPlayer(ip) >0) {
                objBoard.fncSetFnc(arrPl[ip - 1].fncRun(fncOnxy));
                return;
            }
            //二人とも打てる場所なし->終了
            var ip1:int = clsRevCom.getFirstPlayer();
            var ip2:int = clsRevCom.getOtherPlayer(ip1);
            var ip1n:int = objBoard.Kekka(ip1);
            var ip2n:int = objBoard.Kekka(ip2);
            var strWin:String = "引き分けです。";
            if (ip1n > ip2n) { strWin = clsRevCom.getPlColNam(ip1) + "の勝ちです。"; }
            if (ip1n < ip2n) { strWin = clsRevCom.getPlColNam(ip2) + "の勝ちです。"; }
            arrPl[0].fncEnd();    //プレイヤーに終了を知らせる
            arrPl[1].fncEnd();
            
            fncMess2Set("終了しました。" +strWin+"\n"+ clsRevCom.getPlColNam(ip1) + ":" + ip1n +
                            "/" + clsRevCom.getPlColNam(ip2) + ":" + ip2n);
            objBoard.fncSetFnc(null);
            //再開待ち
            fncNect();
        }
        //メッセージの表示
        private function fncMess2Clear():void {
            txtMess2.text = "";
        }
        private function fncMess2Set(strMess:String):void {
            txtMess2.text = strMess+"\n"+txtMess2.text;
        }

    }
}
//======================================================================
//プレイヤーの基底クラス
import flash.display.Sprite;

class clsPlayer extends Sprite {
    //コンストラクター================================================
    public function clsPlayer():void {
    }
    //プレイヤーの初期化===========================================
    // ip:プレイヤーのno(黒=1or白=2)
    // chkIti:指定升目に打てるかチェック(clsBoardの関数) 
    //        chkIti(itiNam:String, ip:int):int
    // masuJyoutai:指定位置の枡の状態(clsBoardの関数) 
    //        masuJyoutai(itiNam:String):int
    // getRireki:履歴の取得(clsBoardの関数)
    //        getRireki(no:int):Object
    // Kekka:駒数(clsBoardの関数)
    //          Kekka(ip:int):int
    public function setColor(ip:int, chkIti:Function,
            masuJyoutai:Function,
            getRireki:Function,Kekka:Function):void {
    }
    //打つ番が来たときにコールされる関数==============================
    // fRet:打つ升目が決まったとき呼ぶ関数 fncOnxy(iti:String):void
    // 戻り値:盤をクリックした時にコールされる関数
    //       (プレイヤーが人間のとき使用,不要の時null)
    //       fucClic(itiNam:String):void
    public function fncRun(fRet:Function):Function {
        return null;
    }
    //ゲーム終了===========================================
    public function fncEnd():void {
    }
    //バージョンの確認=======================================
    public function getVar():String {
        return "clsPlayer-V001.00";
    }
}

//======================================================================
//プレイヤー(左上から順番に探して最初の打てる場所に打つ)
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.utils.setTimeout;

class clsPlCon1 extends clsPlayer {
    private var colNam:String;
    private var textColNam:TextField;
    private var textMessg:TextField;
    private var fncRet:Function;
    private var okIti:String;
    private var ipNo:int;
    private var fncChkIti:Function;
    private var fncMasuJyoutai:Function;
    private var fncGetRireki:Function;
    private var fncKekka:Function;

    //コンストラクター================================================
    public function clsPlCon1():void {
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);
    }
    //初期化
    private function init(e:Event = null):void {
        removeEventListener(Event.ADDED_TO_STAGE, init);
        textColNam = new TextField();
        textColNam.autoSize = TextFieldAutoSize.LEFT;
        textColNam.width = 250;
        textColNam.wordWrap = true;
        textColNam.x = 5;
        textColNam.y = 5;
        textColNam.text = "自動で左上から探します";
        addChild(textColNam);
        textMessg = new TextField();
        textMessg.autoSize = TextFieldAutoSize.LEFT;
        textMessg.width = 250;
        textMessg.wordWrap = true;
        textMessg.x = 5;
        textMessg.y = 25;
        textMessg.text = "準備中";
        addChild(textMessg);
        // 四角形を描く (中を塗りつぶす)
        graphics.lineStyle(1, 0x0000ff);
        graphics.beginFill(0xcccccc);
        graphics.drawRect(0, 0, 300, 50);
        graphics.endFill();
    }
    //プレイヤーの初期化===========================================
    // ip:プレイヤーのno(黒=1or白=2)
    // chkIti:指定升目に打てるかチェック(clsBoardの関数) 
    //        chkIti(itiNam:String, ip:int):int
    // masuJyoutai:指定位置の枡の状態(clsBoardの関数) 
    //        masuJyoutai(itiNam:String):int
    // getRireki:履歴の取得(clsBoardの関数)
    //        getRireki(no:int):Object
    // Kekka:駒数(clsBoardの関数)
    //          Kekka(ip:int):int
    override public function setColor(ip:int, chkIti:Function,
            masuJyoutai:Function,
            getRireki:Function,Kekka:Function):void {
        ipNo=ip;
        fncChkIti=chkIti;
        fncMasuJyoutai=masuJyoutai;
        fncGetRireki = getRireki;
        fncKekka = Kekka;

        textColNam.text = clsRevCom.getPlColNam(ipNo)+"-自動で左上から探します";
        textMessg.text = "まってます。";
    }
    //打つ番が来たときにコールされる関数==============================
    // fRet:打つ升目が決まったとき呼ぶ関数 fncOnxy(iti:String):void
    // 戻り値:盤をクリックした時にコールされる関数
    //       (プレイヤーが人間のとき使用,不要の時null)
    //       fucClic(itiNam:String):void
    override public function fncRun(fRet:Function):Function {

        fncRet = fRet;
        textMessg.text = "すこし考えています。";
        okIti = "";
        //左上から順番に探して最初の打てる場所に打つ
        for (var i:int = 0; i < 8; i++) {
            for (var j:int = 0; j < 8; j++) {
                var strNam:String = clsRevCom.getYokoNam(j)+clsRevCom.getTateNam(i);
                if (fncChkIti(strNam,ipNo) >0) {
                    okIti = strNam;
                    break;
                }
            }
            if (okIti != "") { break;}
        }
        var setIDName:Number = setTimeout(fncRunOK, 1000);    //1秒後に実行
        return null;        //盤がクリックしたときの関数(何もしない)
    }
    //fncRunで見つけた升目を返す
    private function fncRunOK():void {
        textMessg.text = "まってます。";
        fncRet(okIti);
    }
    //ゲーム終了===========================================
    override public function fncEnd():void {
        var ip1n:int = fncKekka(ipNo);
        var ip2n:int = fncKekka(clsRevCom.getOtherPlayer(ipNo));
        if (ip1n > ip2n) {textMessg.text = "私の勝ちです。"; }
        else if (ip1n < ip2n) {textMessg.text = "私の負けです。"; }
        else {textMessg.text = "引き分け";}
    }
}

//======================================================================
//プレイヤー(人間)
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.events.Event;
import flash.events.MouseEvent;
import spark.components.mediaClasses.VolumeBar;

class clsPlMan extends clsPlayer {
    private var textColNam:TextField;
    private var textMessg:TextField;
    private var fncRet:Function;
    private var ipNo:int;
    private var fncChkIti:Function;
    private var fncMasuJyoutai:Function;
    private var fncGetRireki:Function;
    private var fncKekka:Function;
    //コンストラクター================================================
    public function clsPlMan():void {
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);
    }
    //初期化
    private function init(e:Event = null):void {
        removeEventListener(Event.ADDED_TO_STAGE, init);
        textColNam = new TextField();
        textColNam.autoSize = TextFieldAutoSize.LEFT;
        textColNam.width = 250;
        textColNam.wordWrap = true;
        textColNam.x = 5;
        textColNam.y = 5;
        textColNam.text = "人間です。";
        addChild(textColNam);
        textMessg = new TextField();
        textMessg.autoSize = TextFieldAutoSize.LEFT;
        textMessg.width = 250;
        textMessg.wordWrap = true;
        textMessg.x = 5;
        textMessg.y = 25;
        textMessg.text = "準備中";
        addChild(textMessg);
        // 四角形を描く (中を塗りつぶす)
        graphics.lineStyle(1, 0x0000ff);
        graphics.beginFill(0xcccccc);
        graphics.drawRect(0, 0, 300, 50);
        graphics.endFill();
    }
    //プレイヤーの初期化===========================================
    // ip:プレイヤーのno(黒=1or白=2)
    // chkIti:指定升目に打てるかチェック(clsBoardの関数) 
    //        chkIti(itiNam:String, ip:int):int
    // masuJyoutai:指定位置の枡の状態(clsBoardの関数) 
    //        masuJyoutai(itiNam:String):int
    // getRireki:履歴の取得(clsBoardの関数)
    //        getRireki(no:int):Object
    // Kekka:駒数(clsBoardの関数)
    //          Kekka(ip:int):int
    override public function setColor(ip:int, chkIti:Function,
            masuJyoutai:Function,
            getRireki:Function,Kekka:Function):void {
        ipNo=ip;
        fncChkIti=chkIti;
        fncMasuJyoutai=masuJyoutai;
        fncGetRireki=getRireki;
        fncKekka = Kekka;
        textColNam.text = clsRevCom.getPlColNam(ipNo)+"-人間です。";
        textMessg.text = "まってます。";
    }
    //打つ番が来たときにコールされる関数==============================
    // fRet:打つ升目が決まったとき呼ぶ関数 fncOnxy(iti:String):void
    // 戻り値:盤をクリックした時にコールされる関数
    //       (プレイヤーが人間のとき使用,不要の時null)
    //       fucClic(itiNam:String):void
    override public function fncRun(fRet:Function):Function {
        fncRet = fRet;
        textMessg.text = "クリックして下さい。";
        return fucClic;    //盤がクリックしたときの関数
    }
    //盤がクリックしたときの関数
    private function fucClic(itiNam:String):void {
        textMessg.text = "まってます。";
        fncRet(itiNam);
    }
    //ゲーム終了===========================================
    override public function fncEnd():void {
        var ip1n:int = fncKekka(ipNo);
        var ip2n:int = fncKekka(clsRevCom.getOtherPlayer(ipNo));
        if (ip1n > ip2n) {textMessg.text = "私の勝ちです。"; }
        else if (ip1n < ip2n) {textMessg.text = "私の負けです。"; }
        else {textMessg.text = "引き分け";}
    }
}
//======================================================================    
//黒白ゲーム(リバーシ)
//盤クラス(ボードとルール)
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.events.Event;
import flash.events.MouseEvent;

class clsBoard extends Sprite {
    //盤データ(先手黒:1、後手白:2、未配置:0、盤の外:-1)
    //initDataSet()関数を参照
    private var boardData:Array;
    //打った升目の履歴
    // {Player:プレイヤー(1,2),MasuIti:升目の名称("a1"~"h8"),KomaSuu:反転した数+1}
    private var arrRireki:Array;
    //升目のサイズ
    private const mSize:Number = 30;
    //盤をクリックしたときに呼び出す関数(クラス外部の関数を登録)
    //  func(itiNam:String):void
    //      itiNam:升目の名称("a1"~"h8")
    private var fncMouseDown:Function = null;
    
    //コンストラクター================================================
    public function clsBoard():void {
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);
    }
    //初期化
    private function init(e:Event = null):void {
        disText();
        stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
        initDataSet();
    }
    //升目の名称表示
    private function disText():void {
        var i:int;
        var textField:TextField;
        for (i = 1; i < 9; i++) {
            textField = new TextField();
            textField.autoSize = TextFieldAutoSize.LEFT;
            textField.width = 20;
            textField.wordWrap = true;
            textField.x = mSize-10;
            textField.y = mSize*i;
            textField.text = clsRevCom.getTateNam(i-1);
            addChild(textField);
            textField = new TextField();
            textField.autoSize = TextFieldAutoSize.LEFT;
            textField.width = 20;
            textField.wordWrap = true;
            textField.x = mSize*i;
            textField.y = mSize-18;
            textField.text = clsRevCom.getYokoNam(i-1);
            addChild(textField);
        }
    }

    //盤をクリックしたときに呼び出す関数の登録==============================
    public function fncSetFnc(fnc:Function):void {
        fncMouseDown = fnc;
    }
    //盤をクリックしたときの処理
    private function onMouseDown(event:MouseEvent):void {
        if(fncMouseDown==null) { return;}
        var itiX:int = mouseX / mSize;
        var itiY:int = mouseY / mSize;
        if (itiX <= 0 || itiX > 8 || itiY <= 0 || itiY > 8) { return;}
        fncMouseDown(clsRevCom.getYokoNam(itiX-1)+clsRevCom.getTateNam(itiY-1));
    }
    //盤の初期化==================================================
    public function initDataSet():void {
        var ip1:int = clsRevCom.getFirstPlayer();
        var ip2:int = clsRevCom.getOtherPlayer(ip1);
        boardData = new Array(
            new Array( -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
            new Array( -1, 0, 0, 0, 0, 0, 0, 0, 0, -1),
            new Array( -1, 0, 0, 0, 0, 0, 0, 0, 0, -1),
            new Array( -1, 0, 0, 0, 0, 0, 0, 0, 0, -1),
            new Array( -1, 0, 0, 0, ip2, ip1, 0, 0, 0, -1),
            new Array( -1, 0, 0, 0, ip1, ip2, 0, 0, 0, -1),
            new Array( -1, 0, 0, 0, 0, 0, 0, 0, 0, -1),
            new Array( -1, 0, 0, 0, 0, 0, 0, 0, 0, -1),
            new Array( -1, 0, 0, 0, 0, 0, 0, 0, 0, -1),
            new Array( -1, -1, -1, -1, -1, -1, -1, -1, -1, -1));
        arrRireki = new Array();
        disBoard();
    }

    //盤の表示(升目の名称以外)
    private function disBoard():void {
        var i:int;
        var j:int;
        var ip1:int = clsRevCom.getFirstPlayer();
        var ip2:int = clsRevCom.getOtherPlayer(ip1);

        graphics.clear();
        graphics.lineStyle(1, 0x000000);
        for (i = 0; i < 9; i++) {
            graphics.moveTo(mSize, i*mSize+mSize);
            graphics.lineTo(mSize*9, i*mSize+mSize);
            graphics.moveTo(i*mSize+mSize,mSize );
            graphics.lineTo(i*mSize+mSize,mSize*9);
        }
        
        for (i = 1; i < 9; i++) {
            for (j = 1; j < 9; j++) {
                if (boardData[i][j] == ip1) {
                    // 黒:円を描く (中を塗りつぶす)
                    graphics.lineStyle(1, 0x000000);
                    graphics.beginFill(0x000000);
                    graphics.drawCircle(mSize*i+mSize/2, mSize*j+mSize/2, mSize*0.4);
                    graphics.endFill();

                }else if (boardData[i][j] == ip2) {
                    // 白:円を描く (中を塗りつぶさない)
                    graphics.lineStyle(1, 0x000000);
                    graphics.drawCircle(mSize*i+mSize/2, mSize*j+mSize/2, mSize*0.4);
                    graphics.endFill();
                }
            }
        }
    }
    //指定升目に打てるかチェック=====================================
    // itiNam:升目の名称("a1"~"h8")
    // ip:プレイヤー(1,2)
    // 戻り値:反転する升目数+1(打った駒)、0=置けません
    public function chkIti(itiNam:String, ip:int):int {
        var intRet:int = 0;
        var itiX:int = clsRevCom.getYokoIti(itiNam)+1;
        var itiY:int = clsRevCom.getTateIti(itiNam)+1;
        if (itiX == 0 || itiY == 0) { return intRet; }
        intRet = chkItiXY(itiX, itiY, ip);
        return intRet;
    }
    // itiX,itiY:チェックする升目
    // ip:プレイヤー
    // 戻り値:反転する升目数+1(打った駒)、0=置けません
    private function chkItiXY(itiX:int,itiY:int, ip:int):int {
        var intRet:int = 0;
        var ip2:int =clsRevCom.getOtherPlayer(ip);
        //指定升目に何もない
        if (boardData[itiX][itiY] != 0) { return intRet; }
        //8方向をチェック、まず敵の色(繰り返し)、自分の色のチェックを行う
        for (var idx:int = -1; idx <= 1; idx++) {
            for (var idy:int = -1; idy <= 1; idy++) {
                if (idx != 0 || idy != 0) {
                    if (boardData[itiX+idx][itiY+idy] == ip2) {
                        var n:int = chkItiXYnext(itiX+idx, itiY+idy, idx, idy, ip,ip2);
                        if( n>0) { intRet+=n;}
                    }
                }
            }
        }
        if (intRet > 0) { intRet++;}
        return intRet;
    }
    //指定升目に打てるかチェック(再起関数)
    // itiX,itiY:チェックする升目
    // idx,idy:チェックする方向(8方向の1方向)
    // ip,ip2:自分と相手
    // 戻り値:true:配置できる
    private function chkItiXYnext(itiX:int, itiY:int, 
            idx:int, idy:int, ip:int, ip2:int):int {
        var intRet:int = 0;
        //自分の色ならOK
        if (boardData[itiX + idx][itiY + idy] == ip) { 
            intRet = 0;
        //敵の色なら次をチェック
        } else if(boardData[itiX + idx][itiY + idy] == ip2) { 
            intRet=chkItiXYnext(itiX+idx, itiY+idy, idx, idy, ip, ip2);
        } else {
            //その他(空、盤の外)ならNG
            intRet = -1;
        }
        if (intRet >= 0) { 
            intRet++;
        }
        return intRet;
    }
    //指定升目に駒を置く=====================================
    // itiNam:升目の名称("a1"~"h8")
    // ip:プレイヤー(1,2)
    // 戻り値:反転する升目数+1(打った駒)、0=置けません
    public function okuIti(itiNam:String, ip:int):int {
        var intRet:int = 0;
        var itiX:int = clsRevCom.getYokoIti(itiNam)+1;
        var itiY:int = clsRevCom.getTateIti(itiNam)+1;
        if (itiX == 0 || itiY == 0) { return intRet; }
        intRet = okuItiXY(itiX, itiY, ip);
        if (intRet>0) {
            disBoard();
            arrRireki.push({Player:ip,MasuIti:itiNam,KomaSuu:intRet});
        }
        return intRet;
    }
    // itiX,itiY:チェックする升目
    // ip:プレイヤー
    // 戻り値:反転する升目数+1(打った駒)、0=置けません
    private function okuItiXY(itiX:int,itiY:int, ip:int):int {
        var intRet:int = 0;
        var ip2:int =clsRevCom.getOtherPlayer(ip);
        if (chkItiXY(itiX, itiY, ip) ==0) { return intRet; }
        //8方向をチェックと駒を反転
        for (var idx:int = -1; idx <= 1; idx++) {
            for (var idy:int = -1; idy <= 1; idy++) {
                if (idx != 0 || idy != 0) {
                    if (boardData[itiX + idx][itiY + idy] == ip2) {
                        var n:int = setItiXYnext(itiX + idx, itiY + idy, idx, idy, ip, ip2);
                        if( n>0) { intRet+=n;}
                    }
                }
            }
        }
        //反転した駒があるとき指定場祖にお置く
        if (intRet > 0) { 
            boardData[itiX][itiY] = ip; 
            intRet++;
        }
        return intRet;
    }
    //指定升目に打てるかチェック、駒の反転(再起関数)
    // itiX,itiY:チェックする升目
    // idx,idy:チェックする方向(8方向の1方向)
    // ip,ip2:自分と相手
    // 戻り値:true:駒の反転あり
    private function setItiXYnext(itiX:int, itiY:int,
            idx:int, idy:int, ip:int, ip2:int):int {
        var intRet:int = 0;
        //自分と同じ駒ならOK
        if (boardData[itiX + idx][itiY + idy] == ip) {
            intRet = 0;
        //相手と同じなら次をチェック
        } else if (boardData[itiX + idx][itiY + idy] == ip2) { 
            intRet=setItiXYnext(itiX+idx, itiY+idy, idx, idy, ip, ip2);
        } else {
            intRet = -1;
        }
        //その他(空、盤の外)ならNG
        //OKなら戻るとき反転する
        if (intRet >= 0) { 
            boardData[itiX][itiY] = ip; 
            intRet++;
        }
        return intRet;
    }
    //指定プレーヤに打つ場所があるか=======================================
    // ip:プレイヤー
    // 戻り値:打つ場所の有(true)/無(false)
    public function chkPlayer(ip:int):Boolean {
        for (var itiX:int = 1; itiX < 9; itiX++) {
            for (var itiY:int = 1; itiY < 9; itiY++) {
                if (chkItiXY(itiX, itiY, ip) >0) { return true; }
            }
        }
        return false;
    }
    //指定プレーヤ、未配置の駒数=================================================
    // ip:プレイヤー(1,2)、0で未配置
    // 戻り値:駒数
    public function Kekka(ip:int):int {
        var kazu:int = 0;
        for (var itiX:int = 1; itiX < 9; itiX++) {
            for (var itiY:int = 1; itiY < 9; itiY++) {
                if (boardData[itiX][itiY] == ip) { kazu++;}
            }
        }
        return kazu;
    }
    //指定位置の枡の状態================================================
    // itiNam:升目の名称("a1"~"h8")
    //  戻り値:黒(1)、白(2)、未(0)、升目不正(-1)
    public function masuJyoutai(itiNam:String):int {
        var itiX:int = clsRevCom.getYokoIti(itiNam)+1;
        var itiY:int = clsRevCom.getTateIti(itiNam)+1;
        if (itiX == 0 || itiY == 0) { return -1; }
        return boardData[itiX][itiY];
    }
    //打った升目の履歴の取得=====================================================
    // no:no回前(0が一回前)の履歴を取得
    // 戻り値:履歴{Player:プレイヤー(1,2),MasuIti:升目名("a1","b5"),KomaSuu:反転した数+1}
    //      noが正しくないときnull
    public function getRireki(no:int):Object {
        var objRet:Object = null;
        if (no >= 0 && no < arrRireki.length) {
            objRet = arrRireki[arrRireki.length-no-1];
        }
        return objRet;
    }
}
//==============================================
//黒白ゲーム(リバーシ)
//共通関数
class clsRevCom {
    //枡目の名称
    static private const arrYokoName:Array = ["a", "b", "c", "d", "e", "f", "g", "h" ];
    static private const arrTateName:Array = ["1", "2", "3", "4", "5", "6", "7", "8" ];

    //升目の横方向の名称
    static public function getYokoNam(iti:int):String {
        var strRet:String = "";
        if (iti >= 0 && iti < arrYokoName.length) { strRet = arrYokoName[iti];}
        return strRet;
    }
    //升目の縦方向の名称
    static public function getTateNam(iti:int):String {
        var strRet:String = "";
        if (iti >= 0 && iti < arrTateName.length) { strRet = arrTateName[iti];}
        return strRet;
    }
    //升目の名称より横方向の位置を求める
    static public function getYokoIti(itiNam:String):int {
        var iti:int = -1;
        if (itiNam.length != 2) { return iti; }
        var s:String = itiNam.substr(0, 1);
        for (var i:int = 0; i < arrYokoName.length;i++ ) {
            if (arrYokoName[i] == s) { iti = i;}
        }
        return iti;
    }
    //升目の名称より縦方向の位置を求める
    static public function getTateIti(itiNam:String):int {
        var iti:int = -1;
        if (itiNam.length != 2) { return iti; }
        var s:String = itiNam.substr(1, 1);
        for (var i:int = 0; i < arrTateName.length;i++ ) {
            if (arrTateName[i] == s) { iti = i ;}
        }
        return iti;
    }
    //プレイヤーの色名称
    // ip:プレイヤー
    static public function getPlColNam(ip:int):String {
        if (ip == 1) { return "黒"; }
        if (ip == 2) { return "白"; }
        return "";
    }
    //最初に打つプレイヤー
    // ip:プレイヤー
    static public function getFirstPlayer():int {
        return 1;
    }
    //相手のプレイヤー
    // ip:プレイヤー
    static public function getOtherPlayer(ip:int):int {
        if (ip == 1) { return 2;}
        return 1;
    }
}