java麻将算法_原创干货!麻将平胡算法

/** * 手牌 * *@authorzkpursuit */public classHandCards{

/**    * 获取牌号最左边的一位数,如果牌为筒、条、万,则返回值为牌类型数值    *    *@paramcard 牌号    *@return牌号从左至右第一位数(十位数)    */    publicfinalstaticintgetCardLeftValue(intcard){

return card / 10;

}

/**    * 获取牌号最右边的一位数,如果牌为筒、条、万,则返回值为牌点数    *    *@paramcard 牌号    *@return牌号从右至左第一位数(个位数)    */    publicfinalstaticintgetCardRightValue(intcard){

return card % 10;

}

/**    * 获取牌号最左边的一位数,如果牌为筒、条、万,则返回值为牌类型数值    *    *@paramidx 牌在归类数组中的索引位置    *@return牌号从左至右第一位数(十位数)    */    publicfinalstaticintgetCardLeftValueByClusterIndex(intidx){

return idx / 10 + 1;

}

/**    * 获取牌号最右边的一位数,如果牌为筒、条、万,则返回值为牌点数    *    *@paramidx 牌在归类数组中的索引位置    *@return牌号从右至左第一位数(个位数)    */    publicfinalstaticintgetCardRightValueByClusterIndex(intidx){

return idx % 10;

}

/**    * 根据牌号取得其所在的牌归类数组中的索引    *    *@paramcard 牌号    *@return牌归类数组中的索引    */    publicfinalstaticintgetClusterIndexByCard(intcard){

int left = getCardLeftValue(card);

int right = getCardRightValue(card);

int idx = (left - 1) * 10 + right;

return idx;

}

/**    * 根据十位数和个位数确定牌在聚合数组中的索引位置    *    *@paramleftValue 十位数    *@paramrightValue 个位数    *@return聚合数组中的索引位置    */    publicfinalstaticintgetClusterIndex(intleftValue,intrightValue){

return (leftValue - 1) * 10 + rightValue;

}

/**

* 归类牌

* 数组索引 / 10 + 1 表示牌类型

* 数组索引 % 10 表示牌点数

* 数组索引位置的值表示牌数量

*/    private int[] cardClusterArray;

/**

* 起始有效的索引位置

* 第一个值不为0的索引位置

*/    private int startIndex;

/**

* 归类牌数组的有效索引位置,因为有可能后面的位置全是0

* 此索引的后续索引位置的值全部为0,即最后一个值不为0的索引位置

*/    private int lastIndex;

/**

* 所有的牌数量

*/    private int cardTotals;

/**

* 构造方法

*/    publicHandCards(){

cardClusterArray = new int[40];

startIndex = 1000;

lastIndex = -1;

cardTotals = 0;

}

/**    * 构造方法    *    *@paramcards 未归类的牌数组    */    publicHandCards(int[] cards){

this();

if (cards != null) {

setCards(cards);

}

}

/**

* 重置数据

*/    publicvoidreset(){

if (cardTotals != 0) {

int len = getClusterValidLength();

for (int i = 0; i < len; i++) {

cardClusterArray[i] = 0;

}

}

startIndex = 1000;

lastIndex = -1;

cardTotals = 0;

}

/**

* 清除数据

*/    publicvoidclear(){

reset();

}

/**    * 重置数据并以传入的牌数据再次初始化数据    *    *@paramcards 牌数据    */    publicfinalvoidsetCards(int[] cards){

reset();

for (int card : cards) {

addCard(card);

}

}

/**    * 添加num张牌    *    *@paramcard 添加的牌号    *@paramnum 添加的数量    *@returntrue添加成功;false添加失败    */    publicbooleanaddCard(intcard,intnum){

int idx = getClusterIndexByCard(card);

int lastNum = cardClusterArray[idx] + num;

if (lastNum > 4) {

return false;

}

cardClusterArray[idx] = lastNum;

if (idx > lastIndex) {

lastIndex = idx;

}

if (idx < startIndex) {

startIndex = idx;

}

cardTotals += num;

return true;

}

/**    * 添加一张牌    *    *@paramcard 牌号    *@returntrue添加成功;false添加失败    */    publicbooleanaddCard(intcard){

return addCard(card, 1);

}

/**    * 添加牌集合    *    *@paramcards 牌集合,比如 [11, 23, 33, 33, 33, 34]    *@returntrue添加成功,只要有一张添加失败则全部失败    */    publicbooleanaddCards(int... cards){

for (int card : cards) {

int idx = getClusterIndexByCard(card);

int lastNum = cardClusterArray[idx] + 1;

if (lastNum > 4) {

return false;

}

}

for (int card : cards) {

addCard(card);

}

return true;

}

/**    * 移除num张牌    *    *@paramcard 移除的牌号    *@paramnum 移除的数量    *@returntrue移除成功;false移除失败    */    publicbooleanremoveCard(intcard,intnum){

int idx = getClusterIndexByCard(card);

if (cardClusterArray[idx] < num) {

return false;

}

cardClusterArray[idx] -= num;

if (cardClusterArray[idx] == 0) {

if (idx == startIndex) {

startIndex = 1000;

for (int i = idx; i < cardClusterArray.length; i++) {

if (cardClusterArray[i] > 0) {

startIndex = i;

break;

}

}

}

if (lastIndex == idx) {

int start = startIndex;

if (start >= cardClusterArray.length) {

start = 0;

}

lastIndex = -1;

for (int i = idx; i >= start; i--) {

if (cardClusterArray[i] > 0) {

lastIndex = i;

break;

}

}

}

}

cardTotals -= num;

return true;

}

/**    * 移除一张牌    *    *@paramcard 牌号    *@returntrue移除成功;false移除失败    */    publicbooleanremoveCard(intcard){

return removeCard(card, 1);

}

/**    * 移除牌号对应的所有牌    *    *@paramcard 牌号    *@returntrue移除成功;false移除失败    */    publicbooleanremoveCardOfAll(intcard){

int num = getCardNum(card);

if (num >= 0) {

return removeCard(card, num);

}

return true;

}

/**    * 移除牌    *    *@paramcards 需要移除的牌    *@returntrue表示移除成功,只要有一张牌移除失败则整个失败    */    publicbooleanremoveCards(int... cards){

for (int card : cards) {

int idx = getClusterIndexByCard(card);

if (cardClusterArray[idx] < 1) {

return false;

}

}

for (int card : cards) {

removeCard(card);

}

return true;

}

/**    * 是否有指定的牌    *    *@paramcard 牌号    *@returntrue表示存在    */    publicbooleanhasCard(intcard){

return getCardNum(card) > 0;

}

/**    * 获取牌号对应的数量    *    *@paramcard 牌号    *@return牌号对应的数量    */    publicintgetCardNum(intcard){

int idx = getClusterIndexByCard(card);

return cardClusterArray[idx];

}

/**    * 获取归类的牌数据,整除10的索引位置为保留位,不参与任何实际运算

* 数组索引从0开始,有效长度(后面全部为0)结束

* 此数组为数据副本,其中的任何数据变动都不会改变原数组

* 数组索引 / 10 + 1 表示牌类型

* 数组索引 % 10 表示牌点数

*    *@return归类的牌数据    */    public int[] getCardClusterArray() {

int[] array = new int[getClusterValidLength()];

System.arraycopy(cardClusterArray, 0, array, 0, array.length);

return array;

}

/**    * 根据提供的索引位置获取牌数量    *    *@paramidx 牌归类数组中的索引位置    *@return牌数量    */    publicintgetCardNumByClusterIndex(intidx){

return cardClusterArray[idx];

}

/**    * 根据索引位置定位对应的牌    *    *@paramidx 归类牌数组中的索引位置    *@return-1表示找不到对应的牌,否则返回牌号    */    publicintgetCardByClusterIndex(intidx){

if (cardClusterArray[idx] <= 0) {

return -1;

}

int left = getCardLeftValueByClusterIndex(idx);

int right = getCardRightValueByClusterIndex(idx);

return left * 10 + right;

}

/**    * 归类牌数组中起始有效索引    *    *@return起始有效索引,第一个值不为0的索引位置    */    publicintgetClusterValidStartIndex(){

if (cardTotals == 0) {

return 1;

}

return startIndex;

}

/**    * 归类牌数组中最终的有效索引    *    *@return最终有效索引,其后的值全为0    */    publicintgetClusterValidEndIndex(){

return lastIndex;

}

/**    * 归类牌数组的有效长度

* 有效的起始索引到有效的最后索引之前的长度

*    *@return有效长度,因为归类数组中后面可能有很多无效的0    */    publicintgetClusterValidLength(){

return lastIndex + 1;

}

/**    * 所有牌的张数    *    *@return总张数    */    publicintgetCardTotals(){

return cardTotals;

}

/**    * 获取所有的牌数据,未归类    *    *@return未归类的牌数据,两位数的牌号数组    */    public int[] getCards() {

if (cardTotals <= 0) {

return null;

}

int len = getClusterValidLength();

int[] cards = new int[cardTotals];

int idx = 0;

for (int i = getClusterValidStartIndex(); i < len; i++) {

int left = getCardLeftValueByClusterIndex(i);

int right = getCardRightValueByClusterIndex(i);

int count = cardClusterArray[i];

int card = left * 10 + right;

for (int j = 0; j < count; j++) {

cards[idx] = card;

idx++;

}

}

return cards;

}

@Override    publicHandCardsclone(){

HandCards copy = new HandCards();

copy.cardTotals = this.cardTotals;

copy.lastIndex = this.lastIndex;

copy.startIndex = this.startIndex;

if (cardClusterArray != null) {

int[] copyCardClusterArray = new int[cardClusterArray.length];

System.arraycopy(cardClusterArray, 0, copyCardClusterArray, 0, cardClusterArray.length);

copy.cardClusterArray = copyCardClusterArray;

}

return copy;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值