/// <summary> /// Called when the AI has to select one or more cards. /// </summary> /// <param name="cards">List of available cards.</param> /// <param name="min">Minimal quantity.</param> /// <param name="max">Maximal quantity.</param> /// <param name="cancelable">True if you can return an empty list.</param> /// <returns>A new list containing the selected cards.</returns> public IList <ClientCard> OnSelectCard(IList <ClientCard> cards, int min, int max, bool cancelable) { // Check for the executor. IList <ClientCard> result = Executor.OnSelectCard(cards, min, max, cancelable); if (result != null) { return(result); } // Update the next selector. CardSelector selector = GetSelectedCards(); // If we selected a card, use this card. if (selector != null) { return(selector.Select(cards, min, max)); } // Always select the first available cards and choose the minimum. IList <ClientCard> selected = new List <ClientCard>(); for (int i = 0; i < min; ++i) { selected.Add(cards[i]); } return(selected); }
/// <summary> /// Called when the AI has to select one or more cards. /// </summary> /// <param name="cards">List of available cards.</param> /// <param name="min">Minimal quantity.</param> /// <param name="max">Maximal quantity.</param> /// <param name="hint">The hint message of the select.</param> /// <param name="cancelable">True if you can return an empty list.</param> /// <returns>A new list containing the selected cards.</returns> public IList <ClientCard> OnSelectCard(IList <ClientCard> cards, int min, int max, long hint, bool cancelable) { const long HINTMSG_FMATERIAL = 511; const long HINTMSG_SMATERIAL = 512; const long HINTMSG_XMATERIAL = 513; const long HINTMSG_LMATERIAL = 533; const long HINTMSG_SPSUMMON = 509; // Check for the executor. IList <ClientCard> result = Executor.OnSelectCard(cards, min, max, hint, cancelable); if (result != null) { return(result); } if (hint == HINTMSG_SPSUMMON && min == 1 && max > min) // pendulum summon { result = Executor.OnSelectPendulumSummon(cards, max); if (result != null) { return(result); } } CardSelector selector = null; if (hint == HINTMSG_FMATERIAL || hint == HINTMSG_SMATERIAL || hint == HINTMSG_XMATERIAL || hint == HINTMSG_LMATERIAL) { if (m_materialSelector != null) { //Logger.DebugWriteLine("m_materialSelector"); selector = m_materialSelector; } else { if (hint == HINTMSG_FMATERIAL) { result = Executor.OnSelectFusionMaterial(cards, min, max); } if (hint == HINTMSG_SMATERIAL) { result = Executor.OnSelectSynchroMaterial(cards, 0, min, max); } if (hint == HINTMSG_XMATERIAL) { result = Executor.OnSelectXyzMaterial(cards, min, max); } if (hint == HINTMSG_LMATERIAL) { result = Executor.OnSelectLinkMaterial(cards, min, max); } if (result != null) { return(result); } // Update the next selector. selector = GetSelectedCards(); } } else { // Update the next selector. selector = GetSelectedCards(); } // If we selected a card, use this card. if (selector != null) { return(selector.Select(cards, min, max)); } // Always select the first available cards and choose the minimum. IList <ClientCard> selected = new List <ClientCard>(); if (cards.Count >= min) { for (int i = 0; i < min; ++i) { selected.Add(cards[i]); } } return(selected); }
/// <summary> /// Called when the AI has to select one or more cards. /// </summary> /// <param name="cards">List of available cards.</param> /// <param name="min">Minimal quantity.</param> /// <param name="max">Maximal quantity.</param> /// <param name="hint">The hint message of the select.</param> /// <param name="cancelable">True if you can return an empty list.</param> /// <returns>A new list containing the selected cards.</returns> public IList <ClientCard> OnSelectCard(IList <ClientCard> cards, int min, int max, int hint, bool cancelable) { // Check for the executor. IList <ClientCard> result = Executor.OnSelectCard(cards, min, max, hint, cancelable); if (result != null) { return(result); } if (hint == HintMsg.SpSummon && min == 1 && max > min) // pendulum summon { result = Executor.OnSelectPendulumSummon(cards, max); if (result != null) { return(result); } } CardSelector selector = null; if (hint == HintMsg.FusionMaterial || hint == HintMsg.SynchroMaterial || hint == HintMsg.XyzMaterial || hint == HintMsg.LinkMaterial) { if (m_materialSelector != null) { //Logger.DebugWriteLine("m_materialSelector"); selector = m_materialSelector; } else { if (hint == HintMsg.FusionMaterial) { result = Executor.OnSelectFusionMaterial(cards, min, max); } if (hint == HintMsg.SynchroMaterial) { result = Executor.OnSelectSynchroMaterial(cards, 0, min, max); } if (hint == HintMsg.XyzMaterial) { result = Executor.OnSelectXyzMaterial(cards, min, max); } if (hint == HintMsg.LinkMaterial) { result = Executor.OnSelectLinkMaterial(cards, min, max); } if (result != null) { return(result); } // Update the next selector. selector = GetSelectedCards(); } } else { if (m_materialSelector != null && hint == m_materialSelectorHint) { //Logger.DebugWriteLine("m_materialSelector hint match"); selector = m_materialSelector; } else { // Update the next selector. selector = GetSelectedCards(); } } // If we selected a card, use this card. if (selector != null) { return(selector.Select(cards, min, max)); } // Always select the first available cards and choose the minimum. IList <ClientCard> selected = new List <ClientCard>(); if (cards.Count >= min) { for (int i = 0; i < min; ++i) { selected.Add(cards[i]); } } return(selected); }
public async Task <PlayData> PlayAsync(Players players) { _ = players ?? throw new ArgumentNullException(); if (players.Count < 4) { throw new ArgumentException("Number of players cannot be less than 4"); } _ = CardPacks ?? throw new NullReferenceException("Card packs cannot be null"); if (CardPacks.Length == 0) { throw new InvalidOperationException("CardPacks cannot be null"); } var playerId = ""; IList <RoundData> gameData = new List <RoundData>(); await Task.Run(() => { CardPackShuffler.Shuffle(CardPacks); CardHandOuter.HandOut(CardPacks, players); IList <Card> activeCards = new List <Card>(); IList <Card> inactiveCards = new List <Card>(); int playerIndex = 0; bool isEnd = false; foreach (var cp in CardPacks) { ((List <Card>)activeCards).AddRange(cp); } while (!isEnd) { IList <TurnData> round = new List <TurnData>(); int errCount = 0; int passedCount = 0; bool endOfRound = false; while (!endOfRound) { for (int i = playerIndex; i < players.Count; i++) { var player = players[i]; var selectedCards = CardSelector.Select(player.ToArray(), round.ToArray(), activeCards, inactiveCards); selectedCards = SelectionRulesChecker.Check(selectedCards, player.ToArray(), round.ToArray()) ? selectedCards : new Card[0]; passedCount = (selectedCards.Length == 0) ? passedCount + 1 : 0; foreach (var card in selectedCards) { inactiveCards.Add(card); activeCards.Remove(card); player.RemoveCard(card); } if (player.ToArray().Length == 0) { if (playerId == "") { playerId = player.PlayerID; } players.RemovePlayer(player); } round.Add(new TurnData(player, selectedCards.ToArray(), round.ToArray(), activeCards.ToArray(), inactiveCards.ToArray())); if (passedCount == players.Count - 1) { playerIndex = (i == passedCount) ? 0 : i + 1; isEnd = (players.Count == 1); endOfRound = true; break; } playerIndex = 0; } errCount++; if (errCount > 99) { throw new OperationCanceledException(); } } gameData.Add(new RoundData(round.ToArray())); } gameData.Add(new RoundData(new TurnData[] { new TurnData(players[0], new Card[0], new TurnData[0], new Card[0], new Card[0]) })); }); return(new PlayData(gameData.ToArray(), playerId)); }