/// <summary> /// Called when it's a new turn. /// </summary> public void OnNewTurn() { _dialogs.SendMessage($"Turn {Duel.Turn} ------------------------------------------------"); if (Executor is RandomExecutorBase RandomExecutor) { _dialogs.SendMessage("Card Advantage Turn:" + RandomExecutor.GetCardAdvantageField().ToString()); } Executor.OnNewTurn(); }
/// <summary> /// Called when the AI has to do something during the main phase. /// </summary> /// <param name="main">A lot of informations about the available actions.</param> /// <returns>A new MainPhaseAction containing the action to do.</returns> public MainPhaseAction OnSelectIdleCmd(MainPhase main) { if (Executor is RandomExecutorBase RandomExecutor) { RandomExecutor.SetMain(main); ChoiceWeight choice = new ChoiceWeight(RandomExecutor, Duel.Phase, Duel.Turn, _dialogs); //loop through setable monsters foreach (ClientCard card in main.MonsterSetableCards) { choice.SetBest(MainPhaseAction.MainAction.SetMonster, card, card.ActionIndex[(int)MainPhaseAction.MainAction.SetMonster]); } //loop through cards that can change position foreach (ClientCard card in main.ReposableCards) { choice.SetBest(MainPhaseAction.MainAction.Repos, card, card.ActionIndex[(int)MainPhaseAction.MainAction.Repos]); } //Loop through normal summonable monsters foreach (ClientCard card in main.SummonableCards) { choice.SetBest(MainPhaseAction.MainAction.Summon, card, card.ActionIndex[(int)MainPhaseAction.MainAction.Summon]); } //loop through special summonable monsters foreach (ClientCard card in main.SpecialSummonableCards) { choice.SetBest(MainPhaseAction.MainAction.SpSummon, card, card.ActionIndex[(int)MainPhaseAction.MainAction.SpSummon]); } //loop through activatable cards for (int i = 0; i < main.ActivableCards.Count; ++i) { ClientCard card = main.ActivableCards[i]; choice.SetBest(MainPhaseAction.MainAction.Activate, card, card.ActionActivateIndex[main.ActivableDescs[i]]); } switch (choice.BestAction) { case MainPhaseAction.MainAction.Activate: // _dialogs.SendActivate(choice.BestCard.Name); break; case MainPhaseAction.MainAction.Repos: break; case MainPhaseAction.MainAction.SetMonster: // _dialogs.SendSetMonster(); break; case MainPhaseAction.MainAction.SetSpell: break; case MainPhaseAction.MainAction.SpSummon: //_dialogs.SendSummon(choice.BestCard.Name); break; case MainPhaseAction.MainAction.Summon: //_dialogs.SendSummon(choice.BestCard.Name); break; default: if (main.CanBattlePhase && Duel.Fields[0].HasAttackingMonster()) { choice.RecordAction(MainPhaseAction.MainAction.ToBattlePhase, null, -1, 1); return(new MainPhaseAction(MainPhaseAction.MainAction.ToBattlePhase)); } _dialogs.SendEndTurn(); _dialogs.SendMessage("Card Advantage:" + RandomExecutor.GetCardAdvantageField().ToString()); choice.RecordAction(MainPhaseAction.MainAction.ToEndPhase, null, -1, 1); return(new MainPhaseAction(MainPhaseAction.MainAction.ToEndPhase)); } return(choice.ReturnBestAction()); } else//the regular one { Executor.SetMain(main); foreach (CardExecutor exec in Executor.Executors) { if (exec.Type == ExecutorType.GoToEndPhase && main.CanEndPhase && exec.Func()) // check if should enter end phase directly { _dialogs.SendEndTurn(); return(new MainPhaseAction(MainPhaseAction.MainAction.ToEndPhase)); } if (exec.Type == ExecutorType.GoToBattlePhase && main.CanBattlePhase && exec.Func()) // check if should enter battle phase directly { return(new MainPhaseAction(MainPhaseAction.MainAction.ToBattlePhase)); } // NOTICE: GoToBattlePhase and GoToEndPhase has no "card" can be accessed to ShouldExecute(), so instead use exec.Func() to check ... // enter end phase and enter battle pahse is in higher priority. for (int i = 0; i < main.ActivableCards.Count; ++i) { ClientCard card = main.ActivableCards[i]; if (ShouldExecute(exec, card, ExecutorType.Activate, main.ActivableDescs[i])) { _dialogs.SendActivate(card.Name); Logger.WriteToFile($"{card.Name}]{card.Id}"); return(new MainPhaseAction(MainPhaseAction.MainAction.Activate, card.ActionActivateIndex[main.ActivableDescs[i]])); } } foreach (ClientCard card in main.MonsterSetableCards) { if (ShouldExecute(exec, card, ExecutorType.MonsterSet)) { _dialogs.SendSetMonster(); Logger.WriteToFile($"{card.Name}]{card.Id}"); return(new MainPhaseAction(MainPhaseAction.MainAction.SetMonster, card.ActionIndex)); } } foreach (ClientCard card in main.ReposableCards) { if (ShouldExecute(exec, card, ExecutorType.Repos)) { return(new MainPhaseAction(MainPhaseAction.MainAction.Repos, card.ActionIndex)); } } foreach (ClientCard card in main.SpecialSummonableCards) { if (ShouldExecute(exec, card, ExecutorType.SpSummon)) { _dialogs.SendSummon(card.Name); Logger.WriteToFile($"{card.Name}]{card.Id}"); return(new MainPhaseAction(MainPhaseAction.MainAction.SpSummon, card.ActionIndex)); } } foreach (ClientCard card in main.SummonableCards) { if (ShouldExecute(exec, card, ExecutorType.Summon)) { _dialogs.SendSummon(card.Name); Logger.WriteToFile($"{card.Name}]{card.Id}"); return(new MainPhaseAction(MainPhaseAction.MainAction.Summon, card.ActionIndex)); } if (ShouldExecute(exec, card, ExecutorType.SummonOrSet)) { if (Executor.Util.IsAllEnemyBetter(true) && Executor.Util.IsAllEnemyBetterThanValue(card.Attack + 300, false) && main.MonsterSetableCards.Contains(card)) { _dialogs.SendSetMonster(); Logger.WriteToFile($"{card.Name}]{card.Id}"); return(new MainPhaseAction(MainPhaseAction.MainAction.SetMonster, card.ActionIndex)); } _dialogs.SendSummon(card.Name); Logger.WriteToFile($"{card.Name}]{card.Id}"); return(new MainPhaseAction(MainPhaseAction.MainAction.Summon, card.ActionIndex)); } } foreach (ClientCard card in main.SpellSetableCards) { if (ShouldExecute(exec, card, ExecutorType.SpellSet)) { return(new MainPhaseAction(MainPhaseAction.MainAction.SetSpell, card.ActionIndex)); } } } if (main.CanBattlePhase && Duel.Fields[0].HasAttackingMonster()) { return(new MainPhaseAction(MainPhaseAction.MainAction.ToBattlePhase)); } _dialogs.SendEndTurn(); return(new MainPhaseAction(MainPhaseAction.MainAction.ToEndPhase)); } }