package hunan; import com.game.Global; import com.game.Util; import com.taurus.core.entity.ITArray; import com.taurus.core.entity.ITObject; import com.taurus.core.entity.TObject; import com.taurus.core.plugin.database.DataBase; import com.taurus.core.util.Logger; import com.taurus.core.util.StringUtil; import taurus.client.Message; import taurus.client.TaurusClient; import taurus.util.*; import java.sql.SQLException; import java.util.*; public class HuNanChangSha { public static int changShaCard = 0; public static boolean isTinChi = false; public static boolean isTinPeng = false; //湖南红中麻将手牌 private List changShaCardInhand = new ArrayList<>(); private List changShaCardInhandgang = new ArrayList<>(); //红中麻将出过的牌 private List changShachuguopai = new ArrayList<>(); private List gangdepai = new ArrayList<>(); //碰牌 private List pongGroup = new ArrayList<>(); //吃牌 private List chowGroup = new ArrayList<>(); // 玩家座位号 public static int seat = 0; public static int playerId = 0; public static int cardToOut1 = 0; // 会话标识 public static String session = ""; // 访问令牌 public static String token = ""; //红中麻将算法 // private static HongZhongSuanFa hongZhongSuanFa = new HongZhongSuanFa(); private static ChangShaSuanFaTest changShaSuanFaTest = new ChangShaSuanFaTest(); // 公共的getter和setter方法 public List getChangShaCardInhand() { return changShaCardInhand; } public List getgangdepai() { return gangdepai; } public List getchangShaCardInhandgang() { return changShaCardInhandgang; } // 公共的getter和setter方法 public List getpongGroup() { return pongGroup; } public List getchowGroup() { return chowGroup; } public List getChuGuoCardInhand() { return changShachuguopai; } /** * 出牌广播协议 812 * * @param command 协议号 * @param message 消息对象 * @return */ public static String drawCard(String command, Message message) { if (command.equalsIgnoreCase("812")) { ITObject param = message.param; if (param == null) { return null; } changShaCard = param.getInt("card"); } return null; } /** * 摸牌协议 819 * * @param command 协议号 * @param message 消息对象 * @return */ public String getCard(String command, Message message) { if (command.equalsIgnoreCase("819")) { ITObject param = message.param; if (param == null) { return null; } if (param.getInt("player") != null) { int drawnCard = param.getInt("card"); changShaSuanFaTest.drawnCards = drawnCard;//存储摸到的牌 changShaCardInhand.add(drawnCard); changShaSuanFaTest.analyzeHand(changShaCardInhand); } } return null; } /** * 判断是否应该碰牌 * * @param proposedCard 提议碰的牌 * @return 是否应该碰牌 */ public boolean shouldPong(int proposedCard) { // 直接调用hongZhongSuanFaTest中的shouldPong方法,它已经包含了所有需要的规则 return changShaSuanFaTest.shouldPong(proposedCard, changShaCardInhand); // return hongZhongSuanFaTest.shouldPong(proposedCard, Arrays.asList(305,304,303,207,207,204,204,208,208,201,201,412,412)); } public boolean shouldChow(int proposedCard) { return changShaSuanFaTest.shouldChow(proposedCard, changShaCardInhand); } /** * 初始化手牌协议 811 * * @param command 协议号 * @param message 消息对象 * @return */ public String cardInHead(String command, Message message, TaurusClient client) { if (command.equalsIgnoreCase("811")) { ITObject param = message.param; if (param == null) { return null; } // {bank_seat=1, laiziCard=0, laiziCard2=0, laiziCard2Before=0, jing=0, laiziCardBefore=0, card_list=[101, 103, 104, 201, 204, 207, 208, 209, 307, 309, 501, 502, 503]} ITArray cardList = param.getTArray("card_list"); for (int i = 0; i < cardList.size(); i++) { changShaCardInhand.add(cardList.getInt(i)); } // if (changShaCardInhand.size() > 13) { // outCard(client); // } } return null; } /** * 处理杠碰胡操作 * * @param param 消息参数 * @return */ public String actionCard(ITObject param, TaurusClient client) { // TinHuChi tinHuChi = new TinHuChi(); TinHuPeng tinHuPeng = new TinHuPeng(); //获取碰杠胡参数 type 和id 后续算法接入,是否能让碰和杠 ITArray tipList = param.getTArray("tip_list"); int id = 0; int type = 0; int opcard = 0; int opcard1 = 0; int card = 0; //胡牌 ITObject params = TObject.newInstance(); for (int i = 0; i < tipList.size(); i++) { TObject firstTip = (TObject) tipList.get(i).getObject(); id = firstTip.getInt("id"); type = firstTip.getInt("type"); ITArray opcard2 = firstTip.getTArray("opcard"); if (type == 6) { params.putString("session", session + "," + token); params.putInt("qi", 0); params.putInt("id", id); client.send("612", params, response -> { }); return "胡牌"; } } //吃杠 int type2 = 0; int opcard3 = 0; int id3 = 0; List gangCardInhand = new ArrayList<>(); gangCardInhand.addAll(changShaCardInhand); gangCardInhand.addAll(chowGroup); gangCardInhand.addAll(pongGroup); TingPaiChecker.TingResult tingResult = TingPaiChecker.checkTingPai(gangCardInhand); if (tingResult.isTingPai()) { //听牌状态 for (int i = 0; i < tipList.size(); i++) { TObject firstTip = (TObject) tipList.get(i).getObject(); type2 = firstTip.getInt("type"); opcard3 = firstTip.getTArray("opcard").getInt(0); id3 = firstTip.getInt("id"); boolean b = TinHuGang.canGang(gangCardInhand, opcard3, true); //杠牌后是否还能听牌 if (type2 == 3) { // int pisCardsCount = changShaSuanFaTest.countPairs(changShaCardInhand); // boolean gang = isAllSameSuitgang(changShaCardInhand, opcard3); if (b) { System.out.println("听牌 +++进入吃杠===============================------------------------------------------------"); params.putString("session", session + "," + token); params.putInt("qi", 0); params.putInt("id", id3); Util.removeCard(changShaCardInhand, opcard3, 3); client.send("612", params, response -> { }); return "吃杠"; } else { params.putString("session", session + "," + token); params.putInt("qi", 0); params.putInt("id", 0); client.send("612", params, response -> { }); } } } } else { for (int i = 0; i < tipList.size(); i++) { TObject firstTip = (TObject) tipList.get(i).getObject(); type2 = firstTip.getInt("type"); opcard3 = firstTip.getTArray("opcard").getInt(0); id3 = firstTip.getInt("id"); if (type2 == 3) { // int pisCardsCount = changShaSuanFaTest.countPairs(changShaCardInhand); // boolean gang = isAllSameSuitgang(changShaCardInhand, opcard3); // if (pisCardsCount < 5 && gang) { //不是七小对和清一色的情况下 才允许杠 // System.out.println("没有 +++ 听牌 +++进入吃杠===============================------------------------------------------------"); // // params.putString("session", session + "," + token); // params.putInt("qi", 0); // params.putInt("id", id3); // Util.removeCard(changShaCardInhand, opcard3, 3); // // client.send("612", params, response -> { // // }); // return "吃杠"; // } else { params.putString("session", session + "," + token); params.putInt("qi", 0); params.putInt("id", 0); client.send("612", params, response -> { }); } } } TingPaiChecker.TingResult tingResult1 = TingPaiChecker.checkTingPai(gangCardInhand); if (tingResult1.isTingPai()) { for (int i = 0; i < tipList.size(); i++) { TObject firstTip = (TObject) tipList.get(i).getObject(); type2 = firstTip.getInt("type"); opcard3 = firstTip.getTArray("opcard").getInt(0); id3 = firstTip.getInt("id"); boolean c = TinHuGang.canGang(gangCardInhand, opcard3, false); //杠牌后是否还能听牌 if (type2 == 4) { System.out.println("最新自杠 还没进入下面,但是类型为4自杠了==========================="); if (c) { System.out.println("听牌 +++进入自杠===============================------------------------------------------------"); System.out.println("opcard3 ++++++++++++++++++ ++++++++++888 " + opcard3); System.out.println("id3 ++++++++++++++++++ ++++++++++7777 " + id3); params.putString("session", session + "," + token); params.putInt("qi", 0); params.putInt("id", id3); Util.removeCard(changShaCardInhand, opcard3, 4); client.send("612", params, response -> { }); return "自杠"; } else { params.putString("session", session + "," + token); params.putInt("qi", 0); params.putInt("id", 0); client.send("612", params, response -> { }); } } } } else { for (int i = 0; i < tipList.size(); i++) { TObject firstTip = (TObject) tipList.get(i).getObject(); type2 = firstTip.getInt("type"); if (type2 == 4) { System.out.println("放弃自杠111======================================="); params.putString("session", session + "," + token); params.putInt("qi", 0); params.putInt("id", 0); client.send("612", params, response -> { }); } } } // for (int i = 0; i < tipList.size(); i++) { // TObject firstTip = (TObject) tipList.get(i).getObject(); // type2 = firstTip.getInt("type"); // opcard3 = firstTip.getTArray("opcard").getInt(0); // id3 = firstTip.getInt("id"); // // if (type2 == 3) { // int pisCardsCount = changShaSuanFaTest.countPairs(changShaCardInhand); // boolean gang = isAllSameSuitgang(changShaCardInhand, opcard3); // if (pisCardsCount < 5 && gang) { //不是七小对和清一色的情况下 才允许杠 // params.putString("session", session + "," + token); // params.putInt("qi", 0); // params.putInt("id", id3); // Util.removeCard(changShaCardInhand, opcard3, 3); // // client.send("612", params, response -> { // // }); // return "吃杠"; // } else { // params.putString("session", session + "," + token); // params.putInt("qi", 0); // params.putInt("id", 0); // client.send("612", params, response -> { // // }); // // } // } // } int id1 = 0; int type1 = 0; //吃牌判断 boolean b = false; //碰牌判断 boolean a = false; if (tipList.size() > 0) { TObject firstTip = (TObject) tipList.get(0).getObject(); id1 = firstTip.getInt("id"); type1 = firstTip.getInt("type"); ITArray opcard2 = firstTip.getTArray("opcard"); card = firstTip.getInt("card"); b = TinHuChi.canChi(changShaCardInhand, card); List> lists = TinHuChi.checkChi(changShaCardInhand, card); opcard = firstTip.getTArray("opcard").getInt(0); if (type1 == 1) { opcard1 = firstTip.getTArray("opcard").getInt(1); } } if (type1 == 2) { List shifoutingpai = TinHuChi.shifoutingpai(changShaCardInhand); //目前手牌没有听牌 if (shifoutingpai.size() == 0) { List temphand = new ArrayList<>(); temphand.addAll(changShaCardInhand); temphand.add(opcard); Util.removeCard(temphand, opcard, 3); List checktingpai1 = TinHuChi.checktingpai(temphand); System.out.println("checktingpai1 碰牌" + checktingpai1); if (checktingpai1.size() > 0) { System.out.println("===============进入听胡碰牌================== ++++ "); params.putString("session", session + "," + token); params.putInt("qi", 0); params.putInt("id", id1); pongGroup.add(opcard); pongGroup.add(opcard); pongGroup.add(opcard); Util.removeCard(changShaCardInhand, opcard, 2); } else { params.putString("session", session + "," + token); params.putInt("qi", 1); params.putInt("id", 0); } } //听牌的时候先不碰 if (shifoutingpai.size() > 0) { System.out.println("听牌的时候先不碰++++++++++++++++++++++++++++++++"); params.putString("session", session + "," + token); params.putInt("qi", 1); params.putInt("id", 0); } // a = tinHuPeng.canPeng(changShaCardInhand, opcard); // ChangShaSuanFaTest changShaSuanFaTest = new ChangShaSuanFaTest(); // int pisCardsCount = changShaSuanFaTest.countPairs(changShaCardInhand);//分析七小对 // boolean peng = changShaSuanFaTest.isAllSameSuit1(changShaCardInhand); // if (a && !ChangShaSuanFaTest.isTin) { // System.out.println("===============进入听胡碰牌==============================="); // // params.putString("session", session + "," + token); // params.putInt("qi", 0); // params.putInt("id", id1); // pongGroup.add(opcard); // pongGroup.add(opcard); // pongGroup.add(opcard); // Util.removeCard(changShaCardInhand, opcard, 2); // // } else { // // 根据规则判断是否应该碰牌 // if (shouldPong(opcard) && pisCardsCount < 5 && !peng && !isTinPeng) { // params.putString("session", session + "," + token); // params.putInt("qi", 0); // params.putInt("id", id1); // pongGroup.add(opcard); // pongGroup.add(opcard); // pongGroup.add(opcard); // Util.removeCard(changShaCardInhand, opcard, 2); // } else { // params.putString("session", session + "," + token); // params.putInt("qi", 1); // 放弃碰牌 // params.putInt("id", 0); // // } // } } else if (type1 == 3) { int pisCardsCount = changShaSuanFaTest.countPairs(changShaCardInhand);//分析七小对 boolean gang = changShaSuanFaTest.isAllSameSuit1(changShaCardInhand); if (pisCardsCount < 5 && !gang) { params.putString("session", session + "," + token); params.putInt("qi", 0); params.putInt("id", id1); Util.removeCard(changShaCardInhand, opcard, 3); } else { params.putString("session", session + "," + token); params.putInt("qi", 0); params.putInt("id", 0); } } else if (type1 == 1) { // int pisCardsCount = changShaSuanFaTest.countPairs(changShaCardInhand);//分析七小对 // boolean isChow = changShaSuanFaTest.isAllSameSuit1(changShaCardInhand); //判断当前手牌是否已经听牌 已经听牌了就不要再吃牌了 List shifoutingpai = TinHuChi.shifoutingpai(changShaCardInhand); //目前手牌没有听牌 if (shifoutingpai.size() == 0) { List> lists = TinHuChi.checkChi(changShaCardInhand, card); int index = 0; int flag = 0; for (List list : lists) { List temphand = new ArrayList<>(); temphand.addAll(changShaCardInhand); temphand.add(card); Util.removeCard(temphand, list.get(0), 1); Util.removeCard(temphand, list.get(1), 1); Util.removeCard(temphand, list.get(2), 1); List checktingpai1 = TinHuChi.checktingpai(temphand); if (checktingpai1.size() > 0) { flag = index + 1; } index++; System.out.println("checktingpai1 吃牌 " + checktingpai1); } // TODO: 2026/1/1 // 1.需要补充 没听牌也可以吃 但是吃之后要比吃之前的手牌强 也就是可听数量变多 // 2.听牌后也能吃牌,要比吃之前的牌强 // 3.碰也一样要加 if (flag > 0) { System.out.println("===============进入听胡吃牌================== ++++ " + flag); params.putString("session", session + "," + token); params.putInt("qi", 0); params.putInt("id", flag); int index1 = flag - 1; List integers = lists.get(index1); List result1 = getOtherCards1(integers, card); chowGroup.add(card); chowGroup.add(result1.get(0)); chowGroup.add(result1.get(1)); changShaCardInhand.add(card); Util.removeCard(changShaCardInhand, integers.get(0), 1); Util.removeCard(changShaCardInhand, integers.get(1), 1); Util.removeCard(changShaCardInhand, integers.get(2), 1); } else { Map map = new HashMap<>(); Map map2 = new HashMap<>(); //吃之前的逻辑 List tmpChangSch = new ArrayList<>(); tmpChangSch.addAll(changShaCardInhand); tmpChangSch.add(card); ChangshaWinSplitCard.checkNormalHu(tmpChangSch, map); System.out.println("checkNormalHu" + map.get("cardResiue")); List> lists1 = TinHuChi.checkChi(changShaCardInhand, card); System.out.println("checktingpai1" + lists1); int index1 = 0; int flag1 = 0; for (List list : lists1) { List temphand =new ArrayList<>(); temphand.addAll(tmpChangSch); Util.removeCard(temphand,list.get(0),1); Util.removeCard(temphand,list.get(1),1); Util.removeCard(temphand,list.get(2),1); ChangshaWinSplitCard.checkNormalHu(temphand, map2); //判断两个map是否找到更优 System.out.println("map1:"+Integer.parseInt(map.get("remainingMelds").toString())); System.out.println("map2:"+Integer.parseInt(map2.get("remainingMelds").toString())); if (Integer.parseInt(map2.get("remainingMelds").toString())-1 < Integer.parseInt(map.get("remainingMelds").toString()) ){ flag1=index1+1; }else if (Integer.parseInt(map2.get("remainingMelds").toString())-1 == Integer.parseInt(map.get("remainingMelds").toString())){ int size2 = ((List) map2.get("cardResiue")).size(); System.out.println("size2" + size2); int size1 = ((List) map.get("cardResiue")).size(); System.out.println("size1" + size1); if (size2 < size1){ flag1=index1+1; } } index1 ++ ; } if (flag1 > 0){ params.putString("session", session + "," + token); params.putInt("qi", 0); params.putInt("id", flag1); int index2 = flag1 - 1; List integers = lists.get(index2); List result2 = getOtherCards1(integers, card); chowGroup.add(card); chowGroup.add(result2.get(0)); chowGroup.add(result2.get(1)); changShaCardInhand.add(card); Util.removeCard(changShaCardInhand, integers.get(0), 1); Util.removeCard(changShaCardInhand, integers.get(1), 1); Util.removeCard(changShaCardInhand, integers.get(2), 1); Global.logger.info("ddd"); }else { params.putString("session", session + "," + token); params.putInt("qi", 1); params.putInt("id", 0); } } } //听牌的时候先不吃 if (shifoutingpai.size() > 0) { System.out.println("听牌的时候先不吃++++++++++++++++++++++++++++++++"); params.putString("session", session + "," + token); params.putInt("qi", 1); params.putInt("id", 0); } // if (b && TinHuChi.isMoreThanLast() && !ChangShaSuanFaTest.isTin) { // // System.out.println("===============进入听胡吃牌=================="); // params.putString("session", session + "," + token); // params.putInt("qi", 0); // params.putInt("id", 1); // // chowGroup.add(card); // chowGroup.add(opcard); // chowGroup.add(opcard1); //// changShachuguopai.add(card); // Util.removeCard(changShaCardInhand, opcard, 1); // Util.removeCard(changShaCardInhand, opcard1, 1); //// }else { //// params.putString("session", session + "," + token); //// params.putInt("qi", 1); //// params.putInt("id", 0); //// } // } else { // System.out.println("isTin ++++++++++++++++++++++++++++++++++++" + isTinChi); // if (shouldChow(card) && pisCardsCount < 5 && !isChow && !isTinChi) { // params.putString("session", session + "," + token); // params.putInt("qi", 0); // params.putInt("id", 1); // chowGroup.add(card); // chowGroup.add(opcard); // chowGroup.add(opcard1); // // Util.removeCard(changShaCardInhand, opcard, 1); // Util.removeCard(changShaCardInhand, opcard1, 1); // } else { // params.putString("session", session + "," + token); // params.putInt("qi", 1); // params.putInt("id", 0); // } // } //自杠 // } else if (type1 == 4) { //// TingPaiChecker.TingResult tingResult1 = TingPaiChecker.checkTingPai(gangCardInhand); // // if (tingResult1.isTingPai()) { // boolean c = TinHuGang.canGang(gangCardInhand, opcard, false); //杠牌后是否还能听牌 // if (c) { // System.out.println("听牌 +++进入自杠===============================------------------------------------------------"); // // params.putString("session", session + "," + token); // params.putInt("qi", 0); // params.putInt("id", 1); // Util.removeCard(changShaCardInhand, opcard, 4); // // } else { // params.putString("session", session + "," + token); // params.putInt("qi", 0); // params.putInt("id", 0); // } // } else { //// int pisCardsCount = changShaSuanFaTest.countPairs(changShaCardInhand);//分析七小对 //// boolean gang = changShaSuanFaTest.isAllSameSuit1(changShaCardInhand); //// if (pisCardsCount < 5 && !gang) { // System.out.println("没有 +++ 听牌 +++进入自杠===============================------------------------------------------------"); //// //// params.putString("session", session + "," + token); //// params.putInt("qi", 0); //// params.putInt("id", 1); //// Util.removeCard(changShaCardInhand, opcard, 4); //// } else { // params.putString("session", session + "," + token); // params.putInt("qi", 0); // params.putInt("id", 0); //// } // // } // // // // 碰后补杠 // } } else if (type1 == 5) { params.putString("session", session + "," + token); params.putInt("qi", 0); params.putInt("id", 0); // Util.removeCard(changShaCardInhand, opcard, 1); // } } client.send("612", params, response -> { }); return null; } public static List getOtherCards1(List integers, int card) { List result = new ArrayList<>(); for (Integer num : integers) { if (num != card) { result.add(num); } } return result; } public static boolean isAllSameSuitgang(List handCards, int opcard3) { // 统计各花色的牌数量 Map suitCountMap = new HashMap<>(); for (Integer card : handCards) { int suit = card / 100; // 获取花色,100=万,200=筒,300=条 suitCountMap.put(suit, suitCountMap.getOrDefault(suit, 0) + 1); } // 检查是否有花色的牌数量超过8张 for (Map.Entry entry : suitCountMap.entrySet()) { int suit = entry.getKey(); int count = entry.getValue(); if (count >= 9) { // 检查杠牌的花色是否与当前花色一致 int gangSuit = opcard3 / 100; if (suit == gangSuit) { return true; } else { return false; } } } return true; } public static String changePlayer(String command, Message message) { if (command.equalsIgnoreCase("820")) { ITObject param = message.param; if (param == null) { return null; } } return null; } /** * 出牌方法 */ // public String outCard(TaurusClient client, List list) { public String outCard(TaurusClient client, Map> playerOutcardsMap, Map> playerchisMap, Map> playerpengsMap, Map> playermingsMap, Map> playerzisMap) { // playerOutcardsMap + playerchisMap 传到 outCardSuanFa //对出牌进行整合 List resultList = new ArrayList<>(); for (List cards : playerOutcardsMap.values()) { resultList.addAll(cards); } for (List chis : playerchisMap.values()) { resultList.addAll(chis); } for (List pengs : playerpengsMap.values()) { resultList.addAll(pengs); } for (List minggangs : playermingsMap.values()) { resultList.addAll(minggangs); } for (List zigang : playerzisMap.values()) { resultList.addAll(zigang); } // 红中麻将出牌 String changShaOutCard = changShaSuanFaTest.outCardSuanFa(changShaCardInhand, pongGroup, chowGroup, resultList); // String changShaOutCard = changShaSuanFaTest.outCardSuanFa(list, changShaCard,pongGroup); ITObject params = TObject.newInstance(); int cardToOut; if (StringUtil.isNotEmpty(changShaOutCard)) { cardToOut = Integer.parseInt(changShaOutCard); } else { cardToOut = changShaCardInhand.get(0); } params.putInt("card", cardToOut); int outCountBefore = changShachuguopai.size(); // 当前历史出牌数量 // 第n次出牌时,发送前n-1张出牌 if (outCountBefore >= 1) { // 发送前n-1张(所有历史出牌) List cardsToSend = changShachuguopai.subList(0, outCountBefore); params.putTArray("outcard_list", CardUtil.maJiangToTArray(cardsToSend)); } params.putTArray("card_list", CardUtil.maJiangToTArray(changShaCardInhand)); // 将当前出的牌添加到历史出牌列表 changShachuguopai.add(cardToOut); // 从手牌中移除 changShaCardInhand.remove(Integer.valueOf(cardToOut)); params.putString("session", session + "," + token); client.send("611", params, response -> { }); return null; } /** * 删除出过的牌组 * * @param param * @return */ public String shanchuchuguopai(ITObject param) { if (param == null) { return null; } Integer card = param.getInt("card"); // 操作牌值 Integer type = param.getInt("type"); // 操作类型 Integer from_seat = param.getInt("from_seat"); // 牌来源座位 Integer playerid = param.getInt("playerid"); String sql2 = String.format("SELECT id FROM `account` WHERE jiqiren=9998"); try { ITArray robotId2 = DataBase.use().executeQueryByTArray(sql2); List robotIdsList = new ArrayList<>(); for (int j = 0; j < robotId2.size(); j++) { robotIdsList.add(robotId2.getTObject(j).getInt("id")); } if (!robotIdsList.contains(playerid)) { if (type == 2 || type == 3 || type == 5 || type == 1) { // 碰,杠 getChuGuoCardInhand().remove(Integer.valueOf(card)); } } } catch (SQLException e) { e.printStackTrace(); } return null; } }