θυοιβ

ActionScript3
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Tic-Tac-Toe

Posted on 2011-05-27 00:46  ichow  阅读(188)  评论(0)    收藏  举报
Program: Flash Language: AS3 Software Used: Flash Professional CS5, FlashDevelop 3.3.4

Demo!

Source:

package
{
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;

	/**
	 * ...
	 * @author iChow
	 */
	public class Game extends MovieClip
	{
		//格子
		private static const TILES:uint = 9;
		//人數
		public var players:uint;
		//
		public var turn:uint;

		public var left:uint = 10;
		//格子線
		private var _grid:Grid = new Grid();
		private var _tiles:Array = new Array();

		private var _xlist:Array = new Array();
		private var _olist:Array = new Array();
		private var _flist:Array = new Array();
		//AI是否放置
		private var _choose:Boolean = false;
		//先手
		private var ranBegin:int;
		/*
		 * 0 1 2
		 * 3 4 5
		 * 6 7 8
		 * */
		private var _combos:Array = new Array([0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6],
											  [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]);

		public function Game(num:uint)
		{
			players = num;
			turn = 0;
			//隨機先手
			ranBegin = Math.round(Math.random() * 1);
			//添加Tile
			addTiles();
			//偵聽
			addTileListeners();
			//開始
			nextTurn();
		}
		/**
		 * 放置9個Tile和分隔線
		 */
		private function addTiles():void
		{
			for (var i:uint = 0; i < TILES; i++) {
				var _tile:Tile = new Tile();
				_tile.x = i % 3 * 100;
				_tile.y = Math.floor(i / 3) * 100;
				addChild(_tile);
				_tiles.push(_tile);
				_flist.push(_tile);
			}
			addChild(_grid);
		}
		/**
		 * 添加Tile偵聽
		 */
		private function addTileListeners():void
		{
			for (var i:uint = 0; i < _tiles.length; i++) {
				_tiles[i].addEventListener("TILE_ACVITE", nextTurn);
			}
		}
		/**
		 * 電腦下
		 */
		private function handleAI():void {
			_choose = false;
			//屏蔽
			for (var i:uint = 0; i < _flist.length; i++) {
				_flist[i].removeButtonListeners();
			}
			var time:Timer = new Timer(500, 1);
			time.addEventListener(TimerEvent.TIMER_COMPLETE, handleAIChoise);
			time.start();
		}
		/**
		 * 電腦下
		 * @param	e : 半秒後執行下那
		 */
		private function handleAIChoise(e:TimerEvent):void
		{
			var i:int;
			//先判斷放置一個沒點擊的Tile是否勝利
			for (i = 0; i < _flist.length; i++) {
				if (!_choose) {
					var ocheck:Array = _olist.concat();
					ocheck.push(_flist[i]);
					if (checkAIWin(ocheck)) break;
				}
			}
			//同
			for (i = 0; i < _flist.length; i++) {
				if (!_choose) {
					var xcheck:Array = _xlist.concat();
					xcheck.push(_flist[i]);
					if (checkAIWin(xcheck)) break;
				}
			}
			//隨機放置
			if (!_choose) {
				var tile:int = Math.floor(Math.random() * _flist.length);
				_flist[tile].showTile();
				_flist[tile].chooseTile();
			}
			//恢復Tile
			for (i = 0; i < _flist.length; i++) {
				if (!checkWin()) _flist[i].addButtonListeners();
			}
		}
		/**
		 * 判斷勝利
		 * @param	check
		 * @return
		 */
		private function checkAIWin(check:Array):Boolean
		{
			for each(var combi in _combos) {
				var win:Boolean = true;
				//循環判斷勝利條件數組是否成立
				for each(var tile:int in combi) {
					if (check.indexOf(_tiles[tile]) == -1) {
						win = false;
					}
				}
				//通過後放置勝利Tile
				if (win) {
					check[check.length - 1].showTile();
					check[check.length - 1].chooseTile();
					_choose = true;
					break;
				}
			}
			return _choose;
		}
		/**
		 * 到你嚕
		 * @param	e
		 */
		private function nextTurn(e:Event=null):void
		{
			if (!checkWin()) {
				if (e) {
					//分別放到各自數組
					if (e.currentTarget.isSet == "X") {
						_xlist.push(e.currentTarget);
					}
					if (e.currentTarget.isSet == "O") {
						_olist.push(e.currentTarget);
					}
					//移除空閒Tile
					_flist.splice(_flist.indexOf(e.currentTarget), 1);
				}
				left--;
				if (left > 0) {
					turn++;
					//判斷到誰
					if (turn % 2 == ranBegin && players == 1) handleAI();
				}else {
					//遊戲結束
					endGame();
				}
			}
		}
		/**
		 * 判斷勝利
		 * @return
		 */
		private function checkWin():Boolean
		{
			var won:Boolean = false;
			for each(var combi:Array in _combos) {
				var xwin:Boolean = true;
				var owin:Boolean = true;
				//循環判斷是否符合條件
				for each(var tile:int in combi) {
					xwin = xwin && _tiles[tile].isSet == "X";
					owin = owin && _tiles[tile].isSet == "O";
				}
				//X||O符合
				if (xwin || owin) {
					endGame(combi);
					won = true;
					break;
				}else {
					won = false;
				}
			}
			return won;
		}
		/**
		 * 遊戲結束
		 * @param	combi
		 */
		private function endGame(combi:Array = null):void
		{
			for (var i:uint = 0; i < _tiles.length; i++) {
				//移除按鈕事件
				_tiles[i].removeButtonListeners();
				//根據勝利數組現實TileE(白)
				if (combi) {
					for each(var j:int in combi) {
						if (i == j) _tiles[i].showEnd();
					}
				}
			}
			//重來
			var timer:Timer = new Timer(1500, 1);
			timer.addEventListener(TimerEvent.TIMER_COMPLETE, restart);
			timer.start();
		}
		/**
		 * 重新開始
		 * @param	e
		 */
		private function restart(e:TimerEvent):void
		{
			dispatchEvent(new Event("restart"));
		}
	}

}
胆大心细脸皮厚