actionScript3.0 麻将算法

 

代码
package
{
import flash.events.Event;
import flash.events.EventDispatcher;

public class Player extends EventDispatcher
{
public static const PLAYER_TOTAL:Number=4; // 玩家数量
public static const STANDARD_CARD_NUM:Number=16; // 玩家手牌数量

public static const GMAE_END:String="GMAE_END"; // 游戏结束事件
private var _handcardList:Array; // 玩家拥有的牌,
private var _outCardList:Array; // 玩家打出的牌
private var _showCardList:Array; // 玩家显示的牌,吃碰杠的牌
private var _position:int // 方位
private var _huaList:Array; // 花牌列表
private var _ai:Boolean; // 当前玩家是否设置为电脑AI

public function Player(pos:int, ai:Boolean)
{
_ai
=ai;
_position
=pos;
_handcardList
=[];
_showCardList
=[];
_outCardList
=[];
_huaList
=[];
}

/**
* 手牌上是否存在指定牌
*
@param card
*
@return
*/
public function hasCardInHand(card:uint):Boolean
{
return _handcardList.indexOf(card) != -1;
}

public function get handCardNum():int
{
return _handcardList.length;
}

/**
* 当前是否已经摸牌,为等待出牌状态
*/
public function get isOutCardState():Boolean
{
return handCardNum % 3 == 2;
}

/**
* 听牌检测
*
@return - 所听牌列表,如果没有听牌则返回空列表
*/
public function waitCard():Array
{
var tempArr:Array
=[];
var mahjongList:Array
=MahjongManager.MAHJONG_ALL_TYPE;
for each (var card:uint in mahjongList)
{
if (winTest(card) == 1)
{
tempArr.push(card);
}
}
return tempArr;
}

public function gameEnd():void
{
dispatchEvent(
new Event(GMAE_END));
}

/**
* 添加手牌
*
@param card
*/
public function addToHandList(card:uint):void
{
_handcardList.push(card);
dispatchEvent(
new Event(Event.CHANGE));
}

/**
* 添加用户显示的牌
*
@param card
*/
public function addToShowList(tmpArr:Array):void
{
tmpArr.sort(Array.NUMERIC);
for (var i:int=0; i < tmpArr.length; i++)
{
_showCardList.push(tmpArr[i]);
}

dispatchEvent(
new Event(Event.CHANGE));
}

/**
* 移除一个显示牌
*
@param card
*
@return
*/
public function removeFromShowList(card:uint):Boolean
{
var index:
int=_showCardList.indexOf(card);
var bo:Boolean
=false;
if (index != -1)
{

_showCardList.splice(index,
1);
bo
=true;
}
dispatchEvent(
new Event(Event.CHANGE));
return bo;
}

/**
* 移除一个手牌
*
@param card
*
@return
*/
public function removeFromHandList(card:uint):Boolean
{
var index:
int=_handcardList.indexOf(card);
var bo:Boolean
=false;
if (index != -1)
{
_handcardList.splice(index,
1);
bo
=true;
}
dispatchEvent(
new Event(Event.CHANGE));
return bo;
}


public function catchCard():uint
{
var card:uint
=MahjongManager.instance.retrieveMahjong();
while ((card & MahjongManager.MASK_COLOR) == MahjongManager.HUA)
{
_outCardList.push(card);
// 放到用户桌牌列表
_huaList.push(card);

card
=MahjongManager.instance.retrieveMahjong();
dispatchEvent(
new Event(Event.CHANGE));
}

return card;
}

/**
* 补花
*/
public function buHua():void
{
for (var i:int; i < _handcardList.length; i++)
{
var card:uint
=_handcardList[i];
if ((card & MahjongManager.MASK_COLOR) == MahjongManager.HUA)
{
_huaList.push(card);
_outCardList.push(card);
_handcardList.splice(i,
1);
var tmpCard:uint
=catchCard();
_handcardList.push(tmpCard);
buHua();
}
}

dispatchEvent(
new Event(Event.CHANGE));
}

/**
* 出牌
*
@param card
*/
public function userOutCard(card:uint):void
{
var index:
int=_handcardList.indexOf(card);
if (index != -1) // 判断手牌列表是否存在这个牌
{
_handcardList.splice(index,
1);
sortHandCard();
_outCardList.push(card);

dispatchEvent(
new Event(Event.CHANGE));
}
}

//将手里的牌排序
public function sortHandCard():void
{
_handcardList.sort(Array.NUMERIC);
}

/**
* 判断一组数字都不相等
*
@param arr
*
@return
*/
public function unequal(arr:Array):Boolean
{
var len:
int=arr.length;
for (var i:int=0; i < len; i++)
{
for (var j:int=i + 1; j < len; j++)
{
if (arr[i] == arr[j])
{
return false;
}
}
}
return true;
}

/**
* 判断一组数字都相等
*
@param arr
*
@return
*/
public function equal(arr:Array):Boolean
{
var len:
int=arr.length;
for (var i:int=1; i < len; i++)
{
if (arr[0] != arr[i])
{
return false;
}
}
return true;
}

/**
* 补杠或暗杠
*
@param card
*
@return - arr[0]:0没杠,1暗杠,2补杠 arr[1]杠牌
*/
public function privateKong(card:uint):Array
{
var arr:Array
=[0];
var handcardList:Array
=_handcardList.concat(card);
var handcardNum:
int=handcardList.length;
for (var i:int=0; i < handcardNum; i++) // 暗杠
{
for (var j:int=i; j < handcardNum; j++)
{
for (var k:int=j; k < handcardNum; k++)
{
for (var n:int=k; n < handcardNum; n++)
{
if (unequal([i, j, k, n]) && equal([handcardList[i], handcardList[j], handcardList[k], handcardList[n]]))
{
arr[
0]=1; // 暗杠
arr[1]=[handcardList[i], handcardList[i], handcardList[i]];
}
}
}
}
}

handcardList
=_showCardList;
handcardNum
=handcardList.length;
for (i=0; i < handcardNum; i++) // 补杠
{
for (j=i; j < handcardNum; j++)
{
for (k=j; k < handcardNum; k++)
{
if (k != j && k != i && i != j && handcardList[i] == card && handcardList[j] == card && handcardList[k] == card)
{
arr[
0]=2; // 补杠
arr[1]=[card, card, card];
}
}
}
}
return arr;
}

/**
* 碰杠
* 其它玩家打出一个牌,杠
*
@param card
*
@return
*/
public function pundKong(card:uint):Array
{
var handcardNum:
int=_handcardList.length;
for (var i:int=0; i < handcardNum; i++)
{
for (var j:int=i; j < handcardNum; j++)
{
for (var k:int=j; k < handcardNum; k++)
{
if (k != j && k != i && i != j && _handcardList[i] == card && _handcardList[j] == card && _handcardList[k] == card)
{
return [card, card, card];
}
}
}
}
return [];
}

// 判断指定的牌是否为风,箭,花牌
public function isFJH(card:uint):Boolean
{
var temp:Boolean
=false;
var cardType:uint
=card & MahjongManager.MASK_COLOR;
if (cardType == MahjongManager.JIAN || cardType == MahjongManager.FENG || cardType == MahjongManager.HUA)
{
temp
=true;
}
return temp;
}

/**
* 检测当前用户吃牌情况
*
@param card - 牌值
*
@return - 数组第一个元素标志后面元素可组合吃牌的个数.
*/
public function userChow(card:uint):Array
{
var mj:Array
=[];
// 风箭花不吃牌
if (!isFJH(card))
{
var handcardNum:
int=_handcardList.length;
for (var i:int=0; i < handcardNum; i++)
{
for (var j:int=i; j < handcardNum; j++)
{
if (i != j)
{
var arr:Array
=[card, _handcardList[i], _handcardList[j]];
arr.sort(Array.NUMERIC);
if (arr[2] == arr[1] + 1 && arr[2] == arr[0] + 2)
{
if (mj.length > 0) // 以下,过滤相同的吃牌
{
var temp:Array
=mj[mj.length - 1];
if (_handcardList[i] + _handcardList[j] == temp[0] + temp[1])
{
if (temp[0] == _handcardList[i] || temp[0] == _handcardList[j])
{
continue;
}
}
}
mj.push([_handcardList[i], _handcardList[j]]);
}
}
}
}
}
return mj;
}

/**
* 碰牌检测
* 有碰返回几组,否则返回0。
*
@param card -
*
@return
*/
public function userPung(card:uint):Array
{
var handcardNum:
int=_handcardList.length;

for (var i:int=0; i < handcardNum; i++)
{
for (var j:int=i; j < handcardNum; j++)
{
if (i != j && _handcardList[i] == card && _handcardList[j] == card)
{
return [card, card];
}
}
}
return [];
}

/**
* 找闲牌
*/
public function searchIdleCard():uint
{
var handcardNum:
int=_handcardList.length; // 手牌的个数
var tempArr:Array=_handcardList.slice(0, handcardNum);
// 找相同的三个牌
for (var i:int=0; i < handcardNum; i++)
{
for (var j:int=i; j < handcardNum; j++)
{
for (var n:int=j; n < handcardNum; n++)
{
if (i != j && j != n && i != n && tempArr[i] == tempArr[j] && tempArr[j] == tempArr[n] && tempArr[i] > 0)
{
tempArr[i]
=-4;
tempArr[j]
=-4;
tempArr[n]
=-4;
}
}
}
}

// 找顺子
for (i=0; i < handcardNum; i++)
{
// 风箭花不吃牌
if (tempArr[i] < 0)
continue;
if (isFJH(tempArr[i]))
{
continue;
}

for (j=i; j < handcardNum; j++)
{
for (n=j; n < handcardNum; n++)
{
if (i != j && j != n && i != n && tempArr[i] > 0 && tempArr[j] > 0 && tempArr[n] > 0)
{
var arr:Array
=[tempArr[i], tempArr[j], tempArr[n]];
arr.sort(Array.NUMERIC);
if (arr[2] == arr[1] + 1 && arr[2] == arr[0] + 2)
{
tempArr[i]
=-3;
tempArr[j]
=-3;
tempArr[n]
=-3;
}
}
}
}
}
// 找两个相同的
for (i=0; i < handcardNum; i++)
{
for (j=i; j < handcardNum; j++)
{
if (i != j && tempArr[i] > 0 && tempArr[j] > 0)
{
if (tempArr[i] == tempArr[j])
{
tempArr[i]
=-2;
tempArr[j]
=-2;
}
}
}
}
// 找两个相邻的牌
for (i=0; i < handcardNum; i++)
{
// 风箭花不吃牌
if (tempArr[i] < 0)
continue;
if (isFJH(tempArr[i]))
{
continue;
}

for (j=i; j < handcardNum; j++)
{
if (i != j && tempArr[i] > 0 && tempArr[j] > 0)
{
if (tempArr[i] == tempArr[j] + 1 || tempArr[j] == tempArr[i] + 1)
{
tempArr[i]
=-1;
tempArr[j]
=-1;
}
}
}
}
var index:
int=0;
for (i=1; i < handcardNum; i++)
{
if (tempArr[i] > tempArr[index])
{
index
=i;
}
}
return _handcardList[index];
}


/**
* 胡牌检测
* 基本形胡牌 11,123,111,123,111
*
@param handcardList - 玩家拥有牌列表(包括吃碰杠牌)
*
@param handcardNum - 玩家手牌张数(不包括吃碰杠牌);
*
@return - 返回0为未胡,胡牌返回1.
*/
public function winTest(card:uint=0):int
{
var result:
int=0;
var eye:
int=0; // 将眼的个数
var abc:int=0; // 顺和三条的个数
var ja:Array=[]; // 将眼A的位置.
var jb:Array=[]; // 将眼B的位置.

var testList:Array
=_handcardList.concat();
testList.push(card);
var handcardNum:
int=testList.length; // 手牌数量
var mj:Array=testList.concat();

for (var i:int=0; i < handcardNum; i++)
{
for (var j:int=i; j < handcardNum; j++)
{
if (i != j && mj[i] == mj[j] && mj[i] != -1) // 找出所有两张相同的牌
{
ja[eye]
=i;
jb[eye]
=j;
mj[i]
=-1;
mj[j]
=-1;
eye
++
}
}
}
for (var k:int=0; k < eye; k++)
{
// 除去将眼,先查找三个两同的牌
mj=testList.concat();
mj[ja[k]]
=-1;
mj[jb[k]]
=-1;
abc
=0;

searchThree();
searchStraight();

if (abc == int(handcardNum / 3))
{
result
=1; // 符合和牌牌型
break;
}

mj
=testList.concat();
mj[ja[k]]
=-1;
mj[jb[k]]
=-1;
abc
=0;

searchStraight();
searchThree();

if (abc == int(handcardNum / 3))
{
result
=1;
break;
}
}
return result;


function searchThree():
void
{
for (i=0; i < handcardNum; i++)
{
for (j=i; j < handcardNum; j++)
{
for (var n:int=j; n < handcardNum; n++)
{
if (i != j && j != n && i != n && mj[i] == mj[j] && mj[j] == mj[n] && mj[i] != -1)
{
abc
+=1;
mj[i]
=-1;
mj[j]
=-1;
mj[n]
=-1;
}
}
}
}
}

function searchStraight():
void
{
for (i=0; i < handcardNum; i++)
{
// 风箭花不吃牌
if (mj[i] == -1)
continue;
if (isFJH(mj[i]))
{
continue;
}

for (j=i; j < handcardNum; j++)
{
for (var n:int=j; n < handcardNum; n++)
{
if (i != j && j != n && i != n && mj[i] != -1 && mj[j] != -1 && mj[n] != -1)
{
var arr:Array
=[mj[i], mj[j], mj[n]];
arr.sort(Array.NUMERIC);
if (arr[2] == arr[1] + 1 && arr[2] == arr[0] + 2)
{
abc
+=1;
mj[i]
=-1;
mj[j]
=-1;
mj[n]
=-1;
}
}
}
}
}
}
}
// end of function

public function get handcardList():Array
{
return _handcardList;
}

public function set handcardList(value:Array):void
{
_handcardList
=value;
sortHandCard();
}

public function get position():int
{
return _position;
}

public function get showCardList():Array
{
return _showCardList;
}

public function get outCardList():Array
{
return _outCardList;
}

public function get ai():Boolean
{
return _ai;
}
}
}

 

posted @ 2010-10-25 13:35  Rio·Yang  阅读(515)  评论(1编辑  收藏  举报