public PChiaTaoFaKuoTriggerInstaller() : base("假道伐虢的记录") { TriggerList.Add(new PTrigger("假道伐虢[开始记录]") { IsLocked = true, Time = PPeriod.StartTurn.During, Effect = (PGame Game) => { Game.TagManager.PopTag <PChiaTaoFaKuoTag>(PChiaTaoFaKuoTag.TagName); Game.TagManager.CreateTag(new PChiaTaoFaKuoTag(new List <PPlayer>())); } }); TriggerList.Add(new PTrigger("假道伐虢[经过土地]") { IsLocked = true, Time = PTime.MovePositionTime, Effect = (PGame Game) => { PTransportTag TransportTag = Game.TagManager.FindPeekTag <PTransportTag>(PTransportTag.TagName); PPlayer Lord = TransportTag.Destination.Lord; if (Lord != null && !Lord.Equals(Game.NowPlayer)) { PChiaTaoFaKuoTag ChiaTaoFaKuoTag = Game.TagManager.FindPeekTag <PChiaTaoFaKuoTag>(PChiaTaoFaKuoTag.TagName); if (!ChiaTaoFaKuoTag.LordList.Contains(Lord)) { ChiaTaoFaKuoTag.LordList.Add(Lord); } } } }); }
public void Die(PPlayer Player, PPlayer Killer) { PNetworkManager.NetworkServer.TellClients(new PShowInformationOrder(Player.Name + "死亡!")); Monitor.CallTime(PTime.DieTime, new PDyingTag(Player, Killer)); Map.BlockList.ForEach((PBlock Block) => { if (Player.Equals(Block.Lord)) { Block.Lord = null; Block.HouseNumber = 0; Block.BusinessType = PBusinessType.NoType; PNetworkManager.NetworkServer.TellClients(new PRefreshBlockBasicOrder(Block)); } }); CardManager.ThrowAll(Player.Area); Player.IsAlive = false; PNetworkManager.NetworkServer.TellClients(new PDieOrder(Player.Index.ToString())); Monitor.CallTime(PTime.AfterDieTime, new PDyingTag(Player, Killer)); if (GameOver()) { PLogger.Log("游戏结束"); EndGame(); } else if (!NowPlayer.IsAlive) { PLogger.Log("因为当前玩家死亡,回合中止"); TagManager.PopTag <PStepCountTag>(PStepCountTag.TagName); TagManager.PopTag <PDiceResultTag>(PDiceResultTag.TagName); TagManager.PopTag <PTag>(PTag.FreeTimeOperationTag.Name); Monitor.EndTurnDirectly = true; } }
private PCard ChooseCard(PPlayer Player, PPlayer TargetPlayer, string Title, bool AllowHandCards = true, bool AllowEquipment = true, bool AllowAmbush = false, bool IsGet = false) { PCard TargetCard = null; if (Player.IsUser) { if (Player.Equals(TargetPlayer)) { TargetCard = PNetworkManager.NetworkServer.ChooseManager.AskToChooseOwnCard(Player, Title, AllowHandCards, AllowEquipment, AllowAmbush); } else { if (!AllowEquipment) { if (AllowHandCards) { TargetCard = TargetPlayer.Area.HandCardArea.RandomCard(); } } else { TargetCard = PNetworkManager.NetworkServer.ChooseManager.AskToChooseOthersCard(Player, TargetPlayer, Title, AllowHandCards, AllowAmbush); } } } else { if (IsGet) { if (!Player.Age.Equals(TargetPlayer.Age) && TargetPlayer.HasEquipment <P_HsiYooYangToow>() && AllowEquipment) { TargetCard = TargetPlayer.GetEquipment(PCardType.TrafficCard); } else { TargetCard = PAiCardExpectation.FindMostValuableToGet(this, Player, TargetPlayer, AllowHandCards, AllowEquipment, AllowAmbush, Player.Equals(TargetPlayer)).Key; } } else { if (Player.TeamIndex == TargetPlayer.TeamIndex) { TargetCard = PAiCardExpectation.FindLeastValuable(this, Player, TargetPlayer, AllowHandCards, AllowEquipment, AllowAmbush, Player.Equals(TargetPlayer)).Key; } else { TargetCard = PAiCardExpectation.FindMostValuable(this, Player, TargetPlayer, AllowHandCards, AllowEquipment, AllowAmbush).Key; } } } return(TargetCard); }
public override int AIInHandExpectation(PGame Game, PPlayer Player) { int Basic = 2000; if (!Game.Map.BlockList.Exists((PBlock Block) => Player.Equals(Block.Lord))) { return(Basic); } int TargetNumber = Game.AlivePlayerNumber - 1; int Test = PMath.Sum(Game.PlayerList.FindAll((PPlayer _Player) => _Player.IsAlive && !(_Player.Defensor != null && _Player.Defensor.Model is P_YooHsi && TargetNumber > 1) && _Player.HasHouse).ConvertAll((PPlayer _Player) => { return(PAiMapAnalyzer.MaxValueHouse(Game, Player, true).Value + PAiMapAnalyzer.MinValueHouse(Game, _Player).Value *(_Player.TeamIndex == Player.TeamIndex ? -1 : 1)); })); Basic = Math.Max(Basic, Test); return(Math.Max(Basic, base.AIInHandExpectation(Game, Player))); }
public void Traverse(Action <PPlayer> Operation, PPlayer Starter = null) { if (Starter == null) { Starter = PlayerList[0]; } PPlayer Player = Starter; do { if (Player.IsAlive) { Operation(Player); } Player = GetNextPlayer(Player); } while (!Player.Equals(Starter)); }
/// <summary> /// 伤害预测收益,无修正情形为基本伤害的2倍or0 /// </summary> /// <param name="Game"></param> /// <param name="Player">视点玩家</param> /// <param name="FromPlayer">造成伤害的玩家</param> /// <param name="Target"></param> /// <param name="BaseInjure">基本伤害量</param> /// <param name="Source">伤害方式</param> /// <returns></returns> public static int InjureExpect(PGame Game, PPlayer Player, PPlayer FromPlayer, PPlayer Target, int BaseInjure, PObject Source) { #region 防止伤害的情况 if (Player.OutOfGame || !Target.CanBeInjured || (FromPlayer == null && Target.HasEquipment <P_YinYangChing>()) || (BaseInjure <= 1000 && Target.HasEquipment <P_NanManHsiang>())) { return(0); } #endregion int FromCof = FromPlayer == null ? 0 : (Player.TeamIndex == FromPlayer.TeamIndex ? 1 : -1); int ToCof = (Player.TeamIndex != Target.TeamIndex ? 1 : -1); int Sum = 0; #region 成伤害时发动的技能:古锭刀,龙胆,太极,苍狼,趁火打劫,女权,怒斩 if (FromPlayer != null) { if (FromPlayer.Tags.ExistTag(P_WuZhao.NvQuanTag.Name) && (Source is PBlock || Source is PCard)) { BaseInjure += 2000; } if (FromPlayer.General is P_Gryu && Source is PBlock && FromPlayer.Area.EquipmentCardArea.CardNumber > Target.Area.EquipmentCardArea.CardNumber) { BaseInjure += 600; } if ((Target.Area.HandCardArea.CardNumber == 0 || (FromPlayer.General is P_IzayoiMiku && FromPlayer.TeamIndex != Target.TeamIndex)) && FromPlayer.HasEquipment <P_KuTingTao>() && Source is PBlock) { BaseInjure *= 2; } if (FromPlayer.General is P_ZhaoYun && FromPlayer.Tags.ExistTag(P_ZhaoYun.PDanTag.TagName)) { if (P_ZhaoYun.LongDanICondition(Game, FromPlayer, Target, BaseInjure)) { BaseInjure = PMath.Percent(BaseInjure, 150); } } if (FromPlayer.General is P_ZhangSanFeng && Player.Tags.ExistTag(P_ZhangSanFeng.PYinTag.Name)) { BaseInjure += PMath.Percent(BaseInjure, 20); } } if (Target.Area.OwnerCardNumber > 0) { if (FromPlayer != null && FromPlayer.HasEquipment <P_TsaangLang>() && Source != null && Source is PCard Card && Card.Model is PSchemeCardModel) { Sum += 2000 * FromCof + 2000 * ToCof; } if (Player.HasInHand <P_CheevnHuoTaChieh>()) { Sum += 2000 + 2000 * ToCof; } } #endregion #region 受到伤害时发动的技能:八卦阵,百花裙,龙胆,太极,霸王,白衣,镇魂曲 if (Target.HasEquipment <P_PaKuaChevn>()) { // 美九改版,八卦阵有效 if (Target.General is P_LiuJi) { Sum -= 1000 * ToCof; BaseInjure = PMath.Percent(BaseInjure, 50); } else { BaseInjure = (BaseInjure + PMath.Percent(BaseInjure, 50)) / 2; } } if (Target.HasEquipment <P_PaiHuaChooon>() && FromPlayer != null && !Target.Sex.Equals(FromPlayer.Sex)) { BaseInjure = PMath.Percent(BaseInjure, 50); } if (Target.General is P_ZhaoYun && Target.Tags.ExistTag(P_ZhaoYun.PDanTag.TagName)) { if (P_ZhaoYun.LongDanIICondition(Game, Target, FromPlayer, BaseInjure)) { BaseInjure = PMath.Percent(BaseInjure, 50); } } if (Target.General is P_ZhangSanFeng && Target.Tags.ExistTag(P_ZhangSanFeng.PYangTag.Name)) { BaseInjure -= PMath.Percent(BaseInjure, 20); } if (Game.AlivePlayers().Exists((PPlayer _Player) => { return(!_Player.Equals(Target) && _Player.TeamIndex != Target.TeamIndex && _Player.Distance(Target) <= 1 && _Player.General is P_Xdyu); })) { BaseInjure += 800; } if (Target.General is P_LvMeng && Target.Area.EquipmentCardArea.CardNumber > 0 && !(FromPlayer.General is P_IzayoiMiku && FromPlayer.TeamIndex != Target.TeamIndex)) { BaseInjure = Math.Min(PMath.Percent(BaseInjure, 50) + 2000, BaseInjure); } if (Target.General is P_IzayoiMiku && Game.AlivePlayersExist <P_Gabriel>()) { BaseInjure -= PMath.Percent(BaseInjure, 20); } #endregion int ExpectTargetMoney = Target.Money - BaseInjure; #region 濒死时发动的技能:蓄谋,精灵加护,圣女 if (ExpectTargetMoney <= 0) { bool flag = true; if (!(FromPlayer.General is P_LvZhi)) { if (Target.General is P_Gabriel) { flag = false; // 破军歌姬的复活 if (FromPlayer.Equals(Target)) { // 对自己伤害,不触发复活 } else if (FromPlayer.TeamIndex == Target.TeamIndex) { // 美九自己的伤害,触发复活大利好 Sum += 15000; } else { // 对方的伤害 if (Game.AlivePlayersExist <P_IzayoiMiku>()) { // 美九未死,大不利 Sum -= 15000; } else { flag = true; } } } else if (Game.AlivePlayersExist <P_JeanneDarc>() && Source is PBlock) { PPlayer Jeanne = Game.AlivePlayers().Find((PPlayer _Player) => _Player.General is P_JeanneDarc); if (Jeanne.TeamIndex == Target.TeamIndex && Jeanne.Area.OwnerCardNumber > 0 && Jeanne.Money > 5000 && ExpectTargetMoney > -10000) { flag = false; Sum += (5000 + (Target.Equals(Jeanne) ? 0 : 2000) - 2000 * Jeanne.Area.OwnerCardNumber) * (Target.TeamIndex == Player.TeamIndex ? 1 : -1); } } } if (flag) { Sum += 30000 * ToCof; } } #endregion Sum += BaseInjure * ToCof; Sum += BaseInjure * FromCof; #region 受到伤害后:离骚 if (Target.General is P_QuYuan) { // Sum -= 900 * ToCof; // 因为离骚总是会发动,其他伤害也会触发,天灾也会触发 // 所以不应该将离骚计入伤害计算 } #endregion #region 伤害结束后:风云 if (FromPlayer != null && FromPlayer.General is P_ChenYuanYuan) { Sum += 200 * FromCof; } if (Target.General is P_ChenYuanYuan) { Sum -= 200 * ToCof; } #endregion #region 队友间平衡:自身和目标的合理阈值为50%-200% if (FromPlayer.TeamIndex == Target.TeamIndex) { if (FromPlayer.General is P_IzayoiMiku && Target.General is P_Gabriel) { // 美九对破军歌姬的伤害,积极性 Sum += 2000; } else if (FromPlayer.General is P_Gabriel && Target.General is P_IzayoiMiku) { // 破军歌姬对美九的伤害,消极性 Sum -= 20000; } else { if (FromPlayer.Money > ExpectTargetMoney * 2) { Sum -= 2000; } else if (FromPlayer.Money >= Target.Money) { Sum -= 100; } else if (FromPlayer.Money < Target.Money * 2) { Sum += 1000; } } } #endregion #region 美九歌厅的翻面效果 if (Source is PBlock Block && Block.BusinessType.Equals(PBusinessType.Club)) { Sum += PAiMapAnalyzer.ChangeFaceExpect(Game, Target) * (-ToCof); } #endregion #region 贞德设为高嘲讽 if (Game.AlivePlayersExist <P_JeanneDarc>()) { PPlayer Jeanne = Game.AlivePlayers().Find((PPlayer _Player) => _Player.General is P_JeanneDarc); if (Jeanne.TeamIndex != Player.TeamIndex) { if (Target.Equals(Jeanne) && Sum > 0) { Sum += PMath.Percent(Sum, 20); } } } #endregion return(Sum); }
/// <summary> /// 弃一座房屋(没有则不弃) /// </summary> /// <param name="Player"></param> /// <param name="TargetPlayer"></param> /// <param name="Title"></param> public void ThrowHouse(PPlayer Player, PPlayer TargetPlayer, string Title) { if (TargetPlayer.HasHouse) { PBlock TargetBlock = null; if (Player.IsAI) { if (Player.TeamIndex == TargetPlayer.TeamIndex) { TargetBlock = PAiMapAnalyzer.MinValueHouse(this, TargetPlayer).Key; } else { TargetBlock = PAiMapAnalyzer.MaxValueHouse(this, TargetPlayer).Key; } } else { TargetBlock = PNetworkManager.NetworkServer.ChooseManager.AskToChooseBlock(Player, "[" + Title + "]选择" + TargetPlayer.Name + "的房屋", (PBlock Block) => TargetPlayer.Equals(Block.Lord) && Block.HouseNumber > 0); } if (TargetBlock != null) { PNetworkManager.NetworkServer.TellClients(new PHighlightBlockOrder(TargetBlock.Index.ToString())); LoseHouse(TargetBlock, 1); } } }
public P_YooenChiaoChinKung() : base(CardName) { Point = 4; Index = 23; foreach (PTime Time in new PTime[] { PPeriod.FirstFreeTime.During, PPeriod.SecondFreeTime.During }) { MoveInHandTriggerList.Add((PPlayer Player, PCard Card) => { return(new PTrigger(CardName) { IsLocked = false, Player = Player, Time = Time, AIPriority = 75, Condition = (PGame Game) => { return Player.Equals(Game.NowPlayer) && (Player.IsAI || Game.Logic.WaitingForEndFreeTime()); }, AICondition = (PGame Game) => { return AIEmitTargets(Game, Player)[0] != null; }, Effect = MakeNormalEffect(Player, Card, AIEmitTargets, PTrigger.Except(Player), (PGame Game, PPlayer User, PPlayer Target) => { Game.GetCard(Target); PPlayer Another = null; if (User.IsAI) { if (Game.Enemies(User).Exists((PPlayer _Player) => _Player.Money <= 1000) || User.Money > 15000) { Another = PMath.Min(Game.Enemies(User), (PPlayer _Player) => _Player.Money).Key; } else { Another = User; } } else { Another = PNetworkManager.NetworkServer.ChooseManager.AskForTargetPlayer(User, PTrigger.Except(Target), "远交近攻[第二目标]"); } if (Another != null) { if (Another.Equals(User)) { Game.GetMoney(Another, 1000); } else { Game.LoseMoney(Another, 1000); #region 成就:翻云覆雨 if (!Another.IsAlive) { PArch.Announce(Game, User, "翻云覆雨"); } #endregion } } }) }); }); } }
public List <PBlock> FindBlock(PPlayer Lord) { return(BlockList.FindAll((PBlock Block) => Lord.Equals(Block.Lord))); }
/// <summary> /// 将一个玩家移出游戏对其的收益,无卡牌收益嵌套 /// </summary> /// <param name="Game"></param> /// <param name="Player"></param> /// <param name="Including">是否包含其行走阶段</param> /// <returns></returns> public static int OutOfGameExpect(PGame Game, PPlayer Player, bool Including = false, bool IncludingOnly = false) { if (Player.OutOfGame) { return(0); } int Sum = 0; // 一轮其他角色可能造成的过路费收益总和的相反数 if (!IncludingOnly) { PPlayer _Player = Game.NowPlayer; if (Player.Equals(Game.NowPlayer)) { _Player = Game.GetNextPlayer(_Player); } for (; !_Player.Equals(Player); _Player = Game.GetNextPlayer(_Player)) { if (_Player.Equals(Game.NowPlayer) && Game.NowPeriod.IsAfter(PPeriod.WalkingStage)) { continue; } int Temp = 0; List <PBlock> Blocks = NextBlocks(Game, _Player); Blocks.ForEach((PBlock Block) => { int BlockTemp = 0; if (Block.Lord != null && Player.Equals(Block.Lord)) { BlockTemp = Math.Max(0, PAiTargetChooser.InjureExpect(Game, Player, Player, _Player, Block.Toll, Block)); } if (_Player.General is P_Newton) { PBlock PossibleBlock = Game.Map.NextStepBlock(Block, P_Newton.Grx_Next(Game, _Player.Position).Value); if (PossibleBlock.Lord != null && Player.Equals(PossibleBlock.Lord)) { BlockTemp = Math.Min(BlockTemp, Math.Max(0, PAiTargetChooser.InjureExpect(Game, Player, Player, _Player, Block.Toll, Block))); } else { BlockTemp = 0; } } Temp -= BlockTemp; }); Sum += Temp / Math.Max(1, Blocks.Count); } } int SumSelf = 0; if (Including) { List <PBlock> Blocks = NextBlocks(Game, Player); Blocks.ForEach((PBlock Block) => { int BlockTemp = 0; if (Block.Lord != null && Player.TeamIndex != Block.Lord.TeamIndex) { BlockTemp = Math.Max(0, -PAiTargetChooser.InjureExpect(Game, Player, Block.Lord, Player, Block.Toll, Block)); } if (Player.General is P_Newton) { PBlock PossibleBlock = Game.Map.NextStepBlock(Block, P_Newton.Grx_Next(Game, Player.Position).Value); if (PossibleBlock.Lord != null && Player.TeamIndex != PossibleBlock.Lord.TeamIndex) { BlockTemp = Math.Max(BlockTemp, Math.Max(0, -PAiTargetChooser.InjureExpect(Game, Player, Block.Lord, Player, Block.Toll, Block))); } else { BlockTemp = 0; } } SumSelf += BlockTemp; }); SumSelf /= Math.Max(1, Blocks.Count); } return(Sum + SumSelf); }
public static int Expect(PGame Game, PPlayer Player, PBlock Block, bool InPortal = false) { int DeltaMoney = 0; int Disaster = Block.GetMoneyStopSolid; if (Disaster < 0 && -Disaster <= 1000 && Player.Traffic != null && Player.Traffic.Model is P_NanManHsiang) { Disaster = 0; } else if (Disaster < 0 && Player.Defensor != null && Player.Defensor.Model is P_YinYangChing) { Disaster = 0; } DeltaMoney += Disaster; Disaster = PMath.Percent(Player.Money, Block.GetMoneyStopPercent); if (Disaster < 0 && -Disaster <= 1000 && Player.Traffic != null && Player.Traffic.Model is P_NanManHsiang) { Disaster = 0; } else if (Disaster < 0 && Player.Defensor != null && Player.Defensor.Model is P_YinYangChing) { Disaster = 0; } DeltaMoney += Disaster; if (Block.Lord != null && Block.Lord.TeamIndex != Player.TeamIndex) { int Toll = Block.Toll; if (Block.BusinessType.Equals(PBusinessType.ShoppingCenter)) { Toll *= 2; } if (Block.BusinessType.Equals(PBusinessType.Club)) { Toll += PMath.Percent(Toll, 100); } if (Block.Lord.Weapon != null && Block.Lord.Weapon.Model is P_KuTingTao && Player.Area.HandCardArea.CardNumber == 0) { Toll *= 2; } if (Toll <= 1000 && Player.Traffic != null && Player.Traffic.Model is P_NanManHsiang) { Toll = 0; } DeltaMoney -= Toll; } if (Player.Money + DeltaMoney <= 0) { return(-30000 + DeltaMoney * 2); } else if (Player.Money <= 3000) { DeltaMoney *= 2; } DeltaMoney += 2000 * Block.GetCardStop; int LandValue = 0; if (Block.Lord == null && Block.Price < Player.Money) { LandValue = PMath.Percent(Block.Price, 10) * Game.Enemies(Player).Count; if (Block.IsBusinessLand) { LandValue += PMath.Max(PAiBusinessChooser.DirectionExpectations(Game, Player, Block)); } } else if (Player.Equals(Block.Lord)) { int PurchaseLimit = Player.PurchaseLimit; LandValue += PMath.Percent(Block.Price, 20) * Game.Enemies(Player).Count *PurchaseLimit; if (Block.BusinessType.Equals(PBusinessType.Park)) { LandValue += PMath.Percent(Block.Price, 60) * PurchaseLimit; } else if (Block.BusinessType.Equals(PBusinessType.ShoppingCenter) || Block.BusinessType.Equals(PBusinessType.Club)) { LandValue += PMath.Percent(Block.Price, 20) * Game.Enemies(Player).Count *PurchaseLimit; } if (Player.General is P_YangYuHuan) { LandValue += P_ShunShouChiienYang.AIExpect(Game, Player, 0).Value; } } if (Block.Lord != null && Block.Lord.TeamIndex == Player.TeamIndex) { if (Block.BusinessType.Equals(PBusinessType.Institute)) { LandValue += 2 * 2000; } else if (Block.BusinessType.Equals(PBusinessType.Pawnshop)) { LandValue += 2000; } if (Player.General is P_PanYue && (Block.PortalBlockList.Count == 0 || InPortal)) { if (!Player.Equals(Game.NowPlayer) || Player.RemainLimit("闲居")) { LandValue += PMath.Percent(Block.Price, 20 * Game.Enemies(Player).Count + 50); } } } int PortalValue = 0; if (!InPortal && Block.PortalBlockList.Count > 0) { PortalValue = PMath.Max(Block.PortalBlockList, (PBlock _Block) => Expect(Game, Player, _Block, true)).Value; } return(DeltaMoney + LandValue * 20 / GetRingLength(Game, Block) + PortalValue); }
/// <summary> /// 返回最低价值的房屋 /// </summary> /// <param name="Game"></param> /// <param name="Player">房屋所有者</param> /// <param name="StartFromZero">是否允许土地上实际没有房屋</param> /// <param name="Concentrate">是否优先选取房屋数量少的土地的房屋</param> /// <returns></returns> public static KeyValuePair <PBlock, int> MinValueHouse(PGame Game, PPlayer Player, bool StartFromZero = false, bool Concentrate = false) { KeyValuePair <PBlock, int> Test = PMath.Min(Game.Map.BlockList.FindAll((PBlock Block) => Player.Equals(Block.Lord) && (StartFromZero || Block.HouseNumber > 0)), (PBlock Block) => { return(HouseValue(Game, Player, Block) * 1000 + (Concentrate ? Block.HouseNumber : 0)); }); return(new KeyValuePair <PBlock, int>(Test.Key, Test.Value / 1000)); }
public static KeyValuePair <PBlock, int> MaxValueHouse(PGame Game, PPlayer Player, bool StartFromZero = false) { return(PMath.Max(Game.Map.BlockList.FindAll((PBlock Block) => Player.Equals(Block.Lord) && (StartFromZero || Block.HouseNumber > 0)), (PBlock Block) => { return HouseValue(Game, Player, Block); })); }