胡牌算法

2006-10-13 17:36:33 麻将 Views(1287)

/***************
* 检查胡牌
*/

public class CheckHu {

     //牌的情况
     int paiLiSeq[]; //未倒的牌 [0]个数,[1-N]具体的牌
     int paiDao[][]; //一维几个 二维[0],啥子情况,[1-4]具体的牌
     int codition[]; //一些特殊情况,比如海底,绝张之类

     int paiHu[][];   //一维几个,二维[0],啥子情况,[1-4]具体的牌

     static final int PAI_DAO_GANG = 0;
     static final int PAI_DAO_PENG = 1;
     static final int PAI_DAO_CHI = 2;
     static final int PAI_LI_KE = 3;
     static final int PAI_LI_SHUN = 4;
     static final int PAI_LI_JIANG = 5;

     public CheckHu() {
     }

     public void CheckHu(int aryLi[], int aryDao[][], int aryCond[]) {
           paiLiSeq = aryLi;
           paiDao = aryDao;
           codition = aryCond;
     }

     public void CheckHu(int aryHu[][],int aryCond[]){
           paiHu = aryHu;
           codition = aryCond;
     }

     //初始化数据
     public void Init(){
           //初始化paiLiSeq数组
           paiLiSeq = new int[14];
           for (int i=0; i

           }

           //初始化paiDao数组
           int dao = 0;
           int j=0;
           for (int i=0; i< paiHu.length; i++){
                 if (((paiHu[i][0]>=PAI_DAO_GANG) && (paiHu[i][0]<=PAI_DAO_CHI))){
                       dao++;
                 }
           }
           paiDao = new int[dao][5];
           for (int i=0; i< paiHu.length; i++){
                 if (((paiHu[i][0]>=PAI_DAO_GANG) && (paiHu[i][0]<=PAI_DAO_CHI))){
                       System.arraycopy(paiHu[i],0,paiDao[j],0,5);
                       j++;
                 }
           }

     }

     public void SetPaiLi(int ary[]) {
           //paiLi = new int[ary.length];
           paiLiSeq = ary;
     }

     public void SetPaiDao(int ary[][]) {
           paiDao = ary;
     }

     public void SetCondition(int ary[]) {
           codition = ary;
     }

     //配置文件
     int ccTotal; //规则总数
     int ccIndex[]; //规则索引
     int ccFanshu[]; //番数
     int ccRemove[][]; //满足此规则后,要排除掉的

     public void SetCheckContditionFile(int total, int index[], int fanshu[],
                                                         int remove[][]) {
           ccTotal = total;
           ccIndex = index;
           ccFanshu = fanshu;
           ccRemove = remove;
     }

     final static int MAX_CHECK_CONDITION = 36;
     //配置条件
     boolean checkCondition[] = new boolean[MAX_CHECK_CONDITION];

     public void SetCheckConditionFlag() {
           for (int i = 0; i < ccIndex.length; i++) {
                 checkCondition[ccIndex[i]] = true;
           }
     }

     int paiLiGewei[]; //未倒的牌的个位, 风,箭等不记入计算
     private void SetLiGewei() {
           paiLiGewei = new int[paiLiSeq.length];
           paiLiGewei[0] = paiLiSeq[0];
           for (int i = 1; i < paiLiGewei.length; i++) {
                 if (paiLiSeq[i] >= 30) {
                       paiLiGewei[i] = paiLiSeq[i];
                 } else {
                       paiLiGewei[i] = paiLiSeq[i] % 9;
                 }
           }
     }

     int paiLiShiwei[]; //未倒的牌的十位
     private void SetLiShiwei() {
           paiLiShiwei = new int[paiLiSeq.length];
           paiLiShiwei[0] = paiLiSeq[0];
           for (int i = 1; i < paiLiShiwei.length; i++) {
                 paiLiShiwei[i] = paiLiSeq[i] / 10;
           }
     }

     int paiDaoShiwei[]; //倒了的牌的十位
     private void SetDaoShiwei() {
           int length = paiDao.length;
           paiDaoShiwei = new int[length];
           for (int i = 0; i < length; i++) {
                 paiDaoShiwei[i] = paiDao[i][1] / 10;
           }
     }

     int paiDaoGewei[]; //倒了的牌的个位,只需要设置第一个数字,碰,扛一样,吃可以推算出来
     private void SetDaoGewei() {
           int length = paiDao.length;
           paiDaoGewei = new int[length];
           for (int i = 0; i < length; i++) {
                 if (paiDao[i][1] >= 30) {
                       paiDaoGewei[i] = paiDao[i][1];
                 } else {
                       paiDaoGewei[i] = paiDao[i][1] % 9;
                 }
           }
     }

     int paiLiGeweiNum[]; //立着的牌的个位个数
     private void SetLiGeweiNum() {
           paiLiGeweiNum = new int[9];
           for (int i = 1; i <= paiLiGewei[0]; i++) {
                 if (paiLiGewei[i] >= 0 && paiLiGewei[i] < 10) {
                       paiLiGeweiNum[paiLiGewei[i]]++;
                 }
           }
     }

     int paiLiEveryNum[][]; //立着的牌的个数
     private void SetLiEveryNum() {
           paiLiEveryNum = new int[4][9];
           for (int i = 1; i <= paiLiSeq[0]; i++) {
                 paiLiEveryNum[paiLiSeq[i] / 10][paiLiSeq[i] % 9]++;
           }
     }

     int paiHuGewei[][];
     private void SetPaiHuGewei(){
           int length = paiHu.length;
           paiHuGewei = new int[length][5];
           for (int i=0; i                  paiHuGewei[i][0] = paiHu[i][0];
                 if (paiHuGewei[i][1] >= 30){
                       paiHuGewei[i][1] = paiHu[i][1];
                       paiHuGewei[i][2] = paiHu[i][2];
                       paiHuGewei[i][3] = paiHu[i][3];
                       paiHuGewei[i][4] = paiHu[i][4];

                 }else{
                       paiHuGewei[i][1] = paiHu[i][1] % 9;
                       paiHuGewei[i][2] = paiHu[i][2] % 9;
                       paiHuGewei[i][3] = paiHu[i][3] % 9;
                       paiHuGewei[i][4] = paiHu[i][4] % 9;
                 }
           }
     }

     //检查各个算番情况
     //基本的元素检查

     //是否都是立的
     private boolean IsAllLi() {
           return paiLiSeq[0] == 14;
     }

     //立着的牌是否清一色
     private boolean IsLiQingyise() {
           if (paiLiShiwei[0] < 1) {
                 return false;
           }
           int se = paiLiShiwei[1];
           //是否有字
           if (se >= 30) {
                 return false;
           }
           //是否清一色
           for (int i = 1; i <= paiLiShiwei[0]; i++) {
                 if (paiLiShiwei[i] != se) {
                       return false;
                 }
           }
           return true;
     }

     //倒了的牌是否清一色
     private boolean IsDaoQingyise() {
           int length = paiDao.length;
           if (length < 1) {
                 return false;
           }
           int se = paiDaoShiwei[0];
           for (int i = 1; i < length; i++) {
                 if (se != paiDaoShiwei[i]) {
                       return false;
                 }
           }
           return true;
     }

     //得到立着的牌里刻的个数
     private int GetLiKeNum() {
           int re = 0;
           for (int i = 0; i < paiLiEveryNum.length; i++) {
                 for (int j = 0; j < paiLiEveryNum[i].length; j++) {
                       if (paiLiEveryNum[i][j] > 2) {
                             re++;
                       }
                 }
           }
           return re;
     }

     //得到倒的牌里刻的个数
     private int GetDaoKeNum() {
           int re = 0;
           for (int i = 0; i < paiDao.length; i++) {
                 if (paiDao[i][0] == PAI_DAO_PENG || paiDao[i][0] == PAI_DAO_GANG) {
                       re++;
                 }
           }
           return re;
     }

     //立着的牌个位是否一条龙
     private boolean IsYitiaolongSeq() {
           for (int i = 0; i < 9; i++) {
                 if (((i == 0) || (i == 8))) {
                       if (paiLiGeweiNum[i] < 3) {
                             return false;
                       }
                 } else {
                       if (paiLiGeweiNum[i] < 1) {
                             return false;
                       }
                 }
           }
           return true;
     }

     //是否一条龙 满足三个条件:都立着的,清一色,一条龙
     public boolean IsYitiaolong() {
           return (IsAllLi() && IsLiQingyise() && IsYitiaolongSeq());
     }

     //是否十八学士,只需要返回是否杠了四张
     public boolean IsShibaxueshi() {
           if (paiDao.length < 4) {
                 return false;
           }
           for (int i = 0; i < 4; i++) {
                 if (paiDao[i][0] != PAI_DAO_GANG) {
                       return false;
                 }
           }
           return true;
     }

     //是否七对 是否有碰,是否第一张都和第二张相等,增量2
     public boolean IsQidui() {
           if (!IsAllLi()) {
                 return false;
           }
           for (int i = 0; i < 14; i += 2) {
                 if (paiLiSeq[i] != paiLiSeq[i + 1]) {
                       return false;
                 }
           }
           return true;
     }

     //是否清一色 如果没有倒,检查立牌;如果有倒,立牌倒牌都要检查
     public boolean IsQingyise() {
           if (paiDao.length < 1) {
                 return IsLiQingyise();
           } else {
                 return (IsLiQingyise() && IsDaoQingyise() &&
                             (paiDao[0][1] == paiLiSeq[1]));
           }
     }

     //是否对对胡 检查刻数是否为4
     public boolean IsDuiduihu() {
           return (GetLiKeNum() + GetDaoKeNum()) == 4;
     }

     //是否亲一色对对胡
     public boolean IsQingyiseDuiduihu() {
           return (IsQingyise() && IsDuiduihu());
     }

     //是否幺牌 将必须为0或8;第一位必须为0或者最后一位必须为8
     public boolean IsYaopai(){
           //先要排除掉特殊情况
           if (paiHuGewei[0][0] > PAI_LI_JIANG)
                 return false;
           if (((paiHuGewei[0][1] != 0) && (paiHuGewei[0][1] != 8))){
                 return false;
           }
           for (int i=1; i                  if (((paiHuGewei[i][1] != 0) && (paiHuGewei[i][3] != 8))){
                       return false;
                 }
           }
           return true;
     }

     public static void main(String[] args) {

     }

}

to be continued...

Comments

Zebra

看到你一个字"胡",以为是在说我呢,哈哈!

2006-10-15 08:18:52
rui

胡了

2006-10-16 14:09:10

Leave a Comment

Name
Content
Verification Type the characters you see in the picture below