swf参加型(?)の白黒ゲーム(Reversi)
あなたの作ったプレイヤーのswfで白黒ゲーム(Reversi)を行うことができます。
ローカルswfボタンでローカルのswfを読み込めます。
プレイヤーのswfのサンプルは
http://programmingatelier.net/flex4_51/flex4_5105.html
にあります。
コンパイルの確認は「FlashDevelop 3.3. RTM」です。
画面のきれい・強さは無視しています。
別の人が作成したswfと白黒ゲーム(Reversi)ができるかの確認用です。
/**
* 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;
}
}