java 麻将平胡算法
开始时用除将头后先除刻、再除顺,或者反过来,再判断余牌为0,但都不可能覆盖所有情况。
接着,直接用了下面这个方法:
因为有些地区麻将对将头有要求,所以将头做了参数。
/** * 有将的牌是否能胡 * * @param numList 牌数集合 * @param pairs 将头数集合(有些平胡对将头有要求,比如258) * @return 是否有可能 */ @NonNull private static Boolean getMayHu(List<Integer> numList, @NonNull TreeSet<Integer> pairs) { for (Integer n : pairs) { /*先把将头拿出*/ List<Integer> tempList = new CopyOnWriteArrayList<>(numList); tempList.remove(n); tempList.remove(n); List<List<Integer>> allMayLists = new CopyOnWriteArrayList<>();//所有可能的组合 Collections.sort(tempList); allMayLists.add(tempList); for (int i = 0; i < allMayLists.size(); i++) { List<Integer> list = allMayLists.get(i); List<Integer> shun = new ArrayList<>();//可能的顺子组合 Integer num1 = list.get(0); shun.add(num1); shun.add(num1 + 1); shun.add(num1 + 2); List<Integer> ke = new ArrayList<>();//刻子组合 ke.add(num1); ke.add(num1); ke.add(num1); if (Objects.equals(list.get(0), list.get(1)) && Objects.equals(list.get(1), list.get(2))) { if (list.containsAll(shun)) {//有可能组顺子,则去掉顺子,加到前面 List<Integer> newList = new ArrayList<>(list); newList.remove(shun.get(0)); newList.remove(shun.get(1)); newList.remove(shun.get(2)); if (newList.size() == 0) { return true; } newList.add(0, shun.get(2)); newList.add(0, shun.get(1)); newList.add(0, shun.get(0)); allMayLists.add(newList);//把顺调到第一顺序,再加入可能列表 } List<Integer> delKeList = new ArrayList<>(list); delKeList.remove(ke.get(0)); delKeList.remove(ke.get(1)); delKeList.remove(ke.get(2)); if (delKeList.size() == 0) { return true; } allMayLists.add(delKeList);//产生新的去刻再加到可能列表之后 } else if (list.containsAll(shun)) { List<Integer> delShunList = new ArrayList<>(list); delShunList.remove(shun.get(0)); delShunList.remove(shun.get(1)); delShunList.remove(shun.get(2)); if (delShunList.size() == 0) { return true; } allMayLists.add(delShunList);//产生新的去刻再加到可能列表之后 } } } return false; }
以前的是程序员的老板,现在是末路出家的程序员小白。