AS3 五子棋源码

BlackChessman、WhiteChessman为素材类~~


package Classes{
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	import flash.text.TextField;
	
	public class GobangDoc extends MovieClip {
		//棋盘格宽度
		private const gridsize:Number = 20;
		//棋盘格数
		private const gridnum:Number = 15;
		//没有棋子为0,黑子为1,白子为2
		private const NOTHING:uint = 0;
		private const BLACK:uint = 1;
		private const WHITE:uint = 2;
		//现在轮到哪一方出子
		private var crtSide:uint = WHITE;
		//玩家的棋子
		private var mySide:uint = WHITE;
		//对手的棋子
		private var otherSide:uint;
		//是否可以进行游戏
		private var canPlay:Boolean = false;
		//记录盘面状态的数组
		private var aGridState:Array = [];
		//记录盘面上的棋子的数组
		private var aChessmen:Array = [];
		//棋子的几种状态
		public const STWO:int = 2;//眠二
		public const FTWO:int = 4;//假活二
		public const STHREE:int = 5;//眠三
		public const TWO:int = 8;//活二
		public const SFOUR:int = 12;//冲四
		public const FTHREE:int = 15;//假活三
		public const THREE:int = 40;//活三
		public const FOUR:int = 90;//活四
		public const FIVE:int = 200;//五连
		//玩家的棋形表
		private var aPlayer:Array = [];
		//对手的棋形表
		private var aOpponent:Array = [];
		//八个方向,从左上角开始顺时针
		private var dir:Array = [[-1,-1],[0,-1],[1,-1],[1,0],[1,1],[0,1],[-1,1],[-1,0]];

		public function GobangDoc() {
			mcGameState.visible = false;
			otherSide = WHITE + BLACK - mySide;
			//初始化盘面数组
			for (var i:uint=0; i<gridnum; i++) {
				aGridState[i] = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
			}
			mcChessboard.addEventListener(MouseEvent.MOUSE_DOWN,AddMyChessman);
			btnStart.addEventListener(MouseEvent.CLICK,btnStart_Handler);
			btnReplay.addEventListener(MouseEvent.CLICK,btnReplay_Handler);
			mcSelectChessman.addEventListener(MouseEvent.MOUSE_DOWN,selectChessman);
		}
		//初始化棋盘
		private function init():void{
			btnStart.visible = false;
			for(var i:int=0;i<aChessmen.length;i++){
				mcChessboard.removeChild(aChessmen[i]);				
			}
			for (var j:uint=0; j<gridnum; j++) {
				aGridState[j] = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
			}
			aChessmen = [];
			canPlay = true;
		}
		//玩家添加棋子
		public function AddMyChessman(e:MouseEvent):void {
			//不能添加棋子的状态(棋局未开始、对方走、棋子没有落在棋盘里)
			if(!canPlay || crtSide != mySide || e.target.name != "mcChessboard") 
				return;
			if (mySide == crtSide) {
				//计算鼠标落在哪一格
				var crtx:uint = Math.floor(e.localX/gridsize);
				var crty:uint = Math.floor(e.localY/gridsize);
				//如果这一格已经有棋子就返回
				if (aGridState[crty][crtx])
					return;					
				//创建棋子
				var chessman:Chessman;
				if (mySide == BLACK) {
					chessman = new BlackChessman();
				} else {
					chessman = new WhiteChessman();
				}
				chessman.bPlayer = true;
				aGridState[crty][crtx] = mySide;
				chessman.x = (crtx + .5) * gridsize;
				chessman.y = (crty + .5) * gridsize;
				aChessmen.push(chessman);
				mcChessboard.addChild(chessman);
				checkWinner(crtx,crty,crtSide);						
				//对方走
				crtSide = WHITE + BLACK - mySide;
				//计算机走
				var opos:Array = CalculateState(crtSide);
				var cx:int = opos[0];
				var cy:int = opos[1];
				AddChessman(cx,cy);					
				checkWinner(cx,cy,crtSide);
				crtSide = mySide;
			}
		}
		
		//计算机添加棋子
		public function AddChessman(toX:int,toY:int):void {
			if(!canPlay)
				return;
			var autox:int = toX;
			var autoy:int = toY;
			var chessman:Chessman;
			if (mySide == BLACK) {
				chessman = new WhiteChessman();
			} else {
				chessman = new BlackChessman();
			}
			chessman.x = (autox + .5)*gridsize;
			chessman.y = (autoy + .5)*gridsize;
			aGridState[autoy][autox] = (BLACK + WHITE) - mySide;
			aChessmen.push(chessman);
			mcChessboard.addChild(chessman);
		}
		//评估棋盘上每一格的分值,返回得分最高的棋格坐标
		public function CalculateState(side):Array{
			var i:int,j:int,k:int;
			var otherside:int = WHITE + BLACK - side;	
			//填充玩家的棋形表和对手的棋形表
			for(i = 0;i<gridnum;i++){
				for(j = 0;j<gridnum;j++){
					if(aGridState[i][j] != NOTHING){
						aOpponent[i * gridnum + j] = {val:-1,x:j,y:i};
						aPlayer[i * gridnum + j] = {val:-1,x:j,y:i};
					}
					else{
						var v1 = getScore(aGridState,j,i,side);
						aOpponent[i * gridnum + j] = {val:v1,x:j,y:i};
						var v2 = getScore(aGridState,j,i,otherside);
						aPlayer[i * gridnum + j] = {val:v2,x:j,y:i};
					}					
				}
			}
			//取得分值最大的棋格
			var maxO:Object = sortArray(aOpponent);
			var maxP:Object = sortArray(aPlayer);
			var apos:Array = [0,0];
			if(maxO.val < maxP.val)
				apos = [maxP.x,maxP.y];
			else
				apos = [maxO.x,maxO.y];
			return apos
		}
		//检查赢家
		private function checkWinner(xp:int,yp:int,side:int){
			var str:String = (side * 11111).toString();
			var winner:int = 0;	
			var str1:String = getXLine(aGridState,xp,yp,side).join("");
			var str2:String = getYLine(aGridState,xp,yp,side).join("");
			var str3:String = getXYLine(aGridState,xp,yp,side).join("");
			var str4:String = getYXLine(aGridState,xp,yp,side).join("");
			if(str1.indexOf(str)>-1 || str2.indexOf(str)>-1 || str3.indexOf(str)>-1 || str4.indexOf(str)>-1)
				winner = side;			
			if(winner){
				doWin(winner);
			}			
		}		
		//取胜后触发的事件
		private function doWin(side:int):void{
			//现实游戏结果说明
			mcGameState.visible = true;
			//关闭棋局
			canPlay = false;
			//期盼设为半透明
			mcChessboard.alpha = .5;
			//根据玩家输赢展示不同的游戏结果
			if(side == mySide){
				mcGameState.gotoAndStop("win");
			}
			else{
				mcGameState.gotoAndStop("lose");
			}
		}
		//为数组排序的方法
		private function sortArray(arr):Object{
			var arrLen:int = arr.length;
			var ar:Array = [];
			for(var j=0;j<arrLen;j++){
				ar[j] = arr[j];
			}
			//以数字方式对"val"字段进行排序
			ar.sortOn("val",Array.NUMERIC );			
			return ar[ar.length-1];
		}
		//取得指定棋格的分数
		private function getScore(arr:Array,xp:int,yp:int,side:int):int{
			var s0:int = AnalysisLine(getXLine(arr,xp,yp,side),side);
			var s1:int = AnalysisLine(getYLine(arr,xp,yp,side),side);
			var s2:int = AnalysisLine(getXYLine(arr,xp,yp,side),side);																   
			var s3:int = AnalysisLine(getYXLine(arr,xp,yp,side),side);			
			return (s0 + s1 + s2 + s3);
		}
		
		// -- 取得游戏中的一方在指定位置左右两边5格以内的状态
		private function getXLine(aposition:Array,xp:int,yp:int,side:int):Array{
			var arr:Array = [];
			var xs:int,ys:int,xe:int,ye:int;
			//起始位置
			xs = xp - 5>0 ? xp - 5:0;
			//结束位置
			xe = xp + 5>= gridnum?gridnum:xp + 5;
			for(var i:int=xs;i<=xe;i++){
				if(i == xp)
					arr.push(side);
				else{
					arr.push(aGridState[yp][i])
				}				
			}			
			return arr;		
		}
		// | 取得游戏中的一方在指定位置上下两边5格以内的状态
		private function getYLine(aposition:Array,xp:int,yp:int,side:int):Array{
			var arr:Array = [];
			var xs:int,ys:int,xe:int,ye:int;
			//起始位置						
			ys = yp - 5>0 ? yp - 5:0;
			//结束位置
			ye = yp + 5>= gridnum?gridnum:yp + 5;
			for(var i:int=ys;i<ye;i++){
				if(i == yp)
					arr.push(side);
				else{
					arr.push(aposition[i][xp])
				}
			}			
			return arr;
		}
		// \ 取得游戏中的一方在指定位置左上右下两边5格以内的状态
		private function getXYLine(aposition:Array,xp:int,yp:int,side:int):Array{
			var arr:Array = [];
			var xs:int,ys:int,xe:int,ye:int;
			//起始位置
			xs = yp > xp ? 0 : xp - yp;
			ys = xp > yp ? 0 : yp - xp;
			//结束位置
			xe = gridnum - ys;
			ye = gridnum - xs;
			var pos:int;
			for(var i:int=0;i<(xe-xs<ye-ys?xe-xs:ye-ys);i++){				
					if(ys + i == yp && xs + i == xp){
						arr.push(side);
						pos = i;
					}
					else{
						arr.push(aposition[ys + i][ xs + i]);
					}					
			}
			arr = arr.slice(pos-4>0?pos-4:0,pos+5>arr.length?arr.length:pos+5);
			return arr;
		}
		// / 取得游戏中的一方在指定位置左下右上两边5格以内的状态
		private function getYXLine(aposition:Array,xp:int,yp:int,side:int):Array{
			var arr:Array = [];
			var xs:int,ys:int,xe:int,ye:int;
			var num:int = gridnum;
			var half:int = Math.ceil(gridnum/2);
			//起始位置
			xs = xp + yp < num?0:(xp + yp - num + 1);
			ys = xs;
			//结束位置
			xe = xp + yp >= num?num-1:(xp + yp);
			ye = xe;
			var pos:int;
			for(var i:int=0;i<(xp + yp>=num?2*num-xp-yp-1:xp+yp+1);i++){				
					if(ye - i == yp && xs + i == xp){
						arr.push(side);
						pos = i;
					}
					else
						arr.push(aposition[ye - i][ xs + i]);				
			}
			arr = arr.slice(pos-4>0?pos-4:0,pos+5>arr.length?arr.length:pos+5);
			return arr;
		}
		//评估游戏中的一方在指定位置落子后某一方向可能取得的分值
		private function AnalysisLine(aline:Array,side:int):int{
			var otherside:int =  WHITE + BLACK - side;
			//以下注释中 * 为本方棋子,o 为对方棋子,_ 为空格
			// *****
			var five:String = (side * 11111).toString();
			// _****
			var four:String = "0" + (side * 1111).toString() + "0";
			// _***_
			var three:String = "0" + (side * 111).toString() + "0";
			// _**_
			var two:String = "0" + (side * 11).toString() + "0";
			// _*_*_
			var jtwo:String = "0" + (side * 101).toString() + "0";
			// ****_
			var lfour:String = otherside.toString() + (side * 1111).toString() + "0";
			// _****
			var rfour:String = "0" + (side * 1111).toString() + otherside.toString();
			// *_***
			var l_four:String = (side * 10111).toString();
			// ***_*
			var r_four:String = (side * 11101).toString();
			// o***_
			var lthree:String = otherside.toString() + (side * 111).toString() + "0";
			// _***o
			var rthree:String = "0" + (side * 111).toString() + otherside.toString();
			// o**_
			var ltwo:String = otherside.toString() + (side * 11).toString() + "0";
			// _**o
			var rtwo:String = "0" + (side * 11).toString() + otherside.toString();
			// ***_o
			var rfthree:String = (side * 111).toString() + "0" + otherside.toString();
			// o_***
			var lfthree:String = otherside.toString() + "0" + (side * 111).toString();
			
			var str:String = aline.join("");
			var res:int;
			if(str.indexOf(five)>=0){
				res = FIVE;
				if(side == otherSide)
					res *=2;
			}
			else if(str.indexOf(four)>=0)
				res = FOUR;
			else if(str.indexOf(three)>=0)
				res = side!=mySide?THREE+4:THREE;
			else if(str.indexOf(two)>=0 || str.indexOf(jtwo)>=0 )
				res = TWO;
			else if(str.indexOf(lfour)>=0 || str.indexOf(rfour)>=0 || str.indexOf(l_four)>=0 || str.indexOf(r_four)>=0)
				res = SFOUR;
			else if(str.indexOf(lthree)>=0 || str.indexOf(rthree)>=0)
				res = STHREE;
			else if(str.indexOf(ltwo)>=0 || str.indexOf(rtwo)>=0)
				res = STWO;
			else if(str.indexOf(lfthree)>=0 || str.indexOf(rfthree)>=0)
				res = FTHREE;
			else 
				res = 0;
				
			return res;
		}		
		//开始游戏按钮触发的方法
		private function btnStart_Handler(e:MouseEvent):void{
			canPlay = true;
			if(mySide == WHITE){
				AddChessman(Math.floor(gridnum/2),Math.floor(gridnum/2));
			}
			btnStart.visible = false;
		}
		//重玩一遍按钮触发的方法
		private function btnReplay_Handler(e:MouseEvent):void{
			mcGameState.visible = false;
			mcChessboard.alpha = 1;
			init();			
			if(mySide == WHITE){
				AddChessman(Math.floor(gridnum/2),Math.floor(gridnum/2));
			}
		}
		//选择棋子按钮触发的方法
		private function selectChessman(e:MouseEvent):void{
			if(canPlay){
				mcSelectChessman.buttonMode = false;
				return;
			}else{
				mcSelectChessman.buttonMode = true;
				mySide = otherSide;
				otherSide = WHITE + BLACK - mySide;
				if(mySide == WHITE){
					mcSelectChessman.gotoAndStop("white");
				}else{
					mcSelectChessman.gotoAndStop("black");
				}
				crtSide = mySide;
			}
		}
		
	}
}



package Classes{
	import flash.display.MovieClip;
	import flash.events.*;
	
	public class Chessman extends MovieClip{
		private var inc:uint = 0;
		public var bPlayer:Boolean = false;
		public function Chessman(){			
			this.addEventListener(Event.ENTER_FRAME,twinkle);
		}
		public function twinkle(e:Event):void{			
			if(!bPlayer){
				if(inc<15){
					this.alpha = ((inc%5)/5) + .2;
					inc ++;
				}else{				
					this.removeEventListener(Event.ENTER_FRAME,twinkle);
				}
			}
		}
	}
}



源码以及素材下载地址 点击打开链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值