胡牌算法

2006-10-10 17:30:30 麻将 Views(1244)

网上找了半天,有说用三叉搜索树,深度优先递归搜索,太麻烦,不懂,网上找了个简单的:
http://www.lwfb.cn/show.aspx?id=9159&cid=18

然后自己写的代码:
import java.util.Random;

public class MajianaHu {

     //pai数组 一维存储类型,二维的[0]存储个数,[i]存储第i个牌的个数
     //paiForAnay数组 存储14个牌的转化后的值
     private int pai[][]; //麻将的牌
     private int paiForAnay[];

     public static void main(String[] args) {
           MajianaHu m = new MajianaHu();
           //m.set();
           m.anotherSet();
           m.PaiToSequence();
           m.print();
     }

     public MajianaHu() {
           pai = new int[5][10];
           paiForAnay = new int[15];
     }

     //三个牌是否为顺
     public boolean IsShun(int first, int secend, int third) {
           if (first >= 30) {
                 return false;
           }
           return ((third == (secend + 1)) && (secend == (first + 1)));
     }

     //三个牌是否为刻
     public boolean IsKe(int first, int secend, int third) {
           return (first == secend && secend == third);
     }

     //两个牌是否为将
     public boolean IsJiang(int first, int secend) {
           return first == secend;
     }

     //判断是否胡牌,普通判断,不包括一些特殊情况
     //算法:1 先找将 然后去将 2遍历 判断是否有刻 3遍历 是否有顺
     public boolean IsHuCommon() {
           for (int i = 0; i < 4; i++) {
                 switch (pai[i][0] % 3) {
                 case 0: //
                       break;
                 case 1: //不够成胡牌条件
                       return false;
                 case 2: //有将
                       //去降分析
                       if (RemoveJiangAnalyse(i)) {
                             return true;
                       }
                       break;
                 }
           }
           return false;
     }

     //去将分析
     public boolean RemoveJiangAnalyse(int pos) {
           for (int i = 1; i < 10; i++) {
                 if (pai[pos][i] >= 2) {
                       //先排序
                       PaiToSequence();
                       //去将
                       RemoveJiang(pos, i);
                       //分析剩下的
                       if (DeepAnalyse()) {
                             return true;
                       }
                 }
           }
           return false;
     }

     //去掉将,方便以后的分析
     public void RemoveJiang(int pos, int pos2) {
           int num = pos * 10 + pos2;
           for (int i = 1; i <= paiForAnay[0]; i++) {
                 if (paiForAnay[i] == num) {
                       //删除
                       int length = paiForAnay[0] - i - 1;
                       int temp[] = new int[length];
                       System.arraycopy(paiForAnay, i + 2, temp, 0, length);
                       System.arraycopy(temp, 0, paiForAnay, i, length);
                       paiForAnay[0] -= 2;
                       break;
                 }
           }
     }

     //根据pai数组对paiForAnay数组排序
     public void PaiToSequence() {
           int total = 0;
           for (int i = 0; i < 4; i++) {
                 for (int j = 1; j < 10; j++) {
                       for (int k = 0; k < pai[i][j]; k++) {
                             total++;
                             paiForAnay[total] = i * 10 + j;
                       }
                 }

           }
           paiForAnay[0] = total;
     }

     //分析去将后的牌
     public boolean DeepAnalyse() {
           int i = 1;
           while (i < paiForAnay[0]) {
                 if (IsKe(paiForAnay[i], paiForAnay[i + 1], paiForAnay[i + 2])) {
                       i += 3;
                 } else if (IsShun(paiForAnay[i], paiForAnay[i + 1],
                                            paiForAnay[i + 2])) {
                       i += 3;
                 } else {
                       return false;
                 }
           }
           return true;
     }

     public void set() {
           Random r = new Random();
           int pos, pos2;
           for (int i = 0; i < 14; i++) {
                 do {
                       pos = r.nextInt(4);
                       pos2 = r.nextInt(9) + 1;
                 } while (pai[pos][pos2] > 3);
                 pai[pos][pos2]++;
           }
     }

     public void anotherSet() {
           for (int i = 2; i < 9; i++) {
                 pai[0][i] = 1;
           }
           pai[0][0] = 14;
           pai[0][1] = 3;
           pai[0][9] = 3;

           Random r = new Random();
           pai[0][r.nextInt(9) + 1]++;
     }

     public void print() {
           for (int i = 0; i < 15; i++) {
                 System.out.print(paiForAnay[i]);
                 System.out.print("\t");
           }
           System.out.println();
           System.out.print("Is win:");
           System.out.print(IsHuCommon());
     }
}

貌似可行。

Comments

Zebra

赢钱的机会大点了

2006-10-11 08:06:21
guest

很好 正需要这东西 谢谢了

2009-06-12 14:53:13

Leave a Comment

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