protected override EResponse OnHandle_KakanHai(EKaze fromPlayerKaze, Hai haiToHandle) { _action.Reset(); if (inTest) { return(DoResponse(EResponse.Nagashi)); } Hai kanHai = haiToHandle; int agariScore = MahjongAgent.getAgariScore(Tehai, kanHai, JiKaze); if (agariScore > 0) { if (GameSettings.AllowFuriten || !isFuriten()) { return(DoResponse(EResponse.Ron_Agari)); } else { Utils.LogWarningFormat("AI {0} is enable ron but furiten...", JiKaze.ToString()); } } return(DoResponse(EResponse.Nagashi)); }
protected virtual void thinkReach() { _action.ReachSelectIndex = 0; List <int> reachHaiIndex = _action.ReachHaiIndexList; Tehai tehaiCopy = new Tehai(Tehai); int minScore = int.MaxValue; for (int i = 0; i < reachHaiIndex.Count; i++) { Hai hai = tehaiCopy.removeJyunTehaiAt(reachHaiIndex[i]); // reachHaiIndex[i], not i List <Hai> machiiHais; if (MahjongAgent.tryGetMachiHais(tehaiCopy, out machiiHais)) { for (int m = 0; m < machiiHais.Count; m++) { Hai addHai = machiiHais[m]; FormatWorker.setCounterFormat(tehaiCopy, addHai); int score = MahjongAgent.getAgariScore(tehaiCopy, addHai, JiKaze); if (score <= minScore) { minScore = score; _action.ReachSelectIndex = i; } } } tehaiCopy.insertJyunTehai(i, hai); } }
public bool CheckReachPreConditions() { //return !MahjongAgent.isReach(JiKaze) && // MahjongAgent.getTsumoRemain() >= GameSettings.PlayerCount // && Tenbou >= GameSettings.Reach_Cost; return(!MahjongAgent.isReach(JiKaze) && MahjongAgent.getTsumoRemain() >= GameSettings.PlayerCount); }
// 听牌 public bool isTenpai() { if (_reach == true) { return(true); } return(MahjongAgent.canTenpai(_tehai)); }
protected override EResponse OnHandle_SuteHai(EKaze fromPlayerKaze, Hai haiToHandle) { _action.Reset(); _action.SutehaiIndex = 0; Hai suteHai = haiToHandle; // check Ron int agariScore = MahjongAgent.getAgariScore(Tehai, suteHai, JiKaze); if (agariScore > 0) // Ron { if (GameSettings.AllowFuriten || !isFuriten()) { return(DoResponse(EResponse.Ron_Agari)); } else { Utils.LogWarningFormat("AI {0} is enable to ron but furiten...", JiKaze.ToString()); } } if (MahjongAgent.getTsumoRemain() <= 0) { return(DoResponse(EResponse.Nagashi)); } if (MahjongAgent.isReach(JiKaze)) { return(DoResponse(EResponse.Nagashi)); } // TODO: Chii, Pon, Kan check // check Kan(test) /* * if( MahjongAgent.getTotalKanCount() < GameSettings.KanCountMax ) * { * if( Tehai.validDaiMinKan(suteHai) ) { * _action.IsValidDaiMinKan = true; * return DoResponse(EResponse.DaiMinKan); * } * } */ //_action.Reset(); //thinkSelectSuteHai(); return(DoResponse(EResponse.Nagashi)); //return DoResponse(EResponse.Nagashi); }
// 振听. public bool isFuriten() { List <Hai> machiHais; if (MahjongAgent.tryGetMachiHais(Tehai, out machiHais)) { // check hou SuteHai[] suteHais = Hou.getSuteHais(); for (int i = 0; i < suteHais.Length; i++) { SuteHai suteHaiTemp = suteHais[i]; for (int j = 0; j < machiHais.Count; j++) { if (suteHaiTemp.ID == machiHais[j].ID) { return(true); } } } // check sutehai suteHais = MahjongAgent.getSuteHaiList(); int playerSuteHaisCount = MahjongAgent.getPlayerSuteHaisCount(JiKaze); for ( ; playerSuteHaisCount < suteHais.Length - 1; playerSuteHaisCount++) { SuteHai suteHaiTemp = suteHais[playerSuteHaisCount]; for (int j = 0; j < machiHais.Count; j++) { if (suteHaiTemp.ID == machiHais[j].ID) { return(true); } } } } return(false); }
protected override EResponse OnHandle_KakanHai(EKaze fromPlayerKaze, Hai haiToHandle) { _action.Reset(); if (inTest) { //return DoResponse(EResponse.Nagashi); } Hai kanHai = haiToHandle; int agariScore = MahjongAgent.getAgariScore(Tehai, kanHai, JiKaze); if (agariScore > 0) { if (GameSettings.AllowFuriten || !isFuriten()) { _action.IsValidRon = true; _action.MenuList.Add(EActionType.Ron); if (MahjongAgent.isReach(JiKaze)) { return(DisplayMenuList()); } else { _action.MenuList.Add(EActionType.Nagashi); return(DisplayMenuList()); } } else { Utils.LogWarningFormat("Player {0} is enable ron but furiten...", JiKaze.ToString()); } } return(DoResponse(EResponse.Nagashi)); }
protected override EResponse OnHandle_TsumoHai(EKaze fromPlayerKaze, Hai haiToHandle) { _action.Reset(); if (inTest) { _action.SutehaiIndex = Tehai.getJyunTehaiCount(); return(DoResponse(EResponse.SuteHai)); } Hai tsumoHai = haiToHandle; // ツモあがりの場合は、イベント(ツモあがり)を返す。 int agariScore = MahjongAgent.getAgariScore(Tehai, tsumoHai, JiKaze); if (agariScore > 0) { if (GameSettings.AllowFuriten || !isFuriten()) { return(DoResponse(EResponse.Tsumo_Agari)); } else { Utils.LogWarningFormat("AI {0} is enable tsumo but furiten...", JiKaze.ToString()); } } // 九种九牌check if (MahjongAgent.CheckHaiTypeOver9(Tehai, tsumoHai)) { return(DoResponse(EResponse.Nagashi)); } // リーチの場合は、ツモ切りする if (MahjongAgent.isReach(JiKaze)) { _action.SutehaiIndex = Tehai.getJyunTehaiCount(); return(DoResponse(EResponse.SuteHai)); } // check enable Reach if (CheckReachPreConditions() == true) { List <int> reachHaiIndexList; if (MahjongAgent.tryGetReachHaiIndex(Tehai, tsumoHai, out reachHaiIndexList)) { _action.IsValidReach = true; _action.ReachHaiIndexList = reachHaiIndexList; thinkReach(); return(DoResponse(EResponse.Reach)); } } // 制限事項。リーチ後のカンをさせない if (!MahjongAgent.isReach(JiKaze)) { /* * if( MahjongAgent.getTotalKanCount() < GameSettings.KanCountMax ) * { * // TODO: tsumo kans * List<Hai> kanHais = new List<Hai>(); * if( Tehai.validAnyTsumoKan(tsumoHai, kanHais) ) * { * _action.setValidTsumoKan(true, kanHais); * * } * } */ } else { if (MahjongAgent.getTotalKanCount() < GameSettings.KanCountMax) { // if player machi hais won't change after setting AnKan, enable to to it. if (Tehai.validAnKan(tsumoHai)) { List <Hai> machiHais; if (MahjongAgent.tryGetMachiHais(Tehai, out machiHais)) { Tehai tehaiCopy = new Tehai(Tehai); tehaiCopy.setAnKan(tsumoHai); tehaiCopy.Sort(); List <Hai> newMachiHais; if (MahjongAgent.tryGetMachiHais(tehaiCopy, out newMachiHais)) { if (machiHais.Count == newMachiHais.Count) { machiHais.Sort(Tehai.Compare); newMachiHais.Sort(Tehai.Compare); bool enableAnkan = true; for (int i = 0; i < machiHais.Count; i++) { if (machiHais[i].ID != newMachiHais[i].ID) { enableAnkan = false; break; } } if (enableAnkan == true) { _action.setValidTsumoKan(true, new List <Hai>() { tsumoHai }); return(DoResponse(EResponse.Ankan)); } } } } } } // can Ron or Ankan, sute hai automatically. _action.SutehaiIndex = Tehai.getJyunTehaiCount(); // sute the tsumo hai on Reach return(DoResponse(EResponse.SuteHai)); } thinkSutehai(tsumoHai); return(DoResponse(EResponse.SuteHai)); }
protected EResponse DisplayMenuList() { MahjongAgent.PostUiEvent(UIEventType.DisplayMenuList); return(EResponse.Nagashi); }
protected override EResponse OnHandle_TsumoHai(EKaze fromPlayerKaze, Hai haiToHandle) { _action.Reset(); _action.State = EActionState.Select_Sutehai; if (inTest) { //_action.State = EActionState.Select_Sutehai; //return DisplayMenuList(); } // 手牌をコピーする。 Hai tsumoHai = haiToHandle; // check enable Tsumo int agariScore = MahjongAgent.getAgariScore(Tehai, tsumoHai, JiKaze); if (agariScore > 0) { if (GameSettings.AllowFuriten || !isFuriten()) { _action.IsValidTsumo = true; _action.MenuList.Add(EActionType.Tsumo); if (MahjongAgent.isReach(JiKaze)) { return(DisplayMenuList()); } } else { Utils.LogWarningFormat("Player {0} is enable tsumo but furiten...", JiKaze.ToString()); } } // 九种九牌check if (MahjongAgent.CheckHaiTypeOver9(Tehai, tsumoHai)) { _action.MenuList.Add(EActionType.RyuuKyoku); } // check enable Reach if (CheckReachPreConditions() == true) { List <int> reachHaiIndexList; if (MahjongAgent.tryGetReachHaiIndex(Tehai, tsumoHai, out reachHaiIndexList)) { _action.IsValidReach = true; _action.ReachHaiIndexList = reachHaiIndexList; _action.MenuList.Add(EActionType.Reach); } } // 制限事項。リーチ後のカンをさせない if (!MahjongAgent.isReach(JiKaze)) { if (MahjongAgent.getTotalKanCount() < GameSettings.KanCountMax) { // tsumo kans List <Hai> kanHais = new List <Hai>(); if (Tehai.validAnyTsumoKan(tsumoHai, kanHais)) { _action.setValidTsumoKan(true, kanHais); _action.MenuList.Add(EActionType.Kan); } } } else { if (MahjongAgent.getTotalKanCount() < GameSettings.KanCountMax) { // if player machi hais won't change after setting AnKan, enable to to it. if (Tehai.validAnKan(tsumoHai)) { List <Hai> machiHais; if (MahjongAgent.tryGetMachiHais(Tehai, out machiHais)) { Tehai tehaiCopy = new Tehai(Tehai); tehaiCopy.setAnKan(tsumoHai); tehaiCopy.Sort(); List <Hai> newMachiHais; if (MahjongAgent.tryGetMachiHais(tehaiCopy, out newMachiHais)) { if (machiHais.Count == newMachiHais.Count) { machiHais.Sort(Tehai.Compare); newMachiHais.Sort(Tehai.Compare); bool enableAnkan = true; for (int i = 0; i < machiHais.Count; i++) { if (machiHais[i].ID != newMachiHais[i].ID) { enableAnkan = false; break; } } if (enableAnkan == true) { _action.setValidTsumoKan(true, new List <Hai>() { tsumoHai }); _action.MenuList.Add(EActionType.Kan); _action.MenuList.Add(EActionType.Nagashi); _action.State = EActionState.Select_Kan; } } } } } // end if(valid ankan) } // end kan count check // can Ron or Ankan, sute hai automatically. if (_action.MenuList.Count == 0) { _action.SutehaiIndex = Tehai.getJyunTehaiCount(); // sute the tsumo hai on Reach return(DoResponse(EResponse.SuteHai)); } } // always display menu on pick tsumo hai. return(DisplayMenuList()); }
protected override EResponse OnHandle_SuteHai(EKaze fromPlayerKaze, Hai haiToHandle) { _action.Reset(); if (inTest) { //_action.MenuList.Add(EActionType.Nagashi); //return DisplayMenuList(); } Hai suteHai = haiToHandle; // check Ron int agariScore = MahjongAgent.getAgariScore(Tehai, suteHai, JiKaze); if (agariScore > 0) // Ron { if (GameSettings.AllowFuriten || !isFuriten()) { _action.IsValidRon = true; _action.MenuList.Add(EActionType.Ron); if (MahjongAgent.isReach(JiKaze)) { //_action.MenuList.Add( EActionType.Nagashi ); return(DisplayMenuList()); } else { _action.MenuList.Add(EActionType.Nagashi); } } else { Utils.LogWarningFormat("Player {0} is enable to ron but furiten...", JiKaze.ToString()); } } if (MahjongAgent.getTsumoRemain() <= 0) { return(DoResponse(EResponse.Nagashi)); } if (MahjongAgent.isReach(JiKaze)) { return(DoResponse(EResponse.Nagashi)); } // check menu Kan if (MahjongAgent.getTotalKanCount() < GameSettings.KanCountMax) { if (Tehai.validDaiMinKan(suteHai)) { _action.IsValidDaiMinKan = true; _action.MenuList.Add(EActionType.Kan); } } // check menu Pon if (Tehai.validPon(suteHai)) { _action.IsValidPon = true; _action.MenuList.Add(EActionType.Pon); } // check menu Chii int relation = Mahjong.getRelation(fromPlayerKaze, JiKaze); if (relation == (int)ERelation.KaMiCha) { List <Hai> sarashiHaiRight = new List <Hai>(); if (Tehai.validChiiRight(suteHai, sarashiHaiRight)) { _action.setValidChiiRight(true, sarashiHaiRight); if (!_action.MenuList.Contains(EActionType.Chii)) { _action.MenuList.Add(EActionType.Chii); } } List <Hai> sarashiHaiCenter = new List <Hai>(); if (Tehai.validChiiCenter(suteHai, sarashiHaiCenter)) { _action.setValidChiiCenter(true, sarashiHaiCenter); if (!_action.MenuList.Contains(EActionType.Chii)) { _action.MenuList.Add(EActionType.Chii); } } List <Hai> sarashiHaiLeft = new List <Hai>(); if (Tehai.validChiiLeft(suteHai, sarashiHaiLeft)) { _action.setValidChiiLeft(true, sarashiHaiLeft); if (!_action.MenuList.Contains(EActionType.Chii)) { _action.MenuList.Add(EActionType.Chii); } } } if (_action.MenuList.Count > 0) { _action.MenuList.Add(EActionType.Nagashi); return(DisplayMenuList()); } return(DoResponse(EResponse.Nagashi)); }