diff --git a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/Config.java b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/Config.java index 1b30f78..8f18e2d 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/Config.java +++ b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/Config.java @@ -1,105 +1,9 @@ package robot.mj; public class Config { - public static final int FENGDING_SCORE = 28; - public static final int XIPAI_SCORE = 10; - public static final int ANCHOU_SCORE = 10; - - public static final String ROOM_CONFIG_ZIMO = "zimo"; - public static final String ROOM_CONFIG_ZHUANGXIAN = "zhuangxian"; - public static final String ROOM_CONFIG_NIAO = "niao"; - public static final String ROOM_CONFIG_NIAO_TYPE = "niao_type"; - public static final String ROOM_CONFIG_PIAO_NIAO = "piao_niao"; //0:不嫖 1:自由票 2:固定票 - public static final String ROOM_CONFIG_PIAO_NIAO_AUTO = "auto_piao"; //piao fen - public static final String ROOM_CONFIG_PIAO_NIAO_OPT = "piao_niao_opt"; //piao fen - public static final String ROOM_CONFIG_ZT_LIULIUSHUN = "zhongtuliuliushun"; - public static final String ROOM_CONFIG_ZT_DASIXI = "zhongtusixi"; - public static final String ROOM_CONFIG_QS_JIEJIEGAO = "jiejiegao"; - public static final String ROOM_CONFIG_QS_SANTONG = "santong"; - public static final String ROOM_CONFIG_QS_YIZHIHUA = "yizhihua"; - public static final String ROOM_CONFIG_QUEYIMEN = "queyimen"; - public static final String ROOM_CONFIG_FENGDING = "fengding"; - public static final String ROOM_CONFIG_FENGDING_SCORE = "fengding_score"; - public static final String ROOM_CONFIG_XIPAI = "xi_pai"; - public static final String ROOM_CONFIG_XIPAI_SCORE = "xi_pai_score"; - - public static final String ROOM_CONFIG_ANCHOU_SCORE = "an_chou_score"; - - public static final String ROOM_CONFIG_DIFEN_SCORE = "difen_score"; - public static final String ROOM_CONFIG_NIAOFEN_SCORE = "niaofen_score"; - public static final String ROOM_CONFIG_NIAOFEN_OPT = "niaofen_opt"; //0中鸟加分,//1中鸟加倍 - public static final String ROOM_CONFIG_KAI_GONG = "kai_gong"; //0:开杠2张,1:开杠四张 - - - public static final int NIAO_TYPE_ADD = 0; - - public static final int NIAO_TYPE_DOUBLE = 1; - - public static final int NIAO_TYPE_CS2NIAO = 2; - - - public static final String ROOM_CONFIG_QS_JTYN = "two_pair"; - - public static final String ROOM_CONFIG_NO_JIANG = "no_jiang"; - - public static final String ROOM_CONFIG_NATIVE_HU = "native_hu"; - - - public static final String ROOM_CONFIG_FOUR_WIN = "four_win"; - - public static final String SETTLE_XIAO_DIAN_PAO = "xiao_dian_pao"; - public static final String SETTLE_XIAO_JIE_PAO = "xiao_jie_pao"; - public static final String SETTLE_XIAO_ZIMO = "xiao_zimo"; - public static final String SETTLE_DA_DIAN_PAO = "da_dian_pao"; - public static final String SETTLE_DA_JIE_PAO = "da_jie_pao"; - public static final String SETTLE_DA_ZIMO = "da_zimo"; - - - public static final String GAME_EVT_PLAYER_DEAL = "811"; - - public static final String GAME_DIS_CARD = "611"; - - public static final String GAME_EVT_DISCARD = "812"; - - public static final String GAME_EVT_DISCARD_TIP = "813"; - - public static final String GAME_EVT_FZTIPS = "814"; - - public static final String GAME_ACTION = "612"; - - public static final String GAME_EVT_ACTION = "815"; - - public static final String GAME_EVT_HU = "816"; - - public static final String GAME_EVT_RESULT1 = "817"; - - public static final String GAME_EVT_RESULT2 = "818"; - - public static final String GAME_EVT_DRAW = "819"; - - public static final String GAME_EVT_CHANGE_ACTIVE_PLAYER = "820"; - - public static final String GAME_EVT_NIAO = "821"; - - public static final String GAME_EVT_QSTIP = "822"; - - public static final String GAME_EVT_QSWIN = "823"; - - public static final String GAME_EVT_OPENKONG = "824"; - - public static final String GAME_EVT_HAIDITIP = "825"; - - public static final String GAME_EVT_PIAONIAO_TIP = "833"; - - public static final String GAME_EVT_PIAONIAO = "834"; - - public static final String GAME_EVT_TING_TIP = "835"; - - public static final String GAME_EVT_TING = "836"; - - public static final String CREATE_ROOM_ROBOT = "create_room_for_robot"; - public static final String INIT_CONNECTION = "init_connection"; + public static final String CREATE_ROOM_ROBOT = "create_room_for_robot"; + public static final String INIT_CONNECTION = "init_connection"; /** * 加入房间 - robot_mgr to robot_mj_cs 的内部协议号 @@ -111,16 +15,6 @@ public class Config { */ public static final String GAME_READY = "2003"; - /** - * 退出房间 - robot_mgr to robot_mj_cs 的内部协议号 - */ - public static final String EXIT_ROOM = "2005"; - - /** - * 手动重连 - robot_mgr to robot_mj_cs 的内部协议号 - */ - public static final String RECONNECT = "2006"; - /** * 发送准备 - robot_mj_cs to game_mj_cs 的协议号 */ @@ -131,8 +25,4 @@ public class Config { */ public static final String JOIN_ROOM_CS = "1002"; - /** - * 退出房间 - robot_mgr to game_mj_cs 的内部协议号 - */ - public static final String EXIT_ROOM_CS = "1005"; } \ No newline at end of file diff --git a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXActionEvent.java b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXActionEvent.java deleted file mode 100644 index 556d1b3..0000000 --- a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXActionEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package robot.mj; - -public class EXActionEvent { - - public static final String EVENT_ACTION = "action"; - - public static final String EVENT_DISCARD = "discard"; - -} diff --git a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXMainServer.java b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXMainServer.java index c4051e9..b6a2df2 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXMainServer.java +++ b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXMainServer.java @@ -6,18 +6,12 @@ import com.robot.GameController; import com.robot.MainServer; import com.robot.data.Player; import com.robot.data.Room; -import com.taurus.core.entity.ITObject; -import com.taurus.core.entity.TObject; import com.taurus.core.plugin.redis.Redis; -import com.taurus.permanent.TPServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.Jedis; import robot.mj.info.RobotUser; import taurus.client.NetManager; -import taurus.client.TaurusClient; - -import java.util.concurrent.TimeUnit; import static robot.mj.EXGameController.robotRoomMapping; @@ -29,8 +23,6 @@ public class EXMainServer extends MainServer{ private static final Logger log = LoggerFactory.getLogger(EXMainServer.class); private static final RobotConnectionManager robotConnectionManager = new RobotConnectionManager(); - private static final EXGameController exGameController = new EXGameController(); - private volatile boolean connectionCheckRunning = true; @Override public void onStart() { @@ -68,48 +60,6 @@ public class EXMainServer extends MainServer{ } } -// TPServer.me().getTimerPool().scheduleAtFixedRate(new Runnable() { -// @Override -// public void run() { -// -// for(Map.Entry entry : robotRoomMapping.entrySet()) { -// RobotUser robotUser = entry.getValue(); -// //1、登录 -// //判断是否登录 -// if(!robotUser.isLogin){ -// robotConnectionManager.login(robotUser); -// } -// /*//2、链接 -// //判断是否链接 -// System.out.println("robotUser.isconnect"+robotUser.getIsconnect()); -// if(!robotUser.getIsconnect()){ -// robotConnectionManager.connectGame(robotUser); -// }else{ -// robotConnectionManager.renconnect(robotUser); -// } -// -// -// //4、加入房间 -// if(robotUser.getStatus()==0){ -// //没状态时候进入加入房间 -// ITObject params = new TObject(); -// params.putString("connecId", robotUser.getRoomId()+"_"+robotUser.getRobotId()); -// params.putString("roomId", robotUser.getRoomId()); -// params.putString("groupId", robotUser.getRobotGroupid()); -// params.putString("session", "{user}:"+robotUser.getRobotId()); -// exGameController.joinRoom(null, params, robotUser.getClient().getId()); -// } -// System.out.println("robotUser.getIntoRoomTime()"+robotUser.getIntoRoomTime()); -// System.out.println("robGetTiem"+robotConnectionManager.getTime()); -// if(robotUser.getIntoRoomTime()+6<=robotConnectionManager.getTime()){ -// //5、退出房间 -// robotConnectionManager.outoRoom(robotUser); -// }*/ -// -// } -// } -// }, 0, 5 ,TimeUnit.SECONDS); - //5、干活 log.info("长沙麻将机器人服务器已启动"); log.info("服务器将监听端口 {} 用于接收robot_mgr管理协议", gameSetting.port); @@ -132,7 +82,7 @@ public class EXMainServer extends MainServer{ } }, "Changsha_Thread"); - eventThread.setDaemon(true); // 设置为守护线程 + eventThread.setDaemon(true); //设置为守护线程 eventThread.start(); } @@ -157,8 +107,6 @@ public class EXMainServer extends MainServer{ public void onStop() { super.onStop(); - // 停止连接检查线程 - connectionCheckRunning = false; log.info("长沙麻将机器人服务器已停止"); } } \ No newline at end of file diff --git a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXPlayer.java b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXPlayer.java index 54b8039..009e6a6 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXPlayer.java +++ b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXPlayer.java @@ -1,15 +1,7 @@ package robot.mj; -import com.robot.Util; import com.robot.data.Player; import com.robot.data.Room; -import com.robot.data.Score; -import com.taurus.core.entity.ITArray; -import com.taurus.core.entity.ITObject; -import com.taurus.core.entity.TArray; -import com.taurus.core.entity.TObject; - -import java.util.*; /** * diff --git a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXRoom.java b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXRoom.java index 84ea302..877d587 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXRoom.java +++ b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXRoom.java @@ -7,34 +7,13 @@ import java.util.Map; public class EXRoom extends Room { - // - - - public EXRoom(String roomid, Map redis_room_map) { super(roomid, redis_room_map); - - } - - - - - public void checkAction() { - - } - - - - - - - @Override protected void roomResult() { } - @Override public void endGame() { super.endGame(); diff --git a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/RobotConnectionManager.java b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/RobotConnectionManager.java index 421bdfc..31b63c7 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/RobotConnectionManager.java +++ b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/RobotConnectionManager.java @@ -306,8 +306,8 @@ public class RobotConnectionManager { } } } - }finally { - + }catch (Exception e) { + e.printStackTrace(); } }else { renconnect(robotUser); @@ -343,7 +343,7 @@ public class RobotConnectionManager { jedis2.hset(getStart, key, "2"); } } - huNanChangSha.cardInHead(command, message, client); + huNanChangSha.cardInHead(command, message); //处理完协议后保存到Redis HuNanChangSha currentInstance = huNanChangShaInstances.get(connecId); currentInstance.saveToRedis(connecId); @@ -356,14 +356,14 @@ public class RobotConnectionManager { ITArray opmingcards = param.getTArray("opmingcards"); ITArray opzicards = param.getTArray("opzicards"); - // 获取当前连接专用的Maps + //获取当前连接专用的Maps Map> currentPlayerOutcardsMap = getPlayerOutcardsMap(connecId); Map> currentPlayerchisMap = getPlayerchisMap(connecId); Map> currentPlayerpengsMap = getPlayerpengsMap(connecId); Map> currentPlayermingsMap = getPlayermingsMap(connecId); Map> currentPlayerzisMap = getPlayerzisMap(connecId); - // 清空旧数据,用新数据完全覆盖 + //清空旧数据 用新数据完全覆盖 currentPlayerOutcardsMap.clear(); currentPlayerchisMap.clear(); currentPlayerpengsMap.clear(); @@ -376,15 +376,13 @@ public class RobotConnectionManager { int playerId = playerData.getInt("playerId"); ITArray outcardsArray = playerData.getTArray("outcards"); - // 转换为List List outcardsList = new ArrayList<>(); for (int j = 0; j < outcardsArray.size(); j++) { outcardsList.add(outcardsArray.getInt(j)); } - // 存储到当前连接的Map中(覆盖旧数据) + //存储到当前连接的Map中(覆盖旧数据) currentPlayerOutcardsMap.put(playerId, outcardsList); - } } @@ -455,7 +453,7 @@ public class RobotConnectionManager { } //摸牌 else if ("819".equalsIgnoreCase(command)) { - huNanChangSha.getCard(command, message, client); + huNanChangSha.getCard(command, message); //处理完协议后保存到Redis HuNanChangSha currentInstance = huNanChangShaInstances.get(connecId); currentInstance.saveToRedis(connecId); @@ -580,7 +578,6 @@ public class RobotConnectionManager { if (playerId == paramRobotId) { String gpid = jedis0.hget(roomKey, "gpid"); - String gpId = jedis0.hget(roomKey, "group"); //更新机器人剩余数量 if (count != null && count.containsKey(Integer.parseInt(gpid))) { @@ -624,7 +621,6 @@ public class RobotConnectionManager { count.put(pid, currentValue - 1); } } - //更新机器人剩余数量 updateLeftoverRobot(Integer.parseInt(robotUser.getRobotId())); } @@ -677,7 +673,6 @@ public class RobotConnectionManager { client.send("612", params, response -> { }); - } } catch (Exception e) { throw new RuntimeException(e); diff --git a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/RoomCreator.java b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/RoomCreator.java index e6e2539..9101a15 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/RoomCreator.java +++ b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/RoomCreator.java @@ -37,8 +37,7 @@ public class RoomCreator { log.error("没有可用的房间ID,free_room队列为空"); return null; } - //Redis.use("group1_db1").lpush("free_room", newRoomId); - + String roomKey = "room:" + newRoomId; //获取群组信息 @@ -48,7 +47,6 @@ public class RoomCreator { if (groupInfo.isEmpty()) { log.warn("群组信息不存在,群组ID: {},正在创建默认群组信息", groupId); createDefaultGroupInfo(jedis11, groupId); - groupInfo = jedis11.hgetAll(groupKey); } //确保游戏配置存在 @@ -58,7 +56,6 @@ public class RoomCreator { if (gameInfo.isEmpty()) { log.warn("游戏配置不存在,玩法ID: {},正在创建长沙麻将默认游戏配置", wanfaId); createDefaultGameConfig(jedis0, wanfaId); - gameInfo = jedis0.hgetAll(gameConfigKey); } //获取玩法配置 diff --git a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/business/AccountBusiness.java b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/business/AccountBusiness.java index bdf1bfa..e83bc35 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/business/AccountBusiness.java +++ b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/business/AccountBusiness.java @@ -21,13 +21,6 @@ import com.taurus.web.Controller; import com.taurus.web.WebException; import redis.clients.jedis.Jedis; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; @@ -36,71 +29,7 @@ import java.util.Set; public class AccountBusiness extends Controller { private static Logger logger = Logger.getLogger(AccountBusiness.class); - public static String request(String httpUrl, String httpArg) { - BufferedReader reader = null; - String result = null; - StringBuffer sbf = new StringBuffer(); - httpUrl = httpUrl + "?" + httpArg; - - try { - URL url = new URL(httpUrl); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.connect(); - InputStream is = connection.getInputStream(); - reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); - String strRead = reader.readLine(); - if (strRead != null) { - sbf.append(strRead); - while ((strRead = reader.readLine()) != null) { - sbf.append("\n"); - sbf.append(strRead); - } - } - reader.close(); - result = sbf.toString(); - } catch (Exception e) { - e.printStackTrace(); - } - return result; - } - - public static String md5(String plainText) { - StringBuffer buf = null; - try { - MessageDigest md = MessageDigest.getInstance("MD5"); - md.update(plainText.getBytes()); - byte b[] = md.digest(); - int i; - buf = new StringBuffer(""); - for (int offset = 0; offset < b.length; offset++) { - i = b[offset]; - if (i < 0) - i += 256; - if (i < 16) - buf.append("0"); - buf.append(Integer.toHexString(i)); - } - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } - return buf.toString(); - } - - public static String encodeUrlString(String str, String charset) { - String strret = null; - if (str == null) - return str; - try { - strret = java.net.URLEncoder.encode(str, charset); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - return strret; - } - - private final ITObject fillLoginData(String session, int accountid) { + private ITObject fillLoginData(String session, int accountid) { ITObject resData = TObject.newInstance(); ITObject userData = TObject.newInstance(); resData.putTObject("account", userData); @@ -151,8 +80,7 @@ public class AccountBusiness extends Controller { return resData; } - - public final ITObject fastLogin(int userid) throws Exception { + public final ITObject fastLogin(int userid) { Jedis jedis = Redis.use("group1_db0").getJedis(); ITObject resData = null; try { @@ -189,7 +117,6 @@ public class AccountBusiness extends Controller { public final ITObject idPasswordLogin(int id, String password) throws Exception { - logger.info("id:" + id + " login"); Jedis jedis0 = Redis.use("group1_db0").getJedis(); @@ -214,8 +141,6 @@ public class AccountBusiness extends Controller { } - - String idPwdBan = Redis.use("group1_db0").get(id + "_login_ban"); if (StringUtil.isNotEmpty(idPwdBan)) { System.out.println("进入了77777777777777777777"); @@ -261,17 +186,6 @@ public class AccountBusiness extends Controller { if (resultArray.size() > 0) { this.setSession(session); - String old_nick = acc_bean.nick; - String old_portrait = acc_bean.portrait; -// String new_nick = reqData.getUtfString("nick"); -// String new_portrait = reqData.getUtfString("portrait"); -// if (!old_nick.equals(new_nick) || !old_portrait.equals(new_portrait)) { -// ITObject userData1 = TObject.newInstance(); -// userData1.putUtfString("nick", userData.getUtfString("nick")); -// userData1.putUtfString("portrait", userData.getUtfString("portrait")); -// userData1.putInt("sex", userData.getInt("sex")); -// updateSession(userData, accountid); -// } } ITObject resData = fillLoginData(session, accountid); @@ -283,13 +197,6 @@ public class AccountBusiness extends Controller { Redis.use("group1_db0").hset(token, "create_time", "" + System.currentTimeMillis() / 1000); Redis.use("group1_db0").expire(token, 172800); -// Set allToken = Redis.use("group1_db0").smembers(session + "_token"); -// for (String temp : allToken) { -// if (!Redis.use("group1_db0").exists(temp)) { -// Redis.use("group1_db0").srem(session + "_token", temp); -// logger.info("delte timeout token:" + temp); -// } -// } System.out.println("进入了2222222222222"); long tokenNum = Redis.use("group1_db0").scard(session + "_token"); @@ -350,9 +257,8 @@ public class AccountBusiness extends Controller { /** * * @return - * @throws Exception */ - private final int UpdateUserData(ITObject reqData, long id) throws Exception { + private int UpdateUserData(ITObject reqData, long id) { ITObject userData = TObject.newInstance(); userData.putInt("id", (int) id); diff --git a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/handler/HuNanChangSha.java b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/handler/HuNanChangSha.java index f8eb476..474f869 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/handler/HuNanChangSha.java +++ b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/handler/HuNanChangSha.java @@ -1,23 +1,18 @@ package robot.mj.handler; -import com.google.gson.JsonElement; import com.robot.Util; import com.taurus.core.entity.ITArray; import com.taurus.core.entity.ITObject; import com.taurus.core.entity.TArray; import com.taurus.core.entity.TObject; -import com.taurus.core.plugin.database.DataBase; import com.taurus.core.plugin.redis.Redis; -import com.taurus.core.util.Logger; import com.taurus.core.util.StringUtil; import redis.clients.jedis.Jedis; import taurus.client.Message; import taurus.client.TaurusClient; import taurus.util.*; -import java.sql.SQLException; import java.util.*; -import java.util.stream.Collectors; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; @@ -26,20 +21,7 @@ import com.google.gson.reflect.TypeToken; public class HuNanChangSha { public int changShaCard = 0; - public boolean isTinChi = false; public static boolean isTinPeng = false; - - private int robotid=0; - public void setRobotid(int robotid) { - this.robotid = robotid; - } - public int getRobotid() { - return robotid; - } - -// private static final Logger log = Logger.getLogger(DoTest.class); - - private final List changShaCardInhandgang = new ArrayList<>(); @@ -58,21 +40,15 @@ public class HuNanChangSha { //杠的牌 private final List gangdepai = new ArrayList<>(); - //碰牌 private final List pongGroup = new ArrayList<>(); - //吃牌 private final List chowGroup = new ArrayList<>(); - - // 玩家座位号 - public int seat = 0; - - // 会话标识 + //会话标识 public String session = ""; - // 访问令牌 + //访问令牌 public String token = ""; @@ -80,8 +56,7 @@ public class HuNanChangSha { private static final Gson gson = new Gson(); - // 公共的getter和setter方法 - + //公共的getter和setter方法 public List getgangdepai() { return gangdepai; } @@ -90,7 +65,6 @@ public class HuNanChangSha { return changShaCardInhandgang; } - // 公共的getter和setter方法 public List getpongGroup() { return pongGroup; } @@ -99,7 +73,6 @@ public class HuNanChangSha { return chowGroup; } - public List getChuGuoCardInhand() { return changShachuguopai; } @@ -208,7 +181,7 @@ public class HuNanChangSha { if (gangHandCards != null) changShaCardInhandgang.addAll(gangHandCards); } - // 恢复基本属性 + //恢复基本属性 if (stateMap.containsKey("changShaCard")) { changShaCard = Integer.parseInt(stateMap.get("changShaCard")); } @@ -257,8 +230,6 @@ public class HuNanChangSha { return null; } changShaCard = param.getInt("card"); - - } return null; } @@ -271,7 +242,7 @@ public class HuNanChangSha { * @param message 消息对象 * @return */ - public String getCard(String command, Message message, TaurusClient client) { + public String getCard(String command, Message message) { if (command.equalsIgnoreCase("819")) { ITObject param = message.param; if (param == null) { @@ -279,52 +250,19 @@ public class HuNanChangSha { } Jedis jedis222 = Redis.use("group1_db2").getJedis(); - if (param.getInt("player") != null) { - Integer player = param.getInt("player"); int drawnCard = param.getInt("card"); changShaSuanFaTest.drawnCards = drawnCard;//存储摸到的牌 - System.out.println("changShaCardInhand"+changShaCardInhand); changShaCardInhand.add(drawnCard); - System.out.println("changShaCardInhandAdd"+changShaCardInhand); System.out.println("param.getInt(player)" + param.getInt("player") ); System.out.println("摸到的牌 +++++++++ " + drawnCard); - if (jedis222.hget("{robortInfo}:" + player, "circleId") != null && jedis222.hget("{robortInfo}:" + player, "pid") != null) { - String circleId = jedis222.hget("{robortInfo}:" + player, "circleId"); - String pid = jedis222.hget("{robortInfo}:" + player, "pid"); - String getStart = "g{" + circleId + "}:play:" + pid; - if (!pid.equals("0")) { -// jedis222.hset(getStart, String.valueOf(player), "2"); - } - } } - jedis222.close(); } return null; } - /** - * 判断是否应该碰牌 - * - * @param proposedCard 提议碰的牌 - * @return 是否应该碰牌 - */ - public boolean shouldPong(int proposedCard) { - - - // 直接调用hongZhongSuanFaTest中的shouldPong方法,它已经包含了所有需要的规则 - return changShaSuanFaTest.shouldPong(proposedCard, changShaCardInhand); - - } - - - public boolean shouldChow(int proposedCard) { - - return changShaSuanFaTest.shouldChow(proposedCard, changShaCardInhand); - } - /** * 初始化手牌协议 811 * @@ -333,13 +271,12 @@ public class HuNanChangSha { * @return */ - public String cardInHead(String command, Message message, TaurusClient client) { + public String cardInHead(String command, Message message) { 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"); List handCards = new ArrayList<>(); @@ -374,41 +311,6 @@ public class HuNanChangSha { changShachuguopai.addAll(outCard); } - - public static int[][] countTiles(List cardInHand) { - int[][] counts = new int[5][10]; // 类型×值 - - for (Integer card : cardInHand) { - if (card == 0) { - continue; - } - counts[card / 100 - 1][card % 100]++; - } - return counts; - } - - public static boolean isJiangPai(int card) { - if (card % 100 == 2 || card % 100 == 5 || card % 100 == 8) { - return true; - } - return false; - } - - public static int checkduijiang(List cardInHand) { - Map countMap = new HashMap<>(); - for (Integer item : cardInHand) { - countMap.put(item, countMap.getOrDefault(item, 0) + 1); - } - int jiangnum = 0; - for (int key : countMap.keySet()) { - if (isJiangPai(key) && countMap.get(key) >= 2) { - jiangnum++; - } - } - return jiangnum; - } - - /** * 处理 吃,碰,杠,补,胡 * @@ -464,10 +366,8 @@ public class HuNanChangSha { */ public String actionCard(ITObject param, TaurusClient client) { ITArray tipList = param.getTArray("tip_list"); -// log.info("tipList" +tipList); ITObject params = TObject.newInstance(); int card = 0; - // getChangShaCardInhand(); //循环 List yupanhandcard = new ArrayList<>(); yupanhandcard.addAll(changShaCardInhand); @@ -553,7 +453,6 @@ public class HuNanChangSha { if (type == 4) { - // Util.removeCard(changShaCardInhand,card,4); Util.removeCard(gangusecars, card, 4); List shifoutingpai4 = changShaSuanFaTest.handscardshifoutingpai(gangusecars, chowGroup, pongGroup, gangdepai); if (shifoutingpai4.size() > 0) { @@ -590,7 +489,6 @@ public class HuNanChangSha { } } if (type == 5) { - //Util.removeCard(changShaCardInhand,card,1); Util.removeCard(gangusecars, card, 1); List shifoutingpai5 = changShaSuanFaTest.handscardshifoutingpai(gangusecars, chowGroup, pongGroup, gangdepai); @@ -649,7 +547,6 @@ public class HuNanChangSha { Map pingfenResult = new HashMap<>(); Map idObject = new HashMap<>(); - //int bupaiid = 0;//补牌id for (int i = 0; i < tipList.size(); i++) { TObject firstTip = (TObject) tipList.get(i).getObject(); int type = firstTip.getInt("type"); @@ -666,9 +563,6 @@ public class HuNanChangSha { }); return "胡牌"; } - //if((type==4||type==5||type==6)&&weight==3){ - // bupaiid = id; - // } //对应的数据 ITObject tmp = new TObject(); //处理听的结果 @@ -749,7 +643,6 @@ public class HuNanChangSha { //计算牌数 //如果 不吃,不碰,而且差三手牌情况,则补 - //if (bupaiid>0) { for (int i = 0; i < tipList.size(); i++) { TObject firstTip = (TObject) tipList.get(i).getObject(); int type = firstTip.getInt("type"); @@ -860,44 +753,6 @@ public class HuNanChangSha { }); return null; } - /*if (Integer.parseInt(map.get("remainingMelds").toString()) > 2) { - params.putString("session", session + "," + token); - params.putInt("qi", 0); - params.putInt("id", id); - - if (type == 3) { - Util.removeCard(changShaCardInhand, card, 3); - gangdepai.add(card); - gangdepai.add(card); - gangdepai.add(card); - gangdepai.add(card); - } - if (type == 4) { - Util.removeCard(changShaCardInhand, card, 4); - gangdepai.add(card); - gangdepai.add(card); - gangdepai.add(card); - gangdepai.add(card); - } - if (type == 5) { - Util.removeCard(changShaCardInhand, card, 1); - gangdepai.add(card); - gangdepai.add(card); - gangdepai.add(card); - gangdepai.add(card); - } - client.send("612", params, response -> { - }); - return null; - } else { - params.putString("session", session + "," + token); - params.putInt("qi", 0); - params.putInt("id", 0); - client.send("612", params, response -> { - }); - return null; - } - */ } else { params.putString("session", session + "," + token); @@ -942,956 +797,6 @@ public class HuNanChangSha { } - public String actionCardBak2(ITObject param, TaurusClient client) { - ITArray tipList = param.getTArray("tip_list"); -// log.info("tipList" +tipList); - //tipList[{opcard=[207, 208], weight=1, id=1, type=1, card=206}] - boolean chiflag = false;//吃 - boolean pengflag = false; //碰 - boolean bupai = false; //补 - boolean minggang = false; //杠 - boolean angang = false; //暗杠 - boolean penggang = false; //开杠 - - int card = 0;//当前 消息的牌 - ITObject params = TObject.newInstance(); - - for (int i = 0; i < tipList.size(); i++) { - TObject firstTip = (TObject) tipList.get(i).getObject(); - int type = firstTip.getInt("type"); - int id = firstTip.getInt("id"); - int weight = firstTip.getInt("weight"); - card = firstTip.getInt("card"); - if (type == 6) { - params.putString("session", session + "," + token); - params.putInt("qi", 0); - params.putInt("id", id); - client.send("612", params, response -> { - }); - return "胡牌"; - } - if (type == 1) { - chiflag = true; - } - if (type == 2) { - pengflag = true; - } - if (type == 3 && weight == 3) { - //补 - bupai = true; - } - if (type == 3 && weight == 4) { - //杠 - minggang = true; - } - if (type == 5) { - penggang = true; - } - } - - /* - //如果吃,没有碰 - if (chiflag&&!pengflag){ - chiNoPeng(tipList,card,client); - } - - //如果有吃有碰 - if (chiflag&&pengflag&&!minggang&&!penggang){ - chiOrPeng(tipList,card,client); - } - - //没有吃,有碰 - if (!chiflag&&penggang&&!minggang&&!angang){ - pengNoChi(tipList,card,client); - } - - if (bupai&&!penggang&&!angang){ - //补 - - } - - //杠 - if (minggang||bupai||penggang){ - gangNoChiPeng(tipList,card,client); - }*/ - return null; - } - - - /** - * 处理吃 问题 - * @param tipList - * @param client - */ - /* - public int chiNoPeng(ITArray tipList,int card,TaurusClient client){ - ITObject params = TObject.newInstance(); - params.putString("session", session + "," + token); - //判断是否能吃 - //1、吃之后能否下听 - List shifoutingpai = TinHuChi.shifoutingpai(changShaCardInhand); - if (shifoutingpai.size() == 0) { - //没下听 - //如果吃了可以立马下听,则吃 - int chitingpaiid = changShaSuanFaTest.checkChiTingAction(card,changShaCardInhand); - if (chitingpaiid>0){ - //处理吃后的数据 - params.putInt("qi", 0); - params.putInt("id", chitingpaiid-1); - - //记录吃掉的牌 - List> lists = new ArrayList<>(); - lists.addAll(TinHuChi.checkChi(changShaCardInhand, card)); - - List integers = lists.get(chitingpaiid-1); - List result1 = getOtherCards1(integers, card); - - chowGroup.add(card); - chowGroup.add(result1.get(0)); - chowGroup.add(result1.get(1)); - changShaCardInhand.add(card); - Util.removeCard(changShaCardInhand,result1.get(0),1); - Util.removeCard(changShaCardInhand,result1.get(1),1); - Util.removeCard(changShaCardInhand,card,1); - - client.send("612", params, response -> {}); - return chitingpaiid; - } - //2、吃之后是否没了大胡 - //判断是否满足7对 - int pisCardsCount = changShaSuanFaTest.countPairs(changShaCardInhand); - if (pisCardsCount>=4){ - params.putInt("qi", 0); - params.putInt("id", 0); - }else{ - //判断是否可以执行 清一色操作 - boolean isChow = changShaSuanFaTest.checkAllSameSuitAll(card,changShaCardInhand,pongGroup,chowGroup,gangdepai); - if (isChow){ - //判断是否可以吃 - //判断吃之后是否会破坏下听 - //3、吃之后是否破坏牌型 - int canchiId = changShaSuanFaTest.checkCanChiAction(card,changShaCardInhand); - - if (canchiId>0){ - - params.putInt("qi", 0); - params.putInt("id", canchiId-1); - - //记录吃掉的牌 - List> lists = new ArrayList<>(); - lists.addAll(TinHuChi.checkChi(changShaCardInhand, card)); - - List integers2 = lists.get(canchiId-1); - List result2 = getOtherCards1(integers2, card); - - chowGroup.add(card); - chowGroup.add(result2.get(0)); - chowGroup.add(result2.get(1)); - changShaCardInhand.add(card); - Util.removeCard(changShaCardInhand,result2.get(0),1); - Util.removeCard(changShaCardInhand,result2.get(1),1); - Util.removeCard(changShaCardInhand,card,1); - - client.send("612", params, response -> {}); - return chitingpaiid; - - - }else{ - params.putInt("qi", 0); - params.putInt("id", 0); - } - - }else{ - //不可以吃 - params.putInt("qi", 0); - params.putInt("id", 0); - } - } - }else{ - //不吃 - - //吃之后没有下听 - params.putInt("qi", 0); - params.putInt("id", 0); - } - - - - - - - client.send("612", params, response -> {}); - return 0; - } - */ - /** - * 同时有吃有碰 - * @param tipList - * @param client - */ - /* - public void chiOrPeng(ITArray tipList,int card,TaurusClient client){ - ITObject params = TObject.newInstance(); - //判断碰和吃 - //判断牌型是否下听 - params.putString("session", session + "," + token); - List shifoutingpai = TinHuChi.shifoutingpai(changShaCardInhand); - if (shifoutingpai.size() == 0) { - - //1、先判断是否碰之后破坏听牌 - - - //2、如果能碰,则进入判断吃逻辑,对比吃、碰那个会更优 - - - //3、判断吃或者碰之后都会破坏听牌,不能吃和碰 - - }else{ - //有下听 先不做操作,后续判断换牌 - params.putInt("qi", 0); - params.putInt("id", 0); - } - - - - - - - - - client.send("612", params, response -> {}); - } - - /** - * 没吃,有碰 - * @param tipList - * @param client - */ - - /* - public void pengNoChi(ITArray tipList,int card,TaurusClient client){ - ITObject params = TObject.newInstance(); - - client.send("612", params, response -> {}); - }*/ - - /** - * 杠没有吃,没有碰 - * @param tipList - * @param client - */ - /* - public void gangNoChiPeng(ITArray tipList,int card,TaurusClient client){ - ITObject params = TObject.newInstance(); - - - - client.send("612", params, response -> {}); - } - */ - - /** - * 处理杠碰胡操作 - * - * @param - * @return - */ - /* - public String actionCardbak(ITObject param, TaurusClient client) { - 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); - } - } - - System.out.println("进入吃type:" + type1); - - if (type1 == 2) { - - boolean isChow = changShaSuanFaTest.isAllSameSuit1(changShaCardInhand); - if (isChow) { - params.putString("session", session + "," + token); - params.putInt("qi", 1); - params.putInt("id", 0); - } else { - List shifoutingpai = TinHuChi.shifoutingpai(changShaCardInhand); - //目前手牌没有听牌 - if (shifoutingpai.size() == 0) { - - //判断是否满足7对 - int pisCardsCount = changShaSuanFaTest.countPairs(changShaCardInhand); - if (pisCardsCount >= 5) { - - params.putString("session", session + "," + token); - params.putInt("qi", 1); - params.putInt("id", 0); - } else { - 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 { - //碰之前的map - Map map = new HashMap<>(); - //碰之后的map - Map map2 = new HashMap<>(); - - //先判断碰之前还需要几手牌,以及孤章 -// int jiangnum = checkduijiang(changShaCardInhand); - List tmpChangSch = new ArrayList<>(); - tmpChangSch.addAll(changShaCardInhand); - tmpChangSch.add(opcard); - ChangshaWinSplitCard.checkNormalHu(tmpChangSch, map); - - - //碰之后 - List pengtemphand = new ArrayList<>(); - pengtemphand.addAll(tmpChangSch); - Util.removeCard(pengtemphand, opcard, 3); - - ChangshaWinSplitCard.checkNormalHu(pengtemphand, 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()) < Integer.parseInt(map.get("remainingMelds").toString())) { - 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 (Integer.parseInt(map2.get("remainingMelds").toString()) == Integer.parseInt(map.get("remainingMelds").toString())) { //碰完后和碰之前手数相等,需要判断孤章数量 - //碰之后的数量 - int size2 = ((List) map2.get("cardResiue")).size(); - System.out.println("碰之后的孤章数量 size" + size2); - - int size1 = ((List) map.get("cardResiue")).size(); - System.out.println("碰之前的孤章数量 size" + size1); - if (size2 < size1) { - 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 (Integer.parseInt(map2.get("remainingMelds").toString()) > Integer.parseInt(map.get("remainingMelds").toString()) || ((List) map2.get("cardResiue")).size() > ((List) map.get("cardResiue")).size()) { - 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); - if (isChow) { - params.putString("session", session + "," + token); - params.putInt("qi", 1); - params.putInt("id", 0); - } else { - - //判断当前手牌是否已经听牌 已经听牌了就不要再吃牌了 - List shifoutingpai = TinHuChi.shifoutingpai(changShaCardInhand); - - //目前手牌没有听牌 - if (shifoutingpai.size() == 0) { - - //判断是否满足7对 - int pisCardsCount = changShaSuanFaTest.countPairs(changShaCardInhand); - if (pisCardsCount >= 5) { - - params.putString("session", session + "," + token); - params.putInt("qi", 1); - params.putInt("id", 0); - - } else { - - List> lists = new ArrayList<>(); - lists.addAll(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> lists1 = TinHuChi.checkChi(changShaCardInhand, card); - int jiangnum = checkduijiang(changShaCardInhand); - List tmpChangSch = new ArrayList<>(); - tmpChangSch.addAll(changShaCardInhand); - tmpChangSch.add(card); - ChangshaWinSplitCard.checkNormalHu(tmpChangSch, map); - - System.out.println("checkNormalHu" + map.get("cardResiue")); - - - 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()) < Integer.parseInt(map.get("remainingMelds").toString())) { - flag1 = index1 + 1; - } else if (Integer.parseInt(map2.get("remainingMelds").toString()) == 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; - } - - //如果手里没有将,则可以吃 - if (jiangnum > 0) { - int chihoujiangnum = checkduijiang(temphand); - if (chihoujiangnum > 0) { - //吃之后还有将 - flag1 = index1 + 1; - } - } else { - System.out.println("没队将"); - //孤章1张 差一手 不是将 而且card不是将 - if (Integer.parseInt(map.get("remainingMelds").toString()) == 1 && size1 == 1 && !isJiangPai(((List) map.get("cardResiue")).get(0)) && !isJiangPai(card)) { - //吃 - break; - } - flag1 = index1 + 1; - // break; - } - } - index1++; - } - - if (flag1 > 0) { - System.out.println("flag1:" + flag1); - params.putString("session", session + "," + token); - params.putInt("qi", 0); - params.putInt("id", flag1); - - int index2 = flag1 - 1; - - if (index2 >= lists.size()) { - index2 = 0; - } - System.out.println("index2:" + index2); - System.out.println("lists:" + lists); - List integers = new ArrayList<>(); - integers.addAll(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); - - } 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; @@ -1907,7 +812,6 @@ public class HuNanChangSha { /** * 出牌方法 */ -// 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 @@ -1941,7 +845,6 @@ public class HuNanChangSha { String changShaOutCard = changShaSuanFaTest.outCardSuanFa(changShaCardInhand, pongGroup, chowGroup, gangdepai, resultList); System.out.println("长沙麻将出牌" + changShaCardInhand); -// String changShaOutCard = changShaSuanFaTest.outCardSuanFa(list, changShaCard,pongGroup); ITObject params = TObject.newInstance(); int cardToOut; if (StringUtil.isNotEmpty(changShaOutCard)) { @@ -1995,7 +898,6 @@ public class HuNanChangSha { Integer card = param.getInt("card"); // 操作牌值 Integer type = param.getInt("type"); // 操作类型 - Integer from_seat = param.getInt("from_seat"); // 牌来源座位 Integer playerid = param.getInt("playerid"); @@ -2027,93 +929,4 @@ public class HuNanChangSha { return null; } - - public static void main(String[] args) { - - String str = "[107, 202, 204, 103, 109, 101, 108, 201, 109, 105, 207, 209, 202]"; - String cleanedStr = str.substring(1, str.length() - 1); - List list = Arrays.stream(cleanedStr.split(", ")) - .map(Integer::parseInt) - .collect(Collectors.toList()); - System.out.println(list); - /*HuNanChangSha huNanChangSha = new HuNanChangSha(); - ITObject params = TObject.newInstance(); - TaurusClient tc = new TaurusClient("47.109.55.7", "10", TaurusClient.ConnectionProtocol.Tcp); - List hands1 = new ArrayList<>(); - hands1.add(209); - hands1.add(209); - hands1.add(209); - hands1.add(208); - - hands1.add(208); - hands1.add(207); - hands1.add(207); - - hands1.add(206); - hands1.add(205); - hands1.add(104); - - hands1.add(104); - // hands1.add(105); - //hands1.add(103); - //hands1.add(102); - - int card = 203; - huNanChangSha.changShaCardInhand.addAll(hands1); - TArray tiplist = new TArray(); - ITArray opcard = TArray.newInstance(); - opcard.addInt(102); - // opcard.addInt(205); - - // opcard.addInt(203); - TObject tob = new TObject(); - tob.putInt("weight", 3); - tob.putInt("id", 1); - tob.putInt("type", 4); - tob.putInt("card", card); - tob.putTArray("opcard", opcard); - //tiplist.addTObject(tob); - - ITArray opcard2 = TArray.newInstance(); - // opcard2.addInt(106); - opcard2.addInt(107); - TObject tob2 = new TObject(); - tob2.putInt("weight", 5); - tob2.putInt("id", 2); - tob2.putInt("type", 5); - tob2.putInt("card", card); - tob2.putTArray("opcard", opcard2); - // tiplist.addTObject(tob2); - - ITArray opcard3 = TArray.newInstance(); - opcard3.addInt(204); - opcard3.addInt(205); - TObject tob3 = new TObject(); - tob3.putInt("weight", 1); - tob3.putInt("id", 1); - tob3.putInt("type", 1); - tob3.putInt("card", card); - tob3.putTArray("opcard", opcard3); - tiplist.addTObject(tob3); - - - params.putTArray("tip_list", tiplist); - System.out.println(params); - //已经吃掉数据 - // huNanChangSha.chowGroup.add(205); - //huNanChangSha.chowGroup.add(204); - // huNanChangSha.chowGroup.add(206); - - //huNanChangSha.chowGroup.add(201); - // huNanChangSha.chowGroup.add(202); - // huNanChangSha.chowGroup.add(203); - // huNanChangSha.chowGroup.add(206); - //huNanChangSha.chowGroup.add(204); - //huNanChangSha.chowGroup.add(205); - String res = huNanChangSha.actionCard(params, tc); - System.out.println(res); - - */ - } - } diff --git a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/network/TaurusTcpListener.java b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/network/TaurusTcpListener.java deleted file mode 100644 index b1aaa18..0000000 --- a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/network/TaurusTcpListener.java +++ /dev/null @@ -1,113 +0,0 @@ -package robot.mj.network; - -import com.robot.MainServer; -import com.taurus.core.entity.ITObject; -import com.taurus.core.entity.TObject; -import com.taurus.core.util.Logger; -import com.taurus.permanent.data.Session; - -import java.util.concurrent.atomic.AtomicInteger; - -/** - * TCP监听器 - */ -public class TaurusTcpListener { - private static final Logger log = Logger.getLogger(TaurusTcpListener.class); - - private AtomicInteger connectionCount = new AtomicInteger(0); - private volatile boolean running = false; - - /** - * 启动TCP监听 - */ - public void start() { - if (running) { - log.warn("TCP监听已在运行中"); - return; - } - - try { - running = true; - log.info("基于Taurus框架的TCP监听已启动"); - - - } catch (Exception e) { - log.error("启动Taurus TCP监听失败", e); - } - } - - /** - * 停止TCP监听 - */ - public void stop() { - if (!running) { - return; - } - - try { - running = false; - log.info("Taurus TCP监听已停止"); - } catch (Exception e) { - log.error("停止Taurus TCP监听时发生错误", e); - } - } - - /** - * 处理新连接的欢迎消息 - */ - public void sendWelcomeMessage(Session session) { - try { - ITObject welcomeMsg = TObject.newInstance(); - welcomeMsg.putString("type", "welcome"); - welcomeMsg.putString("message", "连接到长沙麻将机器人服务器"); - welcomeMsg.putInt("server_id", 7701); - welcomeMsg.putLong("timestamp", System.currentTimeMillis()); - - MainServer.instance.sendResponse(0, 0, welcomeMsg, session); - - log.debug("已发送欢迎消息 - SessionId: {}", session.getId()); - - } catch (Exception e) { - log.error("发送欢迎消息失败", e); - } - } - - /** - * 处理客户端消息的通用方法 - */ - public void processAndRespond(Session session, ITObject requestData, int gid) { - try { - - ITObject response = TObject.newInstance(); - response.putString("type", "response"); - response.putTObject("original_data", requestData); - response.putBoolean("processed", true); - response.putLong("timestamp", System.currentTimeMillis()); - - //发送响应 - MainServer.instance.sendResponse(gid, 0, response, session); - - log.info("已发送响应 - SessionId: {}", session.getId()); - - } catch (Exception e) { - log.error("处理客户端消息时发生错误", e); - - //发送错误响应 - ITObject errorResponse = TObject.newInstance(); - errorResponse.putString("type", "error"); - errorResponse.putString("message", "处理请求时发生错误: " + e.getMessage()); - errorResponse.putLong("timestamp", System.currentTimeMillis()); - - MainServer.instance.sendResponse(gid, 1, errorResponse, session); - } - } - - - public boolean isRunning() { - return running; - } - - public int getConnectionCount() { - return connectionCount.get(); - } -} \ No newline at end of file diff --git a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/ChangShaSuanFaTest.java b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/ChangShaSuanFaTest.java index 17d893a..5e0ab90 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/ChangShaSuanFaTest.java +++ b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/ChangShaSuanFaTest.java @@ -3,10 +3,8 @@ package taurus.util; import com.robot.Util; import com.taurus.core.entity.ITArray; import com.taurus.core.entity.ITObject; -import com.taurus.core.entity.TArray; import com.taurus.core.entity.TObject; import com.taurus.core.util.Logger; -import org.w3c.dom.html.HTMLDOMImplementation; import java.awt.*; import java.util.*; @@ -36,7 +34,6 @@ public class ChangShaSuanFaTest { JIANG_PAIS = Collections.unmodifiableSet(jiangSet); } - /** * 统一日志输出方法 */ @@ -51,8 +48,6 @@ public class ChangShaSuanFaTest { log = Logger.getLogger(ChangShaSuanFaTest.class); } - - public String teshuXuanPai(List cardInhand, List pengCard, List chowGroup,List gangdepai){ String outcard = ""; //特殊牌型处理 @@ -180,7 +175,6 @@ public class ChangShaSuanFaTest { int pisCardsCount = countPairs(handCards);//分析七小对 //将将胡 boolean jiangHu = isJiangHu(handCards); - boolean isPengPengHu = hasThreeKeziAndTwoPairs(handCards, pengCard); //清一色碰碰胡 // boolean hasBigSuit = isAllSameSuit(handCards, pengCard); // 分析是否有可能的清一色花色 int hasBigSuit = checkDahu(handCards,chowGroup,pengCard,gangdepai); @@ -326,152 +320,6 @@ public class ChangShaSuanFaTest { } -// if (isTin) { -// System.out.println(" "); -// System.out.println("==============听牌牌组-=-==========" + tinCards); -// System.out.println("=========================drawnCards +++++++++++++++++++++++================" + drawnCards); -// List tin = new ArrayList<>(tinCards); -// System.out.println(" "); -// System.out.println("---------------tin--------------"+tin); -// ai ai1 = new ai(); -//// ChangshaMahjongAI ai = new ChangshaMahjongAI(); -// PlayerState playerState = new PlayerState(); -// playerState.handCards = pinghuhandCards; -// -// -// for (int j = 0; j < chowGroup.size(); j += 3) { -// List chigroup = new ArrayList<>(chowGroup.subList(j, Math.min(j + 3, chowGroup.size()))); -// if (chigroup.size() == 3) { -// playerState.addChiGroup(chigroup); -// } -// } -// -// -// for (int h = 0; h < pengCard.size(); h += 3) { -// List penggroup = new ArrayList<>(pengCard.subList(h, Math.min(h + 3, pengCard.size()))); -// if (penggroup.size() == 3) { -// playerState.addPongGroup(penggroup); -// } -// } -// -// -// int bestDiscard = ai1.findBestDiscard(playerState); -// -// -// if (bestDiscard != 0) { -// if (ai1.isTinAi) { -// isTin = true; -// } -// if (tin.size() chigroup = new ArrayList<>(chowGroup.subList(j, Math.min(j + 3, chowGroup.size()))); -// if (chigroup.size() == 3) { -// playerState.addChiGroup(chigroup); -// } -// } -// -// System.out.println("吃牌听牌playerState.chiGroups +++++++++++++++++++ " + playerState.chiGroups); -// System.out.println("吃牌听牌最新 ai出牌--------------------================"); -// for (int h = 0; h < pengCard.size(); h += 3) { -// List penggroup = new ArrayList<>(pengCard.subList(h, Math.min(h + 3, pengCard.size()))); -// if (penggroup.size() == 3) { -// playerState.addPongGroup(penggroup); -// } -// } -// -// -// int bestDiscard = ai1.findBestDiscard(playerState); -// -// -// if (bestDiscard != 0) { -// if (ai1.isTinAi) { -// isTin = true; -// isChi =false; -// } -// System.out.println("吃牌听牌出牌长麻 ++++++++++++++++++++++++++++++++++++++"); -// log.info("吃牌听牌出牌长麻==============================="+bestDiscard); -// return String.valueOf(bestDiscard); -// } -// } -// -// if (isPeng){ -// System.out.println("-----------碰牌听牌中-------"); -// ai ai1 = new ai(); -//// ChangshaMahjongAI ai = new ChangshaMahjongAI(); -// PlayerState playerState = new PlayerState(); -// playerState.handCards = handCards; -// System.out.println("碰牌听牌中chowGroup +++++++++++++++++++++++" + chowGroup); -// System.out.println("碰牌听牌中pengCard +++++++++++++++++++++++" + pengCard); -// -// for (int j = 0; j < chowGroup.size(); j += 3) { -// List chigroup = new ArrayList<>(chowGroup.subList(j, Math.min(j + 3, chowGroup.size()))); -// if (chigroup.size() == 3) { -// playerState.addChiGroup(chigroup); -// } -// } -// -// System.out.println("碰牌听牌中playerState.chiGroups +++++++++++++++++++ " + playerState.chiGroups); -// System.out.println("碰牌听牌中最新 ai出牌--------------------================"); -// for (int h = 0; h < pengCard.size(); h += 3) { -// List penggroup = new ArrayList<>(pengCard.subList(h, Math.min(h + 3, pengCard.size()))); -// if (penggroup.size() == 3) { -// playerState.addPongGroup(penggroup); -// } -// } -// -// -// int bestDiscard = ai1.findBestDiscard(playerState); -// -// -// if (bestDiscard != 0) { -// if (ai1.isTinAi) { -// isTin = true; -// isPeng =false; -// } -// System.out.println("碰牌听牌中出牌长麻 ++++++++++++++++++++++++++++++++++++++"); -// log.info("碰牌听牌中出牌长麻==============================="+bestDiscard); -// return String.valueOf(bestDiscard); -// } -// } - - - //将将胡 if (jiangHu && chowGroup.size() == 0) { logInfo("将将胡"); @@ -512,15 +360,6 @@ public class ChangShaSuanFaTest { } } - - - //boolean qysc = checkHandsQingYiSe(cardInhand,chowGroup,pengCard,gangdepai); - // System.out.println("qysc:"+qysc); - -// List checktingpai = TinHuChi.checktingpai(cardInhand); - - - //碰碰胡 List checktingpai1 = TinHuChi.checktingpai(cardInhand); @@ -602,7 +441,6 @@ public class ChangShaSuanFaTest { integer = selectBestCardByPriority(integers); - Map> mapduijiang = new HashMap<>(); int duijiangnum = checkduijiang(pinghuhandCards); @@ -755,49 +593,6 @@ public class ChangShaSuanFaTest { } - //先拆对子 - - //再拆门子 - - -// ai ai1 = new ai(); -//// ChangshaMahjongAI ai = new ChangshaMahjongAI(); -// PlayerState playerState = new PlayerState(); -// playerState.handCards = pinghuhandCards; -// System.out.println("chowGroup +++++++++++++++++++++++" + chowGroup); -// System.out.println("pengCard +++++++++++++++++++++++" + pengCard); -// -// for (int j = 0; j < chowGroup.size(); j += 3) { -// List chigroup = new ArrayList<>(chowGroup.subList(j, Math.min(j + 3, chowGroup.size()))); -// if (chigroup.size() == 3) { -// playerState.addChiGroup(chigroup); -// } -// } -// -// System.out.println("playerState.chiGroups +++++++++++++++++++ " + playerState.chiGroups); -// System.out.println("最新 ai出牌--------------------================"); -// for (int h = 0; h < pengCard.size(); h += 3) { -// List penggroup = new ArrayList<>(pengCard.subList(h, Math.min(h + 3, pengCard.size()))); -// if (penggroup.size() == 3) { -// playerState.addPongGroup(penggroup); -// } -// } - - - //int bestDiscard = ai1.findBestDiscard(playerState); - // System.out.println("bestDiscard:"+bestDiscard); - - /* if (bestDiscard != 0) { - if (ai1.isTinAi) { - isTin = true; - } - System.out.println("Ai出牌长麻 ++++++++++++++++++++++++++++++++++++++"); - log.info("Ai出牌长麻==============================="); - return String.valueOf(bestDiscard); - }*/ - - - // 1. 手牌分析 - 识别刻子、顺子、对子等牌型 HandAnalysis analysis = analyzeHand(pinghuhandCards1); @@ -961,71 +756,6 @@ public class ChangShaSuanFaTest { } //听牌之后去分析出牌 - private String isTinOutCard(List tinCards, List resultList) { - // 统计听牌组中每张牌在牌桌上的出现次数 - Map tinCardCountMap = new HashMap<>(); - - // 初始化听牌组中所有牌的出现次数为0 - for (Integer card : tinCards) { - tinCardCountMap.put(card, 0); - } - - // 统计听牌组中每张牌在牌桌上的实际出现次数 - for (Integer card : resultList) { - if (tinCardCountMap.containsKey(card)) { - tinCardCountMap.put(card, tinCardCountMap.get(card) + 1); - } - } - - // 找到最大的出现次数 - Integer maxCount = tinCardCountMap.values().stream() - .max(Integer::compareTo) - .orElse(0); - - // 判断所有听牌是否都大于等于3次 - boolean allGreaterOrEqualThree = !tinCardCountMap.isEmpty() && - tinCardCountMap.values().stream().allMatch(count -> count >= 3); - - if (allGreaterOrEqualThree) { - isTin = false; - // 如果所有听牌都出现大于等于3次,则随机出一张听牌 - Integer randomCard = tinCards.get(new Random().nextInt(tinCards.size())); - System.out.println("所有听牌出现次数都>=3,随机出牌: " + randomCard); - tinCards.remove(randomCard); - return "1"; - - - } - - if (maxCount > 0 && maxCount < 3 && tinCards.size() > 1) { - // 出现次数大于0但小于3,也直接出次数最多的牌 - List maxCards = tinCardCountMap.entrySet().stream() - .filter(entry -> entry.getValue().equals(maxCount)) - .map(Map.Entry::getKey) - .collect(Collectors.toList()); - - if (!maxCards.isEmpty()) { - isTin = false; - Integer maxCard = Collections.max(maxCards); - System.out.println("出现次数大于0,直接出牌: " + maxCard); - tinCards.remove(maxCard); - return "1"; - } - } else { - return String.valueOf(drawnCards); - } - - // 如果所有听牌在牌桌上都没出现过(maxCount为0),或者需要调整听牌状态 - if (maxCount == 0) { - //将tinCards转成map格式 - return String.valueOf(drawnCards); - } - - - // 返回一个默认值或处理逻辑(根据您的实际需求调整) - return "0"; - } - private List danzhang(List handCards) { // 统计每张牌出现的次数 Map cardCountMap = new HashMap<>(); @@ -1261,42 +991,6 @@ public class ChangShaSuanFaTest { return keziCount; } - - //分析碰碰胡是否听牌 - public boolean hasThreeKeziAndTwoPairs(List handCards, List pengCard) { - List handCards2 = new ArrayList<>(); - handCards2.addAll(handCards); -// handCards2.addAll(pengCard); - - // 统计每张牌出现的次数 - Map cardCountMap = new HashMap<>(); - for (Integer card : handCards2) { - cardCountMap.put(card, cardCountMap.getOrDefault(card, 0) + 1); - } - - int keziCount = 0; // 刻子数(三张相同) - int pairCount = 0; // 对子数(两张相同) - - // 统计刻子和对子 - for (int count : cardCountMap.values()) { - if (count >= 3) { - // 如果有3张或以上,可以算作一个刻子 - keziCount++; - // 如果有4张,剩余的1张不能算对子,但可能算单张 - if (count >= 4) { - // 4张可以看作1个刻子+1张单牌,或者如果有需要可以调整 - // 这里暂时不额外处理 - } - } else if (count == 2) { - pairCount++; - } - } - - // 检查是否有至少3个刻子和至少2个对子 - return keziCount >= 3 && pairCount >= 2; - } - - //拿出剩余牌 private static Map> separateKeziAndRemaining(List handCards) { List> keziList = new ArrayList<>(); @@ -1466,138 +1160,6 @@ public class ChangShaSuanFaTest { return handCards.get(0); } - - private String selectCardToDiscardPengPengHu(List handCards) { - logInfo("开始执行碰碰胡出牌策略"); - // 1. 复制手牌,避免修改原始数据 - List remainingCards = new ArrayList<>(handCards); - - // 2. 找出所有刻子(三张相同的牌),不重复利用 - List keziList = extractAllKezi(remainingCards); - int keziCount = keziList.size() / 3; - logInfo("找到刻子: " + keziCount + "组 - " + getKeziNames(keziList)); - - - //去除刻子后的牌 - List feiCandidates = findFeiJiangCandidates5(remainingCards); - logInfo("去除刻子后的牌: " + (feiCandidates)); - int i = selectFromFeiCandidates4(feiCandidates); - return String.valueOf(i); - } - - /** - * 找出非将牌候选(除了258将牌和刻子之外的牌) - */ - private List findFeiJiangCandidates5(List cards) { - Map cardCount = new HashMap<>(); - List feiJiangCandidates = new ArrayList<>(); - - // 统计剩余牌的数量 - for (Integer card : cards) { - cardCount.put(card, cardCount.getOrDefault(card, 0) + 1); - } - - - for (Map.Entry entry : cardCount.entrySet()) { - int card = entry.getKey(); - int count = entry.getValue(); - int value = card % 100; - - for (int i = 0; i < count; i++) { - feiJiangCandidates.add(card); - } - } - - return feiJiangCandidates; - } - - /** - * 从非将牌候选中选择要打出的牌 - * 优先打孤张,否则再拆牌 - */ - private int selectFromFeiCandidates4(List feiCandidates) { - if (feiCandidates.isEmpty()) { - return -1; // 或者抛出异常,根据实际情况处理 - } - - // 1. 优先找出非对子的牌 - Integer isolatedCard = findIsolatedCardInFei6(feiCandidates); - logInfo("策略: 打出孤张牌 " + getCardName(isolatedCard)); - return isolatedCard; - } - - private Integer findIsolatedCardInFei6(List feiCandidates) { - // 统计每张牌的出现次数 - Map countMap = new HashMap<>(); - for (int card : feiCandidates) { - countMap.put(card, countMap.getOrDefault(card, 0) + 1); - } - - // 寻找出现次数为 1 的牌(非对子) - for (int card : feiCandidates) { - if (countMap.get(card) == 1) { - return card; - } - } - - // 如果没有非对子的牌,返回 null 或选择第一张牌等策略 - return feiCandidates.get(0); - } - - - private String getKeziNames(List keziList) { - if (keziList.isEmpty()) return "无"; - - Set keziNames = new HashSet<>(); - for (int i = 0; i < keziList.size(); i += 3) { - keziNames.add(getCardName(keziList.get(i))); - } - return String.join(", ", keziNames); - } - - /** - * 提取所有刻子(三张相同的牌),不重复利用 - */ - private List extractAllKezi(List cards) { - List keziList = new ArrayList<>(); - Map cardCount = new HashMap<>(); - - // 统计每张牌的数量 - for (Integer card : cards) { - cardCount.put(card, cardCount.getOrDefault(card, 0) + 1); - } - - // 找出所有数量>=3的牌,提取刻子 - List cardsToRemove = new ArrayList<>(); - for (Map.Entry entry : cardCount.entrySet()) { - int card = entry.getKey(); - int count = entry.getValue(); - - if (count >= 3) { - // 计算可以组成几个刻子(比如4张相同的牌可以组成1个刻子+1张单牌) - int keziGroups = count / 3; - for (int i = 0; i < keziGroups; i++) { - // 添加3次相同的牌表示一个刻子 - keziList.add(card); - keziList.add(card); - keziList.add(card); - } - // 标记需要从剩余牌中移除的牌(只移除刻子部分) - for (int i = 0; i < keziGroups * 3; i++) { - cardsToRemove.add(card); - } - } - } - - // 从剩余牌中移除刻子 - for (Integer card : cardsToRemove) { - cards.remove(card); - } - - return keziList; - } - - /** * 最终出的牌 * 优化后的分析逻辑: @@ -1827,301 +1389,6 @@ public class ChangShaSuanFaTest { } - /** - * 碰牌判断方法 - * - * @param opcard 要碰的牌 - * @param handCards 当前手牌 - * @return 是否允许碰牌 - */ - public boolean shouldPong(int opcard, List handCards) { - // 1. 判断是否有至少两张相同的牌可以碰 - int count = 0; - for (int card : handCards) { - if (card == opcard) { - count++; - } - } - if (count < 2) { - return false; - } - - // 2. 如果是清一色花色,只能碰相同花色的牌 - if (isAllSameSuit1(handCards)) { - Integer mainSuit = getMainSuit(handCards); - int opcardSuit = opcard / 100; - if (mainSuit != null && mainSuit != opcardSuit) { - logInfo("清一色模式:不能碰不同花色的牌。目标牌花色:" + getSuitName(opcardSuit) + ", 主花色:" + getSuitName(mainSuit)); - return false; - } - } - - // 2. 复制手牌并模拟去掉要碰的两张牌 - List tempHand = new ArrayList<>(handCards); - tempHand.remove(Integer.valueOf(opcard)); - tempHand.remove(Integer.valueOf(opcard)); - - // 3. 检查该牌是否是听牌组中的牌 - List tingCards = calculateTingCards(tempHand); - if (tingCards.contains(opcard)) { - return false; - } - - // 4. 检查该牌是否是顺子的一部分 - if (isPartOfSequence(opcard, handCards)) { - return false; - } - - // 5. 检查该牌是否是唯一的将牌 - if (isOnlyPair(tempHand, opcard)) { - return false; - } - - // 其他情况允许碰牌 - return true; - } - - /** - * 吃牌判断方法 - * - * @param opcard 要吃的牌 - * @param handCards 当前手牌 - * @return 是否允许吃牌 - */ - public boolean shouldChow(int opcard, List handCards) { - logInfo("吃牌判断开始, 目标牌: " + opcard + ", 当前手牌: " + handCards); - - // 1. 如果是清一色花色,只能吃相同花色的牌 - if (isAllSameSuit1(handCards)) { - Integer mainSuit = getMainSuit(handCards); - int opcardSuit = opcard / 100; - if (mainSuit != null && mainSuit != opcardSuit) { - logInfo("清一色模式:不能吃不同花色的牌。目标牌花色:" + getSuitName(opcardSuit) + ", 主花色:" + getSuitName(mainSuit)); - return false; - } - } - - // 创建手牌的副本,避免修改原手牌 - List handCopy = new ArrayList<>(handCards); - - // 分析手牌,识别刻子和顺子 - HandAnalysis analysis = analyzeHand(handCopy); - - // 获取剩余牌(未用于刻子或顺子的牌) - List remainingCards = analysis.remainingCards; - - // 检查剩余牌是否能与其他两张牌组成包含opcard的顺子 - boolean canChow = canFormChow(opcard, remainingCards); - - logInfo("吃牌判断结束, 结果: " + canChow); - return canChow; - } - - /** - * 检查是否能形成包含目标牌的顺子 - * @param targetCard 目标牌 - * @param handCards 手牌 - * @return 是否能吃牌 - */ - - /** - * 判断是否应该杠牌(补牌) - * - * @param proposedCard 要杠的牌 - * @param currentHand 当前手牌 - * @param (1:暗杠, 2:明杠, 3:加杠, 4:补杠等) - * @return 是否应该杠牌 - */ - public boolean shouldGang(int proposedCard, List currentHand) { - logInfo("判断是否应该杠牌: " + proposedCard); - - // 1. 如果是清一色花色,只能杠相同花色的牌 - if (isAllSameSuit1(currentHand)) { - Integer mainSuit = getMainSuit(currentHand); - int proposedCardSuit = proposedCard / 100; - if (mainSuit != null && mainSuit != proposedCardSuit) { - logInfo("清一色模式:不能杠不同花色的牌。目标牌花色:" + getSuitName(proposedCardSuit) + ", 主花色:" + getSuitName(mainSuit)); - return false; - } - } - - // 基础杠牌条件:手牌中至少有3张相同的牌 - int count = 0; - for (int card : currentHand) { - if (card == proposedCard) { - count++; - } - } - - if (count < 3) { - logInfo("手牌中没有足够的相同牌来杠"); - return false; - } - - // 这里可以添加更多杠牌决策逻辑,目前只实现清一色优化 - return true; - } - - - private boolean canFormChow(int targetCard, List handCards) { - // 检查是否是字牌(风牌或箭牌),字牌不能组成顺子 - int suit = targetCard / 100; - if (suit == 4 || suit == 5) { // 4是风牌,5是箭牌 - return false; - } - - // 获取目标牌的点数 - int targetPoint = targetCard % 100; - - // 统计手牌中每张牌的数量 - Map cardCounts = new HashMap<>(); - for (int card : handCards) { - cardCounts.put(card, cardCounts.getOrDefault(card, 0) + 1); - } - - // 检查三种可能的顺子组合 - // 1. targetCard-2, targetCard-1, targetCard - if (targetPoint >= 3) { - int card1 = suit * 100 + (targetPoint - 2); - int card2 = suit * 100 + (targetPoint - 1); - if (cardCounts.containsKey(card1) && cardCounts.containsKey(card2)) { - return true; - } - } - - // 2. targetCard-1, targetCard, targetCard+1 - if (targetPoint >= 2 && targetPoint <= 8) { - int card1 = suit * 100 + (targetPoint - 1); - int card2 = suit * 100 + (targetPoint + 1); - if (cardCounts.containsKey(card1) && cardCounts.containsKey(card2)) { - return true; - } - } - - // 3. targetCard, targetCard+1, targetCard+2 - if (targetPoint <= 7) { - int card1 = suit * 100 + (targetPoint + 1); - int card2 = suit * 100 + (targetPoint + 2); - if (cardCounts.containsKey(card1) && cardCounts.containsKey(card2)) { - return true; - } - } - - return false; - } - - - /** - * 计算听牌 - * - * @param handCards 手牌 - * @return 听牌列表 - */ - private List calculateTingCards(List handCards) { - List tingCards = new ArrayList<>(); - Map cardCount = countCards(handCards); - - // 检查每种花色的牌 - for (int suit = 1; suit <= 3; suit++) { // 1:万, 2:筒, 3:索 - List sameSuitCards = new ArrayList<>(); - for (int rank = 1; rank <= 9; rank++) { - int card = suit * 100 + rank; - int count = cardCount.getOrDefault(card, 0); - for (int i = 0; i < count; i++) { - sameSuitCards.add(rank); - } - } - - // 检查是否有搭子需要补牌 - if (sameSuitCards.size() > 0) { - // 简单检查:如果有单张牌,可能听它的相邻牌或相同牌 - Map rankCount = new HashMap<>(); - for (int rank : sameSuitCards) { - rankCount.put(rank, rankCount.getOrDefault(rank, 0) + 1); - } - - for (Map.Entry entry : rankCount.entrySet()) { - int rank = entry.getKey(); - int count = entry.getValue(); - - // 如果是单张或对子,可能需要补牌 - if (count == 1 || count == 2) { - // 添加当前牌(可能组成刻子) - tingCards.add(suit * 100 + rank); - - // 添加相邻牌(可能组成顺子) - if (rank > 1) { - tingCards.add(suit * 100 + (rank - 1)); - } - if (rank < 9) { - tingCards.add(suit * 100 + (rank + 1)); - } - } - } - } - } - - return tingCards; - } - - /** - * 判断是否是顺子的一部分 - * - * @param card 要判断的牌 - * @param handCards 手牌 - * @return 是否是顺子的一部分 - */ - private boolean isPartOfSequence(int card, List handCards) { - int suit = card / 100; - int rank = card % 100; - - // 检查是否存在顺子 - // 顺子是三个连续的牌,比如1-2-3,2-3-4等 - boolean hasPrevPrev = handCards.contains(suit * 100 + rank - 2); - boolean hasPrev = handCards.contains(suit * 100 + rank - 1); - boolean hasNext = handCards.contains(suit * 100 + rank + 1); - boolean hasNextNext = handCards.contains(suit * 100 + rank + 2); - - // 检查是否是顺子的中间牌或边牌 - return (hasPrev && hasNext) || (hasPrevPrev && hasPrev) || (hasNext && hasNextNext); - } - - /** - * 判断是否是唯一的将牌 - * - * @param tempHand 去掉两张要碰的牌后的手牌 - * @param opcard 要碰的牌 - * @return 是否是唯一的将牌 - */ - public boolean isOnlyPair(List tempHand, int opcard) { - Map cardCount = countCards(tempHand); - int pairCount = 0; - - for (Map.Entry entry : cardCount.entrySet()) { - if (entry.getValue() == 2) { - pairCount++; - } - } - - // 如果去掉要碰的牌后没有对子,说明原来的牌是唯一的将牌 - return pairCount == 0; - } - - /** - * 统计每张牌的数量 - * - * @param handCards 手牌 - * @return 牌的数量映射 - */ - private Map countCards(List handCards) { - Map cardCount = new HashMap<>(); - for (int card : handCards) { - cardCount.put(card, cardCount.getOrDefault(card, 0) + 1); - } - return cardCount; - } - - //大胡分析七小对 public static int countPairs(List handCards) { // 1. 先根据花色和点数排序 @@ -2223,142 +1490,6 @@ public class ChangShaSuanFaTest { return pairCount >= 4; } - //分析清一色 - public boolean isAllSameSuit(List handCards, List pengCard) { - // 统计各花色的牌数量 - Map suitCountMap = new HashMap<>(); - List handCards2 = new ArrayList<>(); - handCards2.addAll(handCards); -// handCards2.addAll(pengCard); - - for (Integer card : handCards2) { - 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 >= 10) { - String suitName = getSuitName(suit); - logInfo("检测到可能的清一色花色: " + suitName + ", 数量: " + count); - return true; - } - } - - return false; - } - - /** - * 检测当前牌 是否符合清一色 - * @param card - * @param handCards - * @param pengguopai - * @param chipai - * @param gangpai - * @return - */ - public static boolean checkAllSameSuitAll(int card, List handCards, List pengguopai, List chipai, List gangpai) { - //判断 peng,chi ,gang是否有不同色 - //true 为可以 false 为不能 - List cpg = new ArrayList<>(); - cpg.addAll(pengguopai); - cpg.addAll(chipai); - cpg.addAll(gangpai); - if (cpg.size()>0){ - int tmp1 = 0; - int tmp2 = 0; - for (int i=0;i10){ - //落地已经有了不同色,所以可以进行 - return true; - - } - } - } - //加入之后 - cpg.add(card); - if (cpg.size()>1){ - int tmp3 = 0; - int tmp4 = 0; - for (int i=0;i10){ - //牌 加入已经破坏手牌 - return false; - } - } - } - cpg.clear(); - //判断手牌 - if(handCards.size()>3){ - //手牌判断 - // 统计各花色的牌数量 - Map suitCountMap = new HashMap<>(); - for (Integer cards : handCards) { - int suit = cards / 100; // 获取花色,100=万,200=筒,300=条 - suitCountMap.put(suit, suitCountMap.getOrDefault(suit, 0) + 1); - } - - for (Map.Entry entry : suitCountMap.entrySet()) { - int suit = entry.getKey(); - int count = entry.getValue(); - - if (handCards.size()==4){ - //手牌只有4张 - if (count >= 2) { - //当手牌已经剩下4张时候,可以进行 - return true; - } - } - - if (count >= handCards.size()-3) { - int tmpsuit = card / 100; - if (suit == tmpsuit){ - return true; - } - } - } - } - return false; - } - - - - //分析清一色 - public boolean isAllSameSuit1(List handCards) { - // 统计各花色的牌数量 - Map suitCountMap = new HashMap<>(); - - for (Integer card : handCards) { - int suit = card / 100; // 获取花色,100=万,200=筒,300=条 - suitCountMap.put(suit, suitCountMap.getOrDefault(suit, 0) + 1); - } - - - for (Map.Entry entry : suitCountMap.entrySet()) { - int suit = entry.getKey(); - - int count = entry.getValue(); - - - if (count >= 11) { - String suitName = getSuitName(suit); - logInfo("检测到可能的清一色花色: " + suitName + ", 数量: " + count); - return true; - } - } - - return false; - } - - // 获取主要花色(数量最多且≥9张的花色) public Integer getMainSuit(List handCards) { Map suitCountMap = new HashMap<>(); @@ -2384,8 +1515,6 @@ public class ChangShaSuanFaTest { return mainSuit; } - // 清一色特定出牌策略 - /** * 基于花色分析的清一色七小对出牌策略 * 优先打出花色最少的牌,以优化七小对的形成 @@ -2724,127 +1853,6 @@ public class ChangShaSuanFaTest { } - public boolean isAllSameSuit(List handCards, Integer mainSuit) { - // 提取主花色牌 - List mainSuitCards = new ArrayList<>(); - for (Integer card : handCards) { - int suit = card / 100; - if (suit == mainSuit) { - mainSuitCards.add(card); - } - } - - Map>> stringListMap = analyzeMainSuitPatterns(mainSuitCards); - - List> sequences = stringListMap.get("sequences"); // 顺子列表 - List> triplets = stringListMap.get("triplets"); // 刻子列表 - List> pairs = stringListMap.get("pairs"); // 对子列表 - - // 获取数量 - int sequenceCount = sequences.size(); - int tripletCount = triplets.size(); - - -// 判断顺子加上刻子的数量是否大于6 - boolean isSequenceAndTripletGreaterThan6 = (sequenceCount + tripletCount) > 6; - - return isSequenceAndTripletGreaterThan6; - } - - - /** - * 分析主花色牌组中的顺子、刻子、对子 - * - * @param mainSuitCards 主花色牌组 - * @return 包含顺子、刻子、对子信息的Map - */ - private Map>> analyzeMainSuitPatterns(List mainSuitCards) { - Map>> patterns = new HashMap<>(); - patterns.put("sequences", new ArrayList<>()); // 顺子 - patterns.put("triplets", new ArrayList<>()); // 刻子 - patterns.put("pairs", new ArrayList<>()); // 对子 - - if (mainSuitCards == null || mainSuitCards.isEmpty()) { - return patterns; - } - - // 提取所有点数 - List points = new ArrayList<>(); - for (Integer card : mainSuitCards) { - int point = card % 100; - points.add(point); - } - Collections.sort(points); - - // 统计每个点数的数量 - Map pointCountMap = new HashMap<>(); - for (Integer point : points) { - pointCountMap.put(point, pointCountMap.getOrDefault(point, 0) + 1); - } - - // 找出刻子(三张相同的牌) - for (Map.Entry entry : pointCountMap.entrySet()) { - if (entry.getValue() >= 3) { - List triplet = new ArrayList<>(); - for (int i = 0; i < 3; i++) { - triplet.add(entry.getKey()); - } - patterns.get("triplets").add(triplet); - } - } - - // 找出对子 - for (Map.Entry entry : pointCountMap.entrySet()) { - if (entry.getValue() >= 2) { - List pair = new ArrayList<>(); - for (int i = 0; i < 2; i++) { - pair.add(entry.getKey()); - } - patterns.get("pairs").add(pair); - } - } - - // 找出顺子(需要从剩余牌中找) - // 先复制一份牌用于顺子检测(避免刻子/对子使用的牌影响顺子检测) - List remainingPoints = new ArrayList<>(points); - - // 移除刻子使用的牌(如果有的话) - for (List triplet : patterns.get("triplets")) { - int point = triplet.get(0); - for (int i = 0; i < 3; i++) { - remainingPoints.remove((Integer) point); - } - } - - // 检查顺子 - for (int start = 1; start <= 7; start++) { - boolean canFormSequence = true; - List tempPoints = new ArrayList<>(remainingPoints); - List sequence = new ArrayList<>(); - - // 检查是否有连续的3个点数 - for (int i = 0; i < 3; i++) { - int currentPoint = start + i; - if (!tempPoints.remove((Integer) currentPoint)) { - canFormSequence = false; - break; - } - sequence.add(currentPoint); - } - - if (canFormSequence) { - patterns.get("sequences").add(sequence); - // 从剩余牌中移除这三个点数 - for (int i = 0; i < 3; i++) { - remainingPoints.remove((Integer) (start + i)); - } - } - } - - return patterns; - } - - /** * 选择非主要花色牌打出 */ @@ -2986,40 +1994,6 @@ public class ChangShaSuanFaTest { return value2 == value1 + 1 && value3 == value2 + 1; } - /** - * 找出并移除将牌(258对子) - */ - private void findAndRemoveJiang(List cards, List jiang) { - Map tempCount = new HashMap<>(); - for (Integer card : cards) { - tempCount.put(card, tempCount.getOrDefault(card, 0) + 1); - } - - // 优先找258对子作为将牌 - for (Integer card : cards) { - int value = card % 100; - if ((value == 2 || value == 5 || value == 8) && tempCount.get(card) >= 2) { - // 找到将牌 - jiang.add(card); - jiang.add(card); - cards.remove(card); - cards.remove(card); - return; - } - } - - // 如果没有258对子,找任意对子作为将牌 - for (Integer card : cards) { - if (tempCount.get(card) >= 2) { - jiang.add(card); - jiang.add(card); - cards.remove(card); - cards.remove(card); - return; - } - } - } - /** * 从剩余牌中选择要打出的牌 */ @@ -3760,198 +2734,6 @@ public class ChangShaSuanFaTest { return minShanten; } - - public static int analyzeHandCards(List handCards) { - if (handCards == null || handCards.size() != 14) { - System.out.println("错误:手牌必须是14张"); - return 0; - } - - System.out.println("当前手牌(14张): " + convertToReadable(handCards)); - System.out.println("======================================"); - - - - // 2. 分析手牌结构 - List sortedHand = new ArrayList<>(handCards); - Collections.sort(sortedHand); - - System.out.println("\n=== 手牌结构分析 ==="); - - // 找出所有刻子 - List> kezis = findKezis(sortedHand); - System.out.println("刻子(" + kezis.size() + "组):"); - for (List kezi : kezis) { - System.out.println(" " + convertToReadable(kezi)); - } - - // 找出所有顺子 - List> shunzis = findShunzis(sortedHand); - System.out.println("\n顺子(" + shunzis.size() + "组):"); - for (List shunzi : shunzis) { - System.out.println(" " + convertToReadable(shunzi)); - } - - // 找出所有258将牌 - List jiangCandidates = findJiangCandidates(sortedHand); - System.out.println("\n258将牌候选(" + jiangCandidates.size() + "张):"); - System.out.println(" " + convertToReadable(jiangCandidates)); - - if (kezis.size()>0 || shunzis.size()>0 || jiangCandidates.size()>0){ - return kezis.size()+shunzis.size(); - } - - return 0; - - } - - - - /** - * 找出所有刻子 - */ - private static List> findKezis(List handCards) { - List> kezis = new ArrayList<>(); - List temp = new ArrayList<>(handCards); - - while (!temp.isEmpty()) { - int card = temp.get(0); - int count = Collections.frequency(temp, card); - - if (count >= 3) { - List kezi = new ArrayList<>(); - kezi.add(card); - kezi.add(card); - kezi.add(card); - kezis.add(kezi); - - // 移除这3张牌 - for (int i = 0; i < 3; i++) { - temp.remove(Integer.valueOf(card)); - } - } else { - temp.remove(Integer.valueOf(card)); - } - } - - return kezis; - } - - /** - * 找出所有顺子 - */ - private static List> findShunzis(List handCards) { - List> shunzis = new ArrayList<>(); - List temp = new ArrayList<>(handCards); - - // 先移除已找到的刻子 - List> kezis = findKezis(handCards); - for (List kezi : kezis) { - for (int i = 0; i < 3; i++) { - temp.remove(Integer.valueOf(kezi.get(0))); - } - } - - // 找顺子 - Collections.sort(temp); - - for (int i = 0; i < temp.size(); i++) { - int card1 = temp.get(i); - int type = getCardType(card1); - int value = getCardValue(card1); - - if (type <= 3 && value <= 7) { - int card2 = card1 + 1; - int card3 = card1 + 2; - - if (temp.contains(card2) && temp.contains(card3)) { - List shunzi = new ArrayList<>(); - shunzi.add(card1); - shunzi.add(card2); - shunzi.add(card3); - shunzis.add(shunzi); - - // 移除这3张牌 - temp.remove(Integer.valueOf(card1)); - temp.remove(Integer.valueOf(card2)); - temp.remove(Integer.valueOf(card3)); - i--; // 因为移除了元素 - } - } - } - - return shunzis; - } - - /** - * 找出258将牌候选 - */ - private static List findJiangCandidates(List handCards) { - List jiangs = new ArrayList<>(); - - for (int card : handCards) { - int value = getCardValue(card); - if (JIANG_PAIS.contains(value)) { - jiangs.add(card); - } - } - - return jiangs; - } - - - /** - * 获取牌值 - */ - private static int getCardValue(int card) { - return card % 10; - } - - /** - * 获取牌类型 - */ - private static int getCardType(int card) { - return card / 100; - } - - /** - * 格式化单张牌 - */ - private static String formatCard(int card) { - int type = getCardType(card); - int value = getCardValue(card); - switch (type) { - case 1: - return value + "万"; - case 2: - return value + "筒"; - case 3: - return value + "条"; - default: - return "字牌" + value; - } - } - - /** - * 转换为可读格式 - */ - private static String convertToReadable(List cards) { - if (cards == null || cards.isEmpty()) { - return "空"; - } - - List cardStrs = new ArrayList<>(); - for (int card : cards) { - cardStrs.add(formatCard(card)); - } - return String.join(" ", cardStrs); - } - - - public List chuguodepai() { - return chuguodepai; - } - public static boolean isJiangPai(int card) { if (card % 100 == 2 || card % 100 == 5 || card % 100 == 8) { return true; @@ -3973,107 +2755,6 @@ public class ChangShaSuanFaTest { return jiangnum; } - public static int checkChiTingAction(int card,List changShaCardInhand){ - //判断吃之后能否下听 - List> lists = new ArrayList<>(); - lists.addAll(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){ - return flag; - } - - return 0; - } - - - - public static int checkCanChiAction(int card,List changShaCardInhand){ - //吃之后也不能听 - Map map = new HashMap<>(); - Map map2 = new HashMap<>(); - //吃之前的逻辑 - List> lists1 = TinHuChi.checkChi(changShaCardInhand, card); - - int jiangnum = checkduijiang(changShaCardInhand); - List tmpChangSch = new ArrayList<>(); - tmpChangSch.addAll(changShaCardInhand); - tmpChangSch.add(card); - ChangshaWinSplitCard.checkNormalHu(tmpChangSch, map); - - System.out.println("checkNormalHu" + map.get("cardResiue")); - 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()) < Integer.parseInt(map.get("remainingMelds").toString())) { - flag1 = index1 + 1; - } else if (Integer.parseInt(map2.get("remainingMelds").toString()) == 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; - } - //如果手里没有将,则可以吃 - if (jiangnum > 0) { - int chihoujiangnum = checkduijiang(temphand); - if (chihoujiangnum > 0) { - //吃之后还有将 - flag1 = index1 + 1; - } - } else { - System.out.println("没队将"); - //孤章1张 差一手 不是将 而且card不是将 - if (Integer.parseInt(map.get("remainingMelds").toString()) == 1 && size1 == 1 && !isJiangPai(((List) map.get("cardResiue")).get(0)) && !isJiangPai(card)) { - //吃 - break; - } - flag1 = index1 + 1; - // break; - } - } - index1++; - } - - if (flag1 > 0) { - return flag1; - } - return 0; - } - /** * * @param handcards @@ -4737,12 +3418,6 @@ public class ChangShaSuanFaTest { return chiob; } - public static boolean shiFouJieTing(List tingList,List changShachuguopai ){ - - - return false; - } - public static int getTingPainum(List caozq, List changShachuguopai){ int num = 0; for (int i=0;i test1 = new ArrayList(); - - test1.add(209); - test1.add(208); - test1.add(207); - test1.add(203); - - test1.add(201); - test1.add(109); - test1.add(107); - - test1.add(107); - test1.add(107); - test1.add(105); - - test1.add(105); - test1.add(104); - test1.add(103); - - int lg = countPairs(test1); - System.out.println(lg); - //int card = 206; - //int flag = checkChiTingAction(card,test1); - //System.out.println(flag); - - //测试吃: - List allcard = new ArrayList<>(); - /* allcard.add(201); - allcard.add(201); - allcard.add(109); - allcard.add(109); - allcard.add(104); - allcard.add(104); - allcard.add(104); - //allcard.add(104);*/ - /*ITArray opcard = TArray.newInstance(); - opcard.addInt(209); - opcard.addInt(208);*/ - - List chipai = new ArrayList<>(); - /* chipai.add(101); - chipai.add(102); - chipai.add(103); - - - chipai.add(102); - chipai.add(103); - chipai.add(104);*/ - // int card = 202; - - ListchangShachuguopai = new ArrayList<>(); - //changShachuguopai.add(101); - /* changShachuguopai.add(202); - changShachuguopai.add(201); - changShachuguopai.add(203); - changShachuguopai.add(105); - changShachuguopai.add(105); - changShachuguopai.add(105);*/ - changShachuguopai.addAll(allcard); - - List gangguopai = new ArrayList<>(); - - // gangguopai.add(108);0 - - int card = 106; - ListpengCard = new ArrayList<>(); - /*pengCard.add(203); - pengCard.add(203); - pengCard.add(203); - - pengCard.add(101); - pengCard.add(101); - pengCard.add(101);*/ - - //出牌求优 - ChangShaSuanFaTest ct = new ChangShaSuanFaTest(); - test1.add(card); - String outcard = ct.outCardSuanFa(test1,pengCard,chipai,gangguopai,changShachuguopai); - - System.out.println("outcard:"+outcard); - - // pingguChi(false,card,opcard,test1,0,allcard,chipai,changShachuguopai); - - //测试碰 - // int card = 102; - ITArray opcardpeng = TArray.newInstance(); - opcardpeng.addInt(203); - - List pengpai = new ArrayList<>(); - List gangpai = new ArrayList<>(); - - //pingguPeng(true,card,opcardpeng,test1,0,allcard,chipai,pengpai,gangpai,changShachuguopai); - /* - //Listtf = handscardshifoutingpai(test1); - // System.out.println(tf); - //Map map = new HashMap<>(); - //map = quyizhangChayou(test1); - // System.out.println(map); - - /*Map> maps = new HashMap<>(); - maps = quyizhangTingPai(test1); - System.out.println(maps);*/ - // test1.add(202); - // test1.add(209); - // test1.add(201); - - // test1.add(208); - // test1.add(207); - // test1.add(209); - - // test1.add(104); - - // test1.add(203); - // test1.add(202); - // test1.add(201); -// test1.add(103); -// test1.add(102); - - /* - int card = 201; - List pengguopai = new ArrayList<>(); - pengguopai.add(204); - pengguopai.add(204); - pengguopai.add(204); - List chipai = new ArrayList<>(); - chipai.add(203); - chipai.add(202); - chipai.add(201); - List gangguopai = new ArrayList<>(); - gangguopai.add(206); - gangguopai.add(206); - gangguopai.add(206); - gangguopai.add(206); - - System.out.println("手牌:" + test1); - boolean c = checkAllSameSuitAll(card,test1,pengguopai,chipai,gangguopai); - System.out.println(c); - */ - -// if (!bestDiscard.isEmpty()) { -// System.out.println("建议出牌:" + bestDiscard.get(0)); -// } else { -// System.out.println("没有出牌建议"); -// } - } } diff --git a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/ChangshaWinSplitCard.java b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/ChangshaWinSplitCard.java index 4731988..f4f2a6f 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/ChangshaWinSplitCard.java +++ b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/ChangshaWinSplitCard.java @@ -3,77 +3,6 @@ package taurus.util; import java.util.*; public class ChangshaWinSplitCard { - // 获取数值 - // 获取数值 - public static int GetCardValue(int cbCardData) { - return cbCardData % 100; - } - - // 获取花色 - public static int GetCardColor(int cbCardData) { - return cbCardData / 100; - } - - // 扑克转换 - public static int SwitchToCardData(int cbCardIndex) { - int cbCardColor = cbCardIndex / 10; - int cbCardValue = cbCardIndex % 10; - if (cbCardIndex < 27) { // 9 -> 200 + 1 //10 -> 202 //11 -> 203 // 17 -> 209 // 18 -> 301 19->302 20 -> - // 303 26->309 - if (cbCardValue + (cbCardColor + 1) >= 10) { - return (cbCardColor + 2) * 100 + (cbCardValue + (cbCardColor + 1)) % 10 + 1; - } else { - return (cbCardColor + 1) * 100 + cbCardValue + (cbCardColor + 1); - } - } else { // 27 -> 400 //28 -> 403 // 29 -> 406 // 30 -> 409 //31 -> 412 // 32 -> 415 // - // 33 -> 418 - if (cbCardValue + (cbCardColor + 1) >= 10) { - return (cbCardColor + 2) * 100 + (cbCardValue + (cbCardColor + 1)) % 10 * 3; - } else { - return (cbCardColor + 1) * 100 + (cbCardValue + cbCardColor) * 3; - } - } - } - - // 扑克转换 - public static int SwitchToCardIndex(int cbCardData) { - // 扑克属性 - int cbCardColor = GetCardColor(cbCardData); - int cbCardValue = GetCardValue(cbCardData); - if (cbCardColor <= 3) { - return (cbCardColor - 1) * 10 + cbCardValue - cbCardColor; - } else { - return (cbCardColor - 1) * 10 + cbCardValue / 3 - cbCardColor + 1; - } - } - - // 扑克转换 - public static int[] SwitchToCardData(List cardInhand) { - int[] cardIndex = new int[34]; - for (int i = 0; i < cardIndex.length; i++) { - cardIndex[i] = 0; - } - - for (int i = 0; i < cardInhand.size(); i++) { - - int pos = SwitchToCardIndex(cardInhand.get(i)); - cardIndex[pos]++; - } - - return cardIndex; - } - - // 扑克转换 - public static List SwitchToCardIndex(int[] cardIndex) { - List cardIndexList = new ArrayList(); - for (int i = 0; i < cardIndex.length; i++) { - for (int j = 0; j < cardIndex[i]; j++) { - int card = SwitchToCardData(i); - cardIndexList.add(card); - } - } - return cardIndexList; - } // 统计牌数 public static int[][] countTiles(List cardInHand) { @@ -448,16 +377,6 @@ public class ChangshaWinSplitCard { return cardInHand; } - public static int ckeckOutCard(List cardInhand) { - int card = 0; - Collections.sort(cardInhand); - System.out.println("手牌:" + cardInhand); - Map map = new HashMap(); - checkNormalHu(cardInhand, map); - - return card; - } - public static List checktingpai(List cardhand) { List tpcards = new ArrayList<>(); List tmphc = cardhand; @@ -486,30 +405,6 @@ public class ChangshaWinSplitCard { return tpcards; } - public static boolean isJiangPai(int card) { - if (card % 100 == 2 || card % 100 == 5 || card % 100 == 8) { - return true; - } - return false; - } - - public static int checkduijiang(List cardInHand, Map> map) { - Map countMap = new HashMap<>(); - for (Integer item : cardInHand) { - countMap.put(item, countMap.getOrDefault(item, 0) + 1); - } - int jiangnum = 0; - for (int key : countMap.keySet()) { - if (isJiangPai(key) && countMap.get(key) >= 2) { - jiangnum++; - List tmpI = new ArrayList<>(); - tmpI.add(key); - map.put("jiangcard", tmpI); - } - } - return jiangnum; - } - // 分析最优出牌 public static List analyzeBestDiscard(List cardInHand) { @@ -635,89 +530,6 @@ public class ChangshaWinSplitCard { return zuizhongchupai; } - // 计算听牌数量(简化版,只计算数量不具体分析是哪些牌) - private static int countTingCards(List hand) { - int tingCount = 0; - - // 只尝试添加万、筒、条牌(1-9) - for (int type = 1; type <= 3; type++) { - for (int value = 1; value <= 9; value++) { - int testCard = type * 100 + value; - - // 模拟添加这张牌 - List testHand = new ArrayList<>(hand); - testHand.add(testCard); - Collections.sort(testHand); - - // 检查是否能胡牌 - Map testMap = new HashMap<>(); - if (checkNormalHu(testHand, testMap) == 0) { - tingCount++; - } - } - } - - // 风牌和箭牌(可能性较小,但也要考虑) - for (int type = 4; type <= 5; type++) { - int max = (type == 4) ? 4 : 3; - for (int value = 1; value <= max; value++) { - int testCard = type * 100 + value; - - List testHand = new ArrayList<>(hand); - testHand.add(testCard); - Collections.sort(testHand); - - Map testMap = new HashMap<>(); - if (checkNormalHu(testHand, testMap) == 0) { - tingCount++; - } - } - } - - return tingCount; - } - - // 或者使用更简洁的lambda写法(确保能进入) -// 或者更灵活的版本,可以指定优先级 - public static Integer selectBestCardByPriority(List cards) { - if (cards == null || cards.isEmpty()) { - return null; - } - - Integer bestCard = null; - int bestPriority = Integer.MAX_VALUE; - - for (Integer card : cards) { - int value = card % 100; - int priority = getCardPriority(value); - - if (priority < bestPriority) { - bestPriority = priority; - bestCard = card; - } else if (priority == bestPriority) { - // 优先级相同,比较牌值(小的优先) - if (bestCard == null || value < (bestCard % 100)) { - bestCard = card; - } - } - } - - return bestCard; - } - - // 牌的优先级(数字越小优先级越高) - private static int getCardPriority(int value) { - if (value == 9) - return 1; - if (value == 1) - return 2; - if (value == 2 || value == 8) - return 3; // 靠近边张 - if (value >= 3 && value <= 7) - return 4; // 中间牌 - return 5; // 其他 - } - public static Integer selectBestCardRemove258(List cards) { if (cards == null || cards.isEmpty()) { return null; diff --git a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/HandAnalysis.java b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/HandAnalysis.java index 29214e8..f3c67b5 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/HandAnalysis.java +++ b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/HandAnalysis.java @@ -21,5 +21,4 @@ public class HandAnalysis { public boolean hasPengPengHu = false; //是否有碰碰胡 public Set usedInPairs = new HashSet<>(); //用于对子/将的牌 public List remainingCards = new ArrayList<>(); //剩余需要分析的牌 - public int lastDrawnCard = 0; //最后摸的牌 } \ No newline at end of file diff --git a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/Paixing.java b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/Paixing.java index 04d9abc..c761692 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/Paixing.java +++ b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/Paixing.java @@ -7,26 +7,6 @@ import com.robot.Util; public class Paixing { - - private final static boolean qs_yijihua_check(Map cardMap,int se,int index) { - Integer num = cardMap.get(se+index); - if(num!=null&&num==1) { - for(int i=1;i<=9;++i) { - if(i !=index) { - if(cardMap.containsKey(se+i)){ - return false; - } - } - } - return true; - } - return false; - } - - - - - public static void main(String[] args) { List cardInhand = new java.util.ArrayList<>(); List opCards = new java.util.ArrayList<>(); @@ -179,10 +159,6 @@ public class Paixing { } } - public static boolean checkWin(Map map, List opCards, List cardInhand,int drawCard, int difen) { - return checkWin(map,opCards,cardInhand,drawCard,true, difen); - } - public static boolean checkWin(Map map, List opCards, List cardInhand,int drawCard,boolean jiang, int difen) { int qixiaodui = qixiaodui(opCards,cardInhand, drawCard); if (qixiaodui != -1) { @@ -270,19 +246,4 @@ public class Paixing { return win.tryWin(); } - - static public boolean tingKongCheck(List opCards,List cardInhand,int kongCard,boolean jiang) { - if (quanqiuren(opCards,cardInhand, 0))return true; - if (jiangjiang(opCards,cardInhand, kongCard))return true; - if (pongpong(opCards,cardInhand, 0,false))return true; - if (qingyise(opCards,cardInhand, kongCard)) { - WinCard win = new WinCard(cardInhand, 0); - win.jiang = false; - return win.tryWin(); - } - WinCard win = new WinCard(cardInhand, 0); - win.jiang = jiang; - return win.tryWin(); - } - } \ No newline at end of file diff --git a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/PlayerState.java b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/PlayerState.java index 2453035..861c9be 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/PlayerState.java +++ b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/PlayerState.java @@ -19,58 +19,6 @@ public class PlayerState { this.isZhuang = false; } - public PlayerState(List handCards) { - this(); - this.handCards = new ArrayList<>(handCards); - } - - // 添加碰牌组 - public void addPongGroup(List pongGroup) { - if (pongGroup.size() == 3) { - this.pongGroups.add(new ArrayList<>(pongGroup)); - } - } - - // 添加杠牌组 - public void addGangGroup(List gangGroup) { - if (gangGroup.size() == 4) { - this.gangGroups.add(new ArrayList<>(gangGroup)); - } - } - - // 添加吃牌组 - public void addChiGroup(List chiGroup) { - if (chiGroup.size() == 3) { - this.chiGroups.add(new ArrayList<>(chiGroup)); - } - } - - // 获取所有碰牌(扁平化) - public List getAllPongCards() { - List all = new ArrayList<>(); - for (List group : pongGroups) { - all.addAll(group); - } - return all; - } - - // 获取所有杠牌(扁平化) - public List getAllGangCards() { - List all = new ArrayList<>(); - for (List group : gangGroups) { - all.addAll(group); - } - return all; - } - - // 获取所有吃牌(扁平化) - public List getAllChiCards() { - List all = new ArrayList<>(); - for (List group : chiGroups) { - all.addAll(group); - } - return all; - } // 获取碰牌组数 public int getPongGroupCount() { @@ -87,8 +35,4 @@ public class PlayerState { return chiGroups.size(); } - // 获取总组数 - public int getTotalGroupCount() { - return pongGroups.size() + gangGroups.size() + chiGroups.size(); - } } \ No newline at end of file diff --git a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/TinHuChi.java b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/TinHuChi.java index ba6e166..ce24e36 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/TinHuChi.java +++ b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/TinHuChi.java @@ -1,50 +1,9 @@ package taurus.util; import com.robot.Util; -import robot.mj.handler.HuNanChangSha; - import java.util.*; - - - public class TinHuChi { - public static boolean isMoreThanLast = false; - public static int lastTingCount = 0; - - - public static int[][] countTiles(List cardInHand) { - int[][] counts = new int[5][10]; // 类型×值 - - for (Integer card : cardInHand) { - if (card == 0) { - continue; - } - counts[card / 100 - 1][card % 100]++; - } - return counts; - } - - public static boolean isJiangPai(int card){ - if (card%100==2||card%100==5||card%100==8){ - return true; - } - return false; - } - - public static int checkduijiang(List cardInHand) { - Map countMap = new HashMap<>(); - for (Integer item : cardInHand) { - countMap.put(item, countMap.getOrDefault(item, 0) + 1); - } - int jiangnum = 0; - for (int key : countMap.keySet()) { - if (isJiangPai(key)&&countMap.get(key)>=2){ - jiangnum++; - } - } - return jiangnum; - } /** * 测试方法 @@ -120,149 +79,6 @@ public class TinHuChi { } - - - - - - - -// List temphand = new ArrayList<>(); -// temphand.addAll(hand1); -// temphand.add(104); -// Util.removeCard(temphand, 104, 3); -// List checktingpai1 = TinHuChi.checktingpai(temphand); -// System.out.println("checktingpai1" + checktingpai1); - - //hand1.add(101); - -// Map map = new HashMap<>(); -// Map map2 = new HashMap<>(); -// -// List> lists = checkChi(hand1, addcard); -// //吃之前的逻辑 -// int jiangnum = checkduijiang(hand1); -// hand1.add(addcard); -// System.out.println(hand1); -// ChangshaWinSplitCard.checkNormalHu(hand1, map); -// -// System.out.println("checkNormalHu" + map.get("cardResiue")); -// -// System.out.println("checktingpai1" + lists); -// int index = 0; -// int flag = 0; -// for (List list : lists) { -// List temphand = hand1; -// //temphand.add(addcard); -// Util.removeCard(temphand,list.get(0),1); -// Util.removeCard(temphand,list.get(1),1); -// Util.removeCard(temphand,list.get(2),1); -// System.out.println("temphand" + temphand); -// 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()) < Integer.parseInt(map.get("remainingMelds").toString()) ){ -// flag=index+1; -// }else if (Integer.parseInt(map2.get("remainingMelds").toString()) == 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){ -// flag=index+1; -// } -// -// //如果手里没有将,则可以吃 -// if (jiangnum>0) { -// int chihoujiangnum = checkduijiang(temphand); -// if (chihoujiangnum>0){ -// //吃之后还有将 -// flag=index+1; -// } -// }else{ -// System.out.println("没队将"); -// //孤章1张 差一手 不是将 而且card不是将 -// if (Integer.parseInt(map.get("remainingMelds").toString())==1&&size1==1&&!isJiangPai(((List) map.get("cardResiue")).get(0))&&!isJiangPai(addcard)){ -// //吃 -// break; -// } -// flag=index+1; -// // break; -// } -// -// -// -// } -// -// index ++ ; -// System.out.println("checkNormalHu2" + map2); -// } -// System.out.println("flag" + flag); - - - - - - - /*List shifoutingpai = shifoutingpai(hand1); - System.out.println("shifoutingpai" + shifoutingpai); -// -// List checktingpai = checktingpai(hand1); -// System.out.println("checktingpai" + checktingpai); -// -// - List> lists = checkChi(hand1, addcard); - int index = 0; - int flag = 0; - for (List list : lists) { - List temphand = hand1; - temphand.add(addcard); - Util.removeCard(temphand,list.get(0),1); - Util.removeCard(temphand,list.get(1),1); - Util.removeCard(temphand,list.get(2),1); - List checktingpai1 = checktingpai(temphand); - if (checktingpai1.size() > 0) { - flag =index +1; - } - index ++ ; - System.out.println("checktingpai1" + checktingpai1); - } - System.out.println("flag" + flag); - System.out.println(lists); - */ - - - public static List shifoutingpai(List cardhand) { - List tpcards = new ArrayList<>(); - List tmphc = cardhand; - for (int i = 0; i < cardhand.size(); i++) { - - int tmpcard = tmphc.get(i); -// tmphc.remove(i); - for (int j = 101; j <= 109; j++) { - WinCard win = new WinCard(tmphc, j); - if (win.tryWin()) { - if (!tpcards.contains(j)) { - tpcards.add(j); - } - } - } - for (int j = 201; j <= 209; j++) { - WinCard win = new WinCard(tmphc, j); - if (win.tryWin()) { - if (!tpcards.contains(j)) { - tpcards.add(j); - } - } - } -// tmphc.add(tmpcard); - } - return tpcards; - } - public static List checktingpai(List cardhand) { List tpcards = new ArrayList<>(); List tmphc = cardhand; @@ -291,714 +107,6 @@ public class TinHuChi { return tpcards; } - public static List> checkChi(List hand, int card) { - List> result = new ArrayList<>(); - if (Util.checkCard(card-1, hand ) &&Util.checkCard(card - 2, hand)) { - List opcard = new ArrayList<>(); - opcard.add(card-1); - opcard.add(card - 2); - opcard.add(card); - result.add(opcard); - } - - if (Util.checkCard(card + 1, hand) && Util.checkCard(card - 1, hand)) { - List opcard = new ArrayList<>(); - opcard.add(card + 1); - opcard.add(card - 1); - opcard.add(card); - result.add(opcard); - } - - if (Util.checkCard(card + 1, hand) && Util.checkCard(card + 2, hand)) { - List opcard = new ArrayList<>(); - opcard.add(card + 1); - opcard.add(card + 2); - opcard.add(card); - result.add(opcard); - } - - return result; - } - - public static boolean canChi(List handCards, int card) { - int type = card / 100; - int value = card % 100; - - if (type >= 4) return false; // 字牌不能吃 - - System.out.println("\n要吃的牌: " + value + getTypeName(type)); - System.out.println("当前手牌数量: " + handCards.size() + "张"); - - List chiOptions = new ArrayList<>(); // 存储所有能吃的方式 - - // 检查三种吃法并记录 - if (value >= 3) { - int prev2 = type * 100 + (value - 2); - int prev1 = type * 100 + (value - 1); - if (handCards.contains(prev2) && handCards.contains(prev1)) { - chiOptions.add(new int[]{prev2, prev1}); - System.out.println(" 可以组成" + (value - 2) + (value - 1) + value + "顺子"); - } - } - - if (value >= 2 && value <= 8) { - int prev = type * 100 + (value - 1); - int next = type * 100 + (value + 1); - if (handCards.contains(prev) && handCards.contains(next)) { - chiOptions.add(new int[]{prev, next}); - System.out.println(" 可以组成" + (value - 1) + value + (value + 1) + "顺子"); - } - } - - if (value <= 7) { - int next1 = type * 100 + (value + 1); - int next2 = type * 100 + (value + 2); - if (handCards.contains(next1) && handCards.contains(next2)) { - chiOptions.add(new int[]{next1, next2}); - System.out.println(" 可以组成" + value + (value + 1) + (value + 2) + "顺子"); - } - } - - if (chiOptions.isEmpty()) { - System.out.println(" 没有能吃的方式"); - return false; // 没有能吃的方式 - } - - System.out.println("发现" + chiOptions.size() + "种吃法"); - - // 记录所有能听牌的吃法及其听牌详情 - List tingOptions = new ArrayList<>(); - - for (int[] chiPair : chiOptions) { - System.out.println("\n尝试吃法: 用" + (chiPair[0] % 100) + getTypeName(type) + - "和" + (chiPair[1] % 100) + getTypeName(type) + - "吃" + value + getTypeName(type)); - - // 检查这种吃法能听多少张牌以及听什么牌 - TingResult tingResult = getTingResultAfterChi(handCards, card, chiPair[0], chiPair[1]); - if (tingResult != null && tingResult.tingCount > 0) { - tingOptions.add(new TingChiOption(chiPair, tingResult.tingCount, tingResult.tingCards, tingResult.discardCard)); - System.out.println(" → 打" + (tingResult.discardCard % 100) + getTypeName(tingResult.discardCard / 100) + - "可听" + tingResult.tingCount + "张牌: " + formatCards(tingResult.tingCards)); - } else { - System.out.println(" → 不能听牌"); - } - } - - // 如果有能听牌的吃法 - if (!tingOptions.isEmpty()) { - // 选择听牌数量最多的吃法 - tingOptions.sort((a, b) -> { - // 优先按听牌数量排序 - if (b.tingCount != a.tingCount) { - return b.tingCount - a.tingCount; - } - // 如果听牌数量相同,可以考虑其他因素,比如听牌质量 - return 0; - }); - - TingChiOption bestOption = tingOptions.get(0); - - System.out.println("\n=== 选择最佳吃法 ==="); - System.out.println("用" + (bestOption.chiPair[0] % 100) + getTypeName(type) + - "和" + (bestOption.chiPair[1] % 100) + getTypeName(type) + - "吃" + value + getTypeName(type)); - System.out.println("打" + (bestOption.bestDiscard % 100) + getTypeName(bestOption.bestDiscard / 100)); - System.out.println("听" + bestOption.tingCount + "张牌: " + formatCards(bestOption.tingCards)); - - // 分析听牌类型 - analyzeTingType(bestOption.tingCards); - - return true; - } - - return false; // 所有吃法都不能形成好牌型 - } - - - - // 新增:获取吃牌后的听牌数量 - public static int getTingCountAfterChi(List handCards, int chiCard, - int remove1, int remove2) { - // 模拟吃牌 - List afterChi = new ArrayList<>(handCards); - afterChi.remove(Integer.valueOf(remove1)); - afterChi.remove(Integer.valueOf(remove2)); - Collections.sort(afterChi); - - boolean needs258 = !checkSuitCount(afterChi); - int targetSizeAfterDiscard = afterChi.size() - 1; - - int maxTingCount = 0; - Set uniqueCards = new HashSet<>(afterChi); - - for (int discardCard : uniqueCards) { - List afterDiscard = new ArrayList<>(afterChi); - afterDiscard.remove(Integer.valueOf(discardCard)); - Collections.sort(afterDiscard); - - if (afterDiscard.size() == targetSizeAfterDiscard) { - int tingCount = countTingCards(afterDiscard, needs258); - maxTingCount = Math.max(maxTingCount, tingCount); - } - } - - return maxTingCount; - } - - // 新增:统计听牌数量 - public static int countTingCards(List hand, boolean needs258) { - if (hand.size() % 3 != 1) return 0; // 听牌时手牌应该是3n+1张 - - Set tingCards = new HashSet<>(); - Set allCards = new HashSet<>(); - - // 生成所有可能的牌 - for (int type = 1; type <= 3; type++) { - for (int value = 1; value <= 9; value++) { - allCards.add(type * 100 + value); - } - } - - for (int testCard : allCards) { - List tempHand = new ArrayList<>(hand); - tempHand.add(testCard); - if (canHu(tempHand, needs258)) { - tingCards.add(testCard); - } - } - - return tingCards.size(); - } - - // 修改后的 TingChiOption 类 - static class TingChiOption { - int[] chiPair; - int tingCount; - Set tingCards; - int bestDiscard; - - TingChiOption(int[] chiPair, int tingCount, Set tingCards, int bestDiscard) { - this.chiPair = chiPair; - this.tingCount = tingCount; - this.tingCards = tingCards; - this.bestDiscard = bestDiscard; - } - } - - - // 新增:获取吃牌后的听牌结果 - public static TingResult getTingResultAfterChi(List handCards, int chiCard, - int remove1, int remove2) { - // 模拟吃牌 - List afterChi = new ArrayList<>(handCards); - afterChi.remove(Integer.valueOf(remove1)); - afterChi.remove(Integer.valueOf(remove2)); - Collections.sort(afterChi); - - boolean needs258 = !checkSuitCount(afterChi); - int targetSizeAfterDiscard = afterChi.size() - 1; - - TingResult bestResult = null; - Set uniqueCards = new HashSet<>(afterChi); - - for (int discardCard : uniqueCards) { - List afterDiscard = new ArrayList<>(afterChi); - afterDiscard.remove(Integer.valueOf(discardCard)); - Collections.sort(afterDiscard); - - if (afterDiscard.size() == targetSizeAfterDiscard) { - Set tingCards = getTingCards(afterDiscard, needs258); - int tingCount = tingCards.size(); - - if (tingCount > 0) { - if (bestResult == null || tingCount > bestResult.tingCount) { - bestResult = new TingResult(tingCount, tingCards, discardCard); - } - } - } - } - - return bestResult; - } - - // 新增:获取具体的听牌集合 - public static Set getTingCards(List hand, boolean needs258) { - if (hand.size() % 3 != 1) return new HashSet<>(); // 听牌时手牌应该是3n+1张 - - Set tingCards = new HashSet<>(); - Set allCards = new HashSet<>(); - - // 生成所有可能的牌 - for (int type = 1; type <= 3; type++) { - for (int value = 1; value <= 9; value++) { - allCards.add(type * 100 + value); - } - } - - for (int testCard : allCards) { - List tempHand = new ArrayList<>(hand); - tempHand.add(testCard); - if (canHu(tempHand, needs258)) { - tingCards.add(testCard); - } - } - - return tingCards; - } - - // 新增:格式化牌显示 - public static String formatCards(Set cards) { - List cardStrs = new ArrayList<>(); - for (int card : cards) { - int type = card / 100; - int value = card % 100; - cardStrs.add(value + getTypeName(type)); - } - return String.join(", ", cardStrs); - } - - // 新增:记录听牌结果的类 - static class TingResult { - int tingCount; - Set tingCards; - int discardCard; // 打哪张牌能达到这个听牌 - - TingResult(int tingCount, Set tingCards, int discardCard) { - this.tingCount = tingCount; - this.tingCards = tingCards; - this.discardCard = discardCard; - } - } - /** - * 检查吃牌并打出一张后是否能听牌 - 优化版 - */ - public static boolean canTingAfterChiAndDiscard(List handCards, int chiCard, - int remove1, int remove2) { - // 1. 模拟吃牌:移除两张牌,吃的牌不加入手牌 - List afterChi = new ArrayList<>(handCards); - afterChi.remove(Integer.valueOf(remove1)); - afterChi.remove(Integer.valueOf(remove2)); - Collections.sort(afterChi); - - System.out.println(" 吃后手牌(" + afterChi.size() + "张): " + convertToReadable(afterChi)); - - // 2. 检查是否需要258将(花色是否>=10张) - System.out.println(chiCard); - System.out.println(afterChi); - boolean needs258 = !checkSuitCount(afterChi); - if (needs258) { - System.out.println(" 花色牌数不足10张,需要258做将"); - } - - // 3. 根据手牌数量确定目标手牌数 - int originalSize = handCards.size(); - int targetSizeAfterDiscard; - - if (originalSize == 13) { - // 标准情况:13张手牌 -> 吃后11张 -> 打后10张 - targetSizeAfterDiscard = 10; - } else if (originalSize == 14) { - // 你的例子:14张手牌 -> 吃后12张 -> 打后11张 - targetSizeAfterDiscard = 11; - } else { - // 其他情况,根据吃后手牌数减1 - targetSizeAfterDiscard = afterChi.size() - 1; - System.out.println(" 非标准手牌数,目标手牌数: " + targetSizeAfterDiscard); - } - - // 4. 尝试打每一张不同的牌 - Set uniqueCards = new HashSet<>(afterChi); - boolean foundTing = false; - for (int discardCard : uniqueCards) { - List afterDiscard = new ArrayList<>(afterChi); - afterDiscard.remove(Integer.valueOf(discardCard)); - Collections.sort(afterDiscard); - - int discardType = discardCard / 100; - int discardValue = discardCard % 100; - - System.out.println("---打牌-----" + discardValue); - - System.out.print("\n 打" + discardValue + getTypeName(discardType) + - " → 剩余" + afterDiscard.size() + "张: " + - convertToReadable(afterDiscard)); - - // 5. 检查打牌后是否能听牌 - boolean canTing = checkCanTing(afterDiscard, needs258, targetSizeAfterDiscard); - if (canTing) { - //HuNanChangSha.isTinChi = true; - ChangShaSuanFaTest.isChi=true; - System.out.println(" ✓ 听牌!"); - foundTing = true; - - // 分析听牌详情 - analyzeTingDetails(afterDiscard, needs258); - } else { -// // 如果不能听牌,检查是否是好牌型 -// System.out.print(" [手牌分析中...]"); -// -// if (isGoodHandForTing(afterDiscard, needs258, targetSizeAfterDiscard)) { -// System.out.println(" ✓ 好牌型(接近听牌)"); -// foundTing = true; -// } else { - System.out.println(" ✗ 不听"); -// } - } - } - return foundTing; - } - - /** - * 检查手牌是否能听牌 - */ - public static boolean checkCanTing(List hand, boolean needs258, int targetSize) { - if (hand.size() != targetSize) { - return false; - } - - // 获取所有可能的牌 - Set allCards = new HashSet<>(); - - // 生成所有可能的牌 - for (int type = 1; type <= 3; type++) { - for (int value = 1; value <= 9; value++) { - allCards.add(type * 100 + value); - } - } - - for (int testCard : allCards) { - List tempHand = new ArrayList<>(hand); - tempHand.add(testCard); - Collections.sort(tempHand); - - // 检查是否能胡牌 - if (canHu(tempHand, needs258)) { - return true; - } - } - - return false; - } - - /** - * 检查手牌是否能胡牌(考虑258将要求) - */ - public static boolean canHu(List handCards, boolean needs258) { - // 手牌排序 - List sorted = new ArrayList<>(handCards); - Collections.sort(sorted); - - // 胡牌时手牌数必须是3n+2 - if (sorted.size() % 3 != 2) { - return false; - } - - // 检查七对子(特殊胡牌) - if (checkQiDuiZi(sorted)) { - // 七对子不需要258将 - return true; - } - - // 如果需要258将,检查普通胡牌(必须有258将) - if (needs258) { - return checkNormalHuWith258(sorted); - } else { - // 不需要258将,检查普通胡牌 - return checkNormalHu(sorted); - } - } - - /** - * 分析听牌详情 - */ - public static void analyzeTingDetails(List hand, boolean needs258) { - - Set tingCards = new HashSet<>(); - Set allCards = new HashSet<>(); - - // 生成所有可能的牌 - for (int type = 1; type <= 3; type++) { - for (int value = 1; value <= 9; value++) { - allCards.add(type * 100 + value); - } - } - - for (int testCard : allCards) { - List tempHand = new ArrayList<>(hand); - tempHand.add(testCard); - - if (canHu(tempHand, needs258)) { - tingCards.add(testCard); - } - } - - if (!tingCards.isEmpty()) { - System.out.print(" 听" + tingCards.size() + "张牌: "); - List tingCardStrs = new ArrayList<>(); - - // 比较当前数量和上次数量 - if (tingCards.size() > lastTingCount) { - isMoreThanLast = true; -// System.out.print("(比上次多" + (tingCards.size() - lastTingCount) + "张) "); - } else if (tingCards.size() < lastTingCount) { -// System.out.print("(比上次少" + (lastTingCount - tingCards.size()) + "张) "); - } else { -// System.out.print("(与上次相同) "); - } - - for (int card : tingCards) { - int type = card / 100; - int value = card % 100; - tingCardStrs.add(value + getTypeName(type)); - - } - System.out.println(String.join(", ", tingCardStrs)); - - // 更新上次听牌数量 - lastTingCount = tingCards.size(); - - // 分析听牌类型 - analyzeTingType(tingCards); - } else { - System.out.println(" 无听牌"); - // 比较当前数量和上次数量 - if (0 > lastTingCount) { - isMoreThanLast = true; - } - // 更新上次听牌数量 - lastTingCount = 0; - } - - } - - - // 修改 analyzeTingType 方法以接收 Set - public static void analyzeTingType(Set tingCards) { - if (tingCards.size() == 1) { - System.out.println("听牌类型: 单吊"); - } else if (tingCards.size() == 2) { - List tingList = new ArrayList<>(tingCards); - int type1 = tingList.get(0) / 100; - int type2 = tingList.get(1) / 100; - if (type1 == type2) { - System.out.println("听牌类型: 对倒"); - } else { - System.out.println("听牌类型: 双面听"); - } - } else if (tingCards.size() >= 3) { - System.out.println("听牌类型: 多面听(" + tingCards.size() + "张)"); - } - } - - /** - * 检查手牌花色牌数是否>=10张 - */ - public static boolean checkSuitCount(List hand) { - // 统计万、筒、条各自的数量 - Map suitCount = new HashMap<>(); - for (int card : hand) { - int type = card / 100; - if (type < 4) { // 只统计万筒条 - suitCount.put(type, suitCount.getOrDefault(type, 0) + 1); - } - } - - // 检查是否有某种花色>=10张 - for (int count : suitCount.values()) { - if (count >= 10) { - return true; // 有花色>=10张,不需要258将 - } - } - - return false; // 没有花色>=10张,需要258将 - } - - /** - * 检查七对子 - */ - public static boolean checkQiDuiZi(List handCards) { - if (handCards.size() != 14) return false; - - Map countMap = new HashMap<>(); - for (int card : handCards) { - countMap.put(card, countMap.getOrDefault(card, 0) + 1); - } - - // 检查是否都是对子 - for (int count : countMap.values()) { - if (count != 2) { - return false; - } - } - - return true; - } - - /** - * 检查普通胡牌(必须有258将) - */ - public static boolean checkNormalHuWith258(List handCards) { - // 尝试每种258作为将牌 - for (int card : handCards) { - int value = card % 100; - // 检查是否是258 - if (value == 2 || value == 5 || value == 8) { - // 检查是否有至少2张相同的牌做将 - int count = Collections.frequency(handCards, card); - if (count >= 2) { - // 移除将牌 - List remaining = new ArrayList<>(handCards); - for (int i = 0; i < 2; i++) { - remaining.remove(Integer.valueOf(card)); - } - - // 检查剩余牌是否能组成顺子/刻子 - if (canGroup(remaining)) { - return true; - } - } - } - } - - return false; - } - - /** - * 检查普通胡牌(不需要258将) - */ - public static boolean checkNormalHu(List handCards) { - return checkNormalHuRecursive(new ArrayList<>(handCards), false); - } - - public static boolean checkNormalHuRecursive(List handCards, boolean hasJiang) { - if (handCards.isEmpty()) { - return true; // 所有牌都分组成功 - } - - Collections.sort(handCards); - - // 统计第一张牌的数量 - int firstCard = handCards.get(0); - int count = Collections.frequency(handCards, firstCard); - - // 尝试作为刻子(三张相同) - if (count >= 3) { - List remaining = new ArrayList<>(handCards); - for (int i = 0; i < 3; i++) { - remaining.remove(Integer.valueOf(firstCard)); - } - if (checkNormalHuRecursive(remaining, hasJiang)) { - return true; - } - } - - // 尝试作为顺子(三张连续) - int type = firstCard / 100; - int value = firstCard % 100; - - if (type < 4 && value <= 7) { // 字牌和8、9不能组成顺子 - int second = type * 100 + (value + 1); - int third = type * 100 + (value + 2); - - if (handCards.contains(second) && handCards.contains(third)) { - List remaining = new ArrayList<>(handCards); - remaining.remove(Integer.valueOf(firstCard)); - remaining.remove(Integer.valueOf(second)); - remaining.remove(Integer.valueOf(third)); - if (checkNormalHuRecursive(remaining, hasJiang)) { - return true; - } - } - } - - // 尝试作为将(对子)- 只能有一个将 - if (!hasJiang && count >= 2) { - List remaining = new ArrayList<>(handCards); - remaining.remove(Integer.valueOf(firstCard)); - remaining.remove(Integer.valueOf(firstCard)); - if (checkNormalHuRecursive(remaining, true)) { - return true; - } - } - - return false; - } - - /** - * 检查牌是否能组成顺子或刻子 - */ - public static boolean canGroup(List cards) { - if (cards.isEmpty()) { - return true; // 所有牌都分组成功 - } - - List sorted = new ArrayList<>(cards); - Collections.sort(sorted); - - int firstCard = sorted.get(0); - int count = Collections.frequency(sorted, firstCard); - - // 尝试作为刻子(三张相同) - if (count >= 3) { - List remaining = new ArrayList<>(sorted); - for (int i = 0; i < 3; i++) { - remaining.remove(Integer.valueOf(firstCard)); - } - if (canGroup(remaining)) { - return true; - } - } - - // 尝试作为顺子(三张连续) - int type = firstCard / 100; - int value = firstCard % 100; - - if (type < 4 && value <= 7) { // 字牌和8、9不能组成顺子 - int second = type * 100 + (value + 1); - int third = type * 100 + (value + 2); - - if (sorted.contains(second) && sorted.contains(third)) { - List remaining = new ArrayList<>(sorted); - remaining.remove(Integer.valueOf(firstCard)); - remaining.remove(Integer.valueOf(second)); - remaining.remove(Integer.valueOf(third)); - if (canGroup(remaining)) { - return true; - } - } - } - - return false; - } - - /** - * 获取所有麻将牌 - */ - public static Set getAllCards() { - Set allCards = new HashSet<>(); - // 万条筒 1-9 - for (int type = 1; type <= 3; type++) { - for (int value = 1; value <= 9; value++) { - allCards.add(type * 100 + value); - } - } - return allCards; - } - - /** - * 转换为可读格式 - */ - public static String convertToReadable(List cards) { - StringBuilder sb = new StringBuilder(); - for (int card : cards) { - int type = card / 100; - int value = card % 100; - sb.append(value).append(getTypeName(type)).append(" "); - } - return sb.toString(); - } - /** * 获取牌型名称 */ @@ -1016,7 +124,4 @@ public class TinHuChi { } - public static boolean isMoreThanLast() { - return isMoreThanLast; - } } \ No newline at end of file diff --git a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/TinHuGang.java b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/TinHuGang.java deleted file mode 100644 index 5510452..0000000 --- a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/TinHuGang.java +++ /dev/null @@ -1,404 +0,0 @@ -package taurus.util; - -import java.util.*; - -public class TinHuGang { - - - /** - * 判断是否能杠牌(检查杠牌后是否立即听牌) - */ - public static boolean canGang(List handCards, int card, boolean isMingGang) { - int type = card / 100; - int value = card % 100; - - System.out.println("\n检查" + (isMingGang ? "明" : "暗") + "杠" + value + getTypeName(type) + ":"); - - // 检查是否符合杠牌条件 - int count = Collections.frequency(handCards, card); - - if (isMingGang) { - // 明杠:手牌中需要有三张相同的牌 - if (count < 3) { - System.out.println(" 手牌中没有三张相同的" + value + getTypeName(type) + ",不能明杠"); - return false; - } - System.out.println(" 发现三张" + value + getTypeName(type) + ",可以明杠"); - } else { - // 暗杠:手牌中需要有四张相同的牌 - if (count < 4) { - System.out.println(" 手牌中没有四张相同的" + value + getTypeName(type) + ",不能暗杠"); - return false; - } - System.out.println(" 发现四张" + value + getTypeName(type) + ",可以暗杠"); - } - - // 检查杠牌后是否立即听牌(杠牌后手牌本身就是听牌状态) - return canTingImmediatelyAfterGang(handCards, card, isMingGang); - } - - /** - * 检查杠牌后是否能立即听牌 - */ - private static boolean canTingImmediatelyAfterGang(List handCards, int gangCard, boolean isMingGang) { - int type = gangCard / 100; - int value = gangCard % 100; - - System.out.println("\n模拟" + (isMingGang ? "明" : "暗") + "杠" + value + getTypeName(type) + ":"); - - // 1. 模拟杠牌:移除手牌中的牌 - List afterGang = new ArrayList<>(handCards); - - if (isMingGang) { - // 明杠:移除手牌中的三张牌 - for (int i = 0; i < 3; i++) { - afterGang.remove(Integer.valueOf(gangCard)); - } - // 杠牌后手牌数:13张 → 10张 - } else { - // 暗杠:移除手牌中的四张牌 - for (int i = 0; i < 4; i++) { - afterGang.remove(Integer.valueOf(gangCard)); - } - // 暗杠后需要补牌,但这里先不处理 - } - - Collections.sort(afterGang); - - System.out.println(" 杠后手牌(" + afterGang.size() + "张): " + convertToReadable(afterGang)); - - // 2. 检查是否需要258将 - boolean needs258 = !checkSuitCount(afterGang); - if (needs258) { - System.out.println(" 花色牌数不足10张,需要258做将"); - } - - // 3. 检查杠牌后手牌本身是否就是听牌状态 - // 注意:杠牌后手牌数是10张,这10张牌本身应该是听牌状态 - // 也就是说,随便摸一张牌(任何牌)都能胡牌 - - System.out.println("\n 检查杠后手牌是否听牌:"); - - if (afterGang.size() != 10) { - System.out.println(" 手牌数不是10张,不符合听牌条件"); - return false; - } - - // 检查这10张牌是否听牌 - boolean canTing = checkIfHandIsTingPai(afterGang, needs258); - - if (canTing) { - System.out.println(" ✓ 杠后手牌是听牌状态!"); - - // 显示听哪些牌 - Set tingCards = getTingCards(afterGang, needs258); - if (!tingCards.isEmpty()) { - System.out.print(" 听" + tingCards.size() + "张牌: "); - List tingStrs = new ArrayList<>(); - for (int tingCard : tingCards) { - tingStrs.add((tingCard%100) + getTypeName(tingCard/100)); - } - System.out.println(String.join(", ", tingStrs)); - } - return true; - } else { - System.out.println(" ✗ 杠后手牌不是听牌状态"); - return false; - } - } - - /** - * 检查手牌是否处于听牌状态 - */ - private static boolean checkIfHandIsTingPai(List hand, boolean needs258) { - if (hand.size() != 10) { - return false; - } - - // 听牌状态:再摸任何一张牌都能胡牌 - // 我们需要检查是否至少有一张牌能让这手牌胡牌 - Set allCards = getAllCards(); - int tingCount = 0; - - for (int testCard : allCards) { - List tempHand = new ArrayList<>(hand); - tempHand.add(testCard); - - if (canHu(tempHand, needs258)) { - tingCount++; - } - } - - System.out.println(" 可胡" + tingCount + "张牌"); - return tingCount > 0; - } - - /** - * 获取听哪些牌 - */ - private static Set getTingCards(List hand, boolean needs258) { - Set tingCards = new HashSet<>(); - - if (hand.size() != 10) { - return tingCards; - } - - Set allCards = getAllCards(); - - for (int testCard : allCards) { - List tempHand = new ArrayList<>(hand); - tempHand.add(testCard); - - if (canHu(tempHand, needs258)) { - tingCards.add(testCard); - } - } - - return tingCards; - } - - /** - * 检查手牌是否能胡牌 - */ - private static boolean canHu(List handCards, boolean needs258) { - // 手牌排序 - List sorted = new ArrayList<>(handCards); - Collections.sort(sorted); - - // 胡牌时手牌数必须是3n+2 - if (sorted.size() != 11 && sorted.size() != 14) { - return false; - } - - // 检查七对子 - if (checkQiDuiZi(sorted)) { - // 七对子不需要258将 - return true; - } - - // 如果需要258将,检查普通胡牌(必须有258将) - if (needs258) { - return checkNormalHuWith258(sorted); - } else { - // 不需要258将,检查普通胡牌 - return checkNormalHu(sorted); - } - } - - /** - * 检查七对子 - */ - private static boolean checkQiDuiZi(List handCards) { - if (handCards.size() != 14) return false; - - Map countMap = new HashMap<>(); - for (int card : handCards) { - countMap.put(card, countMap.getOrDefault(card, 0) + 1); - } - - // 检查是否都是对子 - for (int count : countMap.values()) { - if (count != 2) { - return false; - } - } - - return true; - } - - /** - * 检查普通胡牌(必须有258将) - */ - private static boolean checkNormalHuWith258(List handCards) { - // 尝试每种258作为将牌 - for (int card : handCards) { - int value = card % 100; - // 检查是否是258 - if (value == 2 || value == 5 || value == 8) { - // 检查是否有至少2张相同的牌做将 - int count = Collections.frequency(handCards, card); - if (count >= 2) { - // 移除将牌 - List remaining = new ArrayList<>(handCards); - for (int i = 0; i < 2; i++) { - remaining.remove(Integer.valueOf(card)); - } - - // 检查剩余牌是否能组成顺子/刻子 - if (canGroup(remaining)) { - return true; - } - } - } - } - - return false; - } - - /** - * 检查普通胡牌(不需要258将) - */ - private static boolean checkNormalHu(List handCards) { - return checkNormalHuRecursive(new ArrayList<>(handCards), false); - } - - private static boolean checkNormalHuRecursive(List handCards, boolean hasJiang) { - if (handCards.isEmpty()) { - return true; // 所有牌都分组成功 - } - - Collections.sort(handCards); - - // 统计第一张牌的数量 - int firstCard = handCards.get(0); - int count = Collections.frequency(handCards, firstCard); - - // 尝试作为刻子(三张相同) - if (count >= 3) { - List remaining = new ArrayList<>(handCards); - for (int i = 0; i < 3; i++) { - remaining.remove(Integer.valueOf(firstCard)); - } - if (checkNormalHuRecursive(remaining, hasJiang)) { - return true; - } - } - - // 尝试作为顺子(三张连续) - int type = firstCard / 100; - int value = firstCard % 100; - - if (type < 4 && value <= 7) { // 字牌和8、9不能组成顺子 - int second = type * 100 + (value + 1); - int third = type * 100 + (value + 2); - - if (handCards.contains(second) && handCards.contains(third)) { - List remaining = new ArrayList<>(handCards); - remaining.remove(Integer.valueOf(firstCard)); - remaining.remove(Integer.valueOf(second)); - remaining.remove(Integer.valueOf(third)); - if (checkNormalHuRecursive(remaining, hasJiang)) { - return true; - } - } - } - - // 尝试作为将(对子)- 只能有一个将 - if (!hasJiang && count >= 2) { - List remaining = new ArrayList<>(handCards); - remaining.remove(Integer.valueOf(firstCard)); - remaining.remove(Integer.valueOf(firstCard)); - if (checkNormalHuRecursive(remaining, true)) { - return true; - } - } - - return false; - } - - /** - * 检查牌是否能组成顺子或刻子 - */ - private static boolean canGroup(List cards) { - if (cards.isEmpty()) { - return true; // 所有牌都分组成功 - } - - List sorted = new ArrayList<>(cards); - Collections.sort(sorted); - - int firstCard = sorted.get(0); - int count = Collections.frequency(sorted, firstCard); - - // 尝试作为刻子(三张相同) - if (count >= 3) { - List remaining = new ArrayList<>(sorted); - for (int i = 0; i < 3; i++) { - remaining.remove(Integer.valueOf(firstCard)); - } - if (canGroup(remaining)) { - return true; - } - } - - // 尝试作为顺子(三张连续) - int type = firstCard / 100; - int value = firstCard % 100; - - if (type < 4 && value <= 7) { // 字牌和8、9不能组成顺子 - int second = type * 100 + (value + 1); - int third = type * 100 + (value + 2); - - if (sorted.contains(second) && sorted.contains(third)) { - List remaining = new ArrayList<>(sorted); - remaining.remove(Integer.valueOf(firstCard)); - remaining.remove(Integer.valueOf(second)); - remaining.remove(Integer.valueOf(third)); - if (canGroup(remaining)) { - return true; - } - } - } - - return false; - } - - /** - * 检查手牌花色牌数是否>=10张 - */ - private static boolean checkSuitCount(List hand) { - Map suitCount = new HashMap<>(); - for (int card : hand) { - int type = card / 100; - if (type < 4) { - suitCount.put(type, suitCount.getOrDefault(type, 0) + 1); - } - } - - for (int count : suitCount.values()) { - if (count >= 10) { - return true; - } - } - - return false; - } - - /** - * 获取所有麻将牌 - */ - private static Set getAllCards() { - Set allCards = new HashSet<>(); - for (int type = 1; type <= 3; type++) { - for (int value = 1; value <= 9; value++) { - allCards.add(type * 100 + value); - } - } - return allCards; - } - - /** - * 转换为可读格式 - */ - private static String convertToReadable(List cards) { - StringBuilder sb = new StringBuilder(); - for (int card : cards) { - int type = card / 100; - int value = card % 100; - sb.append(value).append(getTypeName(type)).append(" "); - } - return sb.toString(); - } - - /** - * 获取牌型名称 - */ - private static String getTypeName(int type) { - switch(type) { - case 1: return "万"; - case 2: return "筒"; - case 3: return "条"; - default: return "字"; - } - } -} \ No newline at end of file diff --git a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/TinHuPeng.java b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/TinHuPeng.java deleted file mode 100644 index e49cef6..0000000 --- a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/TinHuPeng.java +++ /dev/null @@ -1,425 +0,0 @@ -package taurus.util; - - -import robot.mj.handler.HuNanChangSha; - -import java.util.*; - -public class TinHuPeng { - - /** - * 判断是否能碰牌(包含碰牌后的听牌检查) - */ - public boolean canPeng(List handCards, int card) { - int type = card / 100; - int value = card % 100; - - if (type >= 4) return false; // 字牌不能碰(长沙麻将没有字牌) - - System.out.println("\n要碰的牌: " + value + getTypeName(type)); - System.out.println("当前手牌数量: " + handCards.size() + "张"); - - // 检查基本碰牌条件:手牌至少有2张相同的牌 - if (!canPengBasic(handCards, card)) { - System.out.println(" 基本碰牌条件不满足:手牌没有2张" + value + getTypeName(type)); - return false; - } - System.out.println(" ✓ 手牌有2张" + value + getTypeName(type) + ",可以碰"); - ChangShaSuanFaTest.isPeng = true; - // 检查碰牌后是否能听牌 - return canTingAfterPengAndDiscard(handCards, card); - } - - /** - * 检查基本碰牌条件 - */ - private boolean canPengBasic(List handCards, int card) { - // 碰牌:手牌有2张相同的牌,别人打出第3张 - int count = 0; - for (int c : handCards) { - if (c == card) { - count++; - } - } - return count >= 2; - } - - /** - * 检查碰牌并打出一张后是否能听牌 - */ - private boolean canTingAfterPengAndDiscard(List handCards, int pengCard) { - // 1. 模拟碰牌:移除两张相同的牌,碰的牌不加入手牌 - List afterPeng = new ArrayList<>(handCards); - - // 移除2张相同的牌 - int removed = 0; - for (int i = 0; i < handCards.size() && removed < 2; i++) { - if (handCards.get(i) == pengCard) { - afterPeng.remove(Integer.valueOf(pengCard)); - removed++; - } - } - Collections.sort(afterPeng); - - System.out.println(" 碰后手牌(" + afterPeng.size() + "张): " + convertToReadable(afterPeng)); - - // 2. 检查是否需要258将(花色是否>=10张) - boolean needs258 = !checkSuitCount(afterPeng); - if (needs258) { - System.out.println(" 花色牌数不足10张,需要258做将"); - } - - // 3. 根据碰后手牌数确定目标手牌数 - // 碰牌前后手牌数变化:碰前N张 -> 碰后(N-2)张 -> 打后(N-3)张 - int targetSizeAfterDiscard = afterPeng.size() - 1; - System.out.println(" 目标手牌数: " + targetSizeAfterDiscard); - - // 4. 尝试打每一张不同的牌 - Set uniqueCards = new HashSet<>(afterPeng); - boolean foundTing = false; - - for (int discardCard : uniqueCards) { - List afterDiscard = new ArrayList<>(afterPeng); - afterDiscard.remove(Integer.valueOf(discardCard)); - Collections.sort(afterDiscard); - - int discardType = discardCard / 100; - int discardValue = discardCard % 100; - - System.out.print("\n 打" + discardValue + getTypeName(discardType) + - " → 剩余" + afterDiscard.size() + "张: " + - convertToReadable(afterDiscard)); - - // 5. 检查打牌后是否能听牌 - boolean canTing = checkCanTing(afterDiscard, needs258, targetSizeAfterDiscard); - - if (canTing) { - HuNanChangSha.isTinPeng = true; - System.out.println(" ✓ 听牌!"); - foundTing = true; - - // 分析听牌详情 - analyzeTingDetails(afterDiscard, needs258); - } else { - System.out.println(" ✗ 不听"); - } - } - - return foundTing; - } - - /** - * 检查手牌是否能听牌 - */ - private boolean checkCanTing(List hand, boolean needs258, int targetSize) { - if (hand.size() != targetSize) { - System.out.print(" [手牌数" + hand.size() + "≠目标" + targetSize + "]"); - return false; - } - - // 获取所有可能的牌 - Set allCards = getAllCards(); - - for (int testCard : allCards) { - List tempHand = new ArrayList<>(hand); - tempHand.add(testCard); - Collections.sort(tempHand); - - // 检查是否能胡牌 - if (canHu(tempHand, needs258)) { - return true; - } - } - - return false; - } - - /** - * 检查手牌是否能胡牌(考虑258将要求) - */ - private boolean canHu(List handCards, boolean needs258) { - // 手牌排序 - List sorted = new ArrayList<>(handCards); - Collections.sort(sorted); - - // 胡牌时手牌数必须是3n+2 - if (sorted.size() % 3 != 2) { - return false; - } - - // 检查七对子(特殊胡牌) - if (checkQiDuiZi(sorted)) { - // 七对子不需要258将 - return true; - } - - // 如果需要258将,检查普通胡牌(必须有258将) - if (needs258) { - return checkNormalHuWith258(sorted); - } else { - // 不需要258将,检查普通胡牌 - return checkNormalHu(sorted); - } - } - - /** - * 分析听牌详情 - */ - private void analyzeTingDetails(List hand, boolean needs258) { - Set tingCards = new HashSet<>(); - Set allCards = getAllCards(); - - for (int testCard : allCards) { - List tempHand = new ArrayList<>(hand); - tempHand.add(testCard); - - if (canHu(tempHand, needs258)) { - tingCards.add(testCard); - } - } - - if (!tingCards.isEmpty()) { - System.out.print(" 听" + tingCards.size() + "张牌: "); - List tingCardStrs = new ArrayList<>(); - for (int card : tingCards) { - int type = card / 100; - int value = card % 100; - tingCardStrs.add(value + getTypeName(type)); - } - System.out.println(String.join(", ", tingCardStrs)); - } - } - - /** - * 检查手牌花色牌数是否>=10张 - */ - private boolean checkSuitCount(List hand) { - // 统计万、筒、条各自的数量 - Map suitCount = new HashMap<>(); - for (int card : hand) { - int type = card / 100; - if (type < 4) { // 只统计万筒条 - suitCount.put(type, suitCount.getOrDefault(type, 0) + 1); - } - } - - // 检查是否有某种花色>=10张 - for (int count : suitCount.values()) { - if (count >= 10) { - return true; // 有花色>=10张,不需要258将 - } - } - - return false; // 没有花色>=10张,需要258将 - } - - /** - * 检查七对子 - */ - private boolean checkQiDuiZi(List handCards) { - if (handCards.size() != 14) return false; - - Map countMap = new HashMap<>(); - for (int card : handCards) { - countMap.put(card, countMap.getOrDefault(card, 0) + 1); - } - - // 检查是否都是对子 - for (int count : countMap.values()) { - if (count != 2) { - return false; - } - } - - return true; - } - - /** - * 检查普通胡牌(必须有258将) - */ - private boolean checkNormalHuWith258(List handCards) { - // 尝试每种258作为将牌 - for (int card : handCards) { - int value = card % 100; - // 检查是否是258 - if (value == 2 || value == 5 || value == 8) { - // 检查是否有至少2张相同的牌做将 - int count = Collections.frequency(handCards, card); - if (count >= 2) { - // 移除将牌 - List remaining = new ArrayList<>(handCards); - for (int i = 0; i < 2; i++) { - remaining.remove(Integer.valueOf(card)); - } - - // 检查剩余牌是否能组成顺子/刻子 - if (canGroup(remaining)) { - return true; - } - } - } - } - - return false; - } - - /** - * 检查普通胡牌(不需要258将) - */ - private boolean checkNormalHu(List handCards) { - return checkNormalHuRecursive(new ArrayList<>(handCards), false); - } - - private boolean checkNormalHuRecursive(List handCards, boolean hasJiang) { - if (handCards.isEmpty()) { - return true; // 所有牌都分组成功 - } - - Collections.sort(handCards); - - // 统计第一张牌的数量 - int firstCard = handCards.get(0); - int count = Collections.frequency(handCards, firstCard); - - // 尝试作为刻子(三张相同) - if (count >= 3) { - List remaining = new ArrayList<>(handCards); - for (int i = 0; i < 3; i++) { - remaining.remove(Integer.valueOf(firstCard)); - } - if (checkNormalHuRecursive(remaining, hasJiang)) { - return true; - } - } - - // 尝试作为顺子(三张连续) - int type = firstCard / 100; - int value = firstCard % 100; - - if (type < 4 && value <= 7) { // 字牌和8、9不能组成顺子 - int second = type * 100 + (value + 1); - int third = type * 100 + (value + 2); - - if (handCards.contains(second) && handCards.contains(third)) { - List remaining = new ArrayList<>(handCards); - remaining.remove(Integer.valueOf(firstCard)); - remaining.remove(Integer.valueOf(second)); - remaining.remove(Integer.valueOf(third)); - if (checkNormalHuRecursive(remaining, hasJiang)) { - return true; - } - } - } - - // 尝试作为将(对子)- 只能有一个将 - if (!hasJiang && count >= 2) { - List remaining = new ArrayList<>(handCards); - remaining.remove(Integer.valueOf(firstCard)); - remaining.remove(Integer.valueOf(firstCard)); - if (checkNormalHuRecursive(remaining, true)) { - return true; - } - } - - return false; - } - - /** - * 检查牌是否能组成顺子或刻子 - */ - private boolean canGroup(List cards) { - if (cards.isEmpty()) { - return true; // 所有牌都分组成功 - } - - List sorted = new ArrayList<>(cards); - Collections.sort(sorted); - - int firstCard = sorted.get(0); - int count = Collections.frequency(sorted, firstCard); - - // 尝试作为刻子(三张相同) - if (count >= 3) { - List remaining = new ArrayList<>(sorted); - for (int i = 0; i < 3; i++) { - remaining.remove(Integer.valueOf(firstCard)); - } - if (canGroup(remaining)) { - return true; - } - } - - // 尝试作为顺子(三张连续) - int type = firstCard / 100; - int value = firstCard % 100; - - if (type < 4 && value <= 7) { // 字牌和8、9不能组成顺子 - int second = type * 100 + (value + 1); - int third = type * 100 + (value + 2); - - if (sorted.contains(second) && sorted.contains(third)) { - List remaining = new ArrayList<>(sorted); - remaining.remove(Integer.valueOf(firstCard)); - remaining.remove(Integer.valueOf(second)); - remaining.remove(Integer.valueOf(third)); - if (canGroup(remaining)) { - return true; - } - } - } - - return false; - } - - /** - * 获取所有麻将牌 - */ - private Set getAllCards() { - Set allCards = new HashSet<>(); - // 万条筒 1-9 - for (int type = 1; type <= 3; type++) { - for (int value = 1; value <= 9; value++) { - allCards.add(type * 100 + value); - } - } - return allCards; - } - - /** - * 转换为可读格式 - */ - private String convertToReadable(List cards) { - StringBuilder sb = new StringBuilder(); - for (int card : cards) { - int type = card / 100; - int value = card % 100; - sb.append(value).append(getTypeName(type)).append(" "); - } - return sb.toString(); - } - - /** - * 获取牌型名称 - */ - private String getTypeName(int type) { - switch(type) { - case 1: return "万"; - case 2: return "筒"; - case 3: return "条"; - default: return "字"; - } - } - - /** - * 手牌分析类 - */ - class HandAnalysis { - int keziCount = 0; // 刻子数量 - int pairCount = 0; // 对子数量 - int shunziCount = 0; // 顺子数量 - int singleCount = 0; // 单张数量 - List singles = new ArrayList<>(); // 单张列表 - boolean has258Jiang = false; // 是否有258将 - List pairs = new ArrayList<>(); // 对子列表(value) - } -} diff --git a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/TingPaiChecker.java b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/TingPaiChecker.java index b66d3d5..cb6ddbc 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/TingPaiChecker.java +++ b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/TingPaiChecker.java @@ -419,58 +419,6 @@ public class TingPaiChecker { return possibleCards; } - /** - * 检查剩余牌是否能全部组成顺子或刻子 - */ - private boolean canFormAllMelds(List cards) { - if (cards.isEmpty()) { - return true; - } - return dfsFormMelds(new ArrayList<>(cards)); - } - - private boolean dfsFormMelds(List cards) { - if (cards.isEmpty()) { - return true; - } - - Collections.sort(cards); - int firstCard = cards.get(0); - int count = Collections.frequency(cards, firstCard); - - // 尝试刻子 - if (count >= 3) { - List newCards = new ArrayList<>(cards); - for (int i = 0; i < 3; i++) { - newCards.remove(Integer.valueOf(firstCard)); - } - if (dfsFormMelds(newCards)) { - return true; - } - } - - // 尝试顺子 - int type = getCardType(firstCard); - int value = getCardValue(firstCard); - - if (type <= 3 && value <= 7) { - int secondCard = firstCard + 1; - int thirdCard = firstCard + 2; - - if (cards.contains(secondCard) && cards.contains(thirdCard)) { - List newCards = new ArrayList<>(cards); - newCards.remove(Integer.valueOf(firstCard)); - newCards.remove(Integer.valueOf(secondCard)); - newCards.remove(Integer.valueOf(thirdCard)); - if (dfsFormMelds(newCards)) { - return true; - } - } - } - - return false; - } - /** * 获取牌值 */ diff --git a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/WinCard.java b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/WinCard.java index bd8e5c8..c2f631b 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/WinCard.java +++ b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/WinCard.java @@ -231,7 +231,6 @@ public class WinCard { public static void main(String[] args) { long time = System.currentTimeMillis(); -// for (int i = 0; i < 1000000; ++i) { ArrayList cardInhand = new ArrayList(); cardInhand.add(207); cardInhand.add(207); @@ -248,24 +247,9 @@ public class WinCard { cardInhand.add(102); cardInhand.add(102); -// cardInhand.add(301); -// cardInhand.add(301); -// cardInhand.add(108); - -// cardInhand.contains(204); -// Util.checkCard(204, cardInhand); -// CardUtil.checkCardAndRomve(204, cardInhand, 2); - -// if(Util.checkCard(204, cardInhand)) { -// CardUtil.removeCard(cardInhand, 204, 2); -// } WinCard win = new WinCard(cardInhand, 104); boolean c = win.tryWin(); System.out.println(c); -// Paixing.tingKongCheck(new ArrayList<>(), cardInhand, 301); -// } - //Map map = new HashMap(); - //Paixing.checkWin(map, new ArrayList<>(), cardInhand, 305, room.difen_score); System.out.println(System.currentTimeMillis() - time); diff --git a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/ai.java b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/ai.java index 4a440c2..1d5bf5b 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/taurus/util/ai.java +++ b/robots/majiang/robot_mj_cs/src/main/java/taurus/util/ai.java @@ -1,8 +1,3 @@ -// -// Source code recreated from a .class file by IntelliJ IDEA -// (powered by Fernflower decompiler) -// - package taurus.util; import java.util.ArrayList; @@ -17,11 +12,6 @@ import java.util.stream.Collectors; public class ai { private static final Set JIANG_PAIS; - private static final int DOOR_NONE = 0; - private static final int DOOR_BIAN = 1; - private static final int DOOR_GE = 2; - private static final int DOOR_XIANGLIN = 3; - private static final int DOOR_DUIZI = 4; public boolean isTinAi = false; public boolean isTingpai = false; private Map scoreCache = new HashMap(); @@ -395,18 +385,6 @@ public class ai { } } - private boolean isInSequenceMiddle(int card, List hand) { - int type = this.getCardType(card); - this.getCardValue(card); - if (type > 3) { - return false; - } else { - int prevCard = card - 1; - int nextCard = card + 1; - return hand.contains(prevCard) && hand.contains(nextCard); - } - } - private double evaluatePairsAndPongsFinal(int card, PlayerState state) { int originalCount = 0;