public void getHoldList(MulliganData mulliganData) { cards.Clear(); for (var i = 0; i < mulliganData.Cards.Count; i++) { cards.Add(new CardIDEntity(mulliganData.Cards[i].Entity.Id, i)); } HeroEnum ownHeroClass = heroTAG_CLASSstringToEnum(mulliganData.UserClass.ToString()); HeroEnum enemyHeroClass = heroTAG_CLASSstringToEnum(mulliganData.OpponentClass.ToString()); if (!(cards.Count == 3 || cards.Count == 4)) { Helpfunctions.Instance.ErrorLog("[Mulligan] Mulligan is not used, since it got number of cards: " + cards.Count.ToString()); return; } int manaRule = 4; string MullRuleKey = getMullRuleKey(CardDB.cardIDEnum.None, ownHeroClass, enemyHeroClass, false); if (MulliganRules.ContainsKey(MullRuleKey)) { string[] temp = MulliganRules[MullRuleKey].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); manaRule = Convert.ToInt32(temp[1]); } else { MullRuleKey = getMullRuleKey(CardDB.cardIDEnum.None, ownHeroClass, HeroEnum.None, false); if (MulliganRules.ContainsKey(MullRuleKey)) { string[] temp = MulliganRules[MullRuleKey].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); manaRule = Convert.ToInt32(temp[1]); } } CardIDEntity Coin = new CardIDEntity("GAME_005", -888); if (cards.Count == 4) cards.Add(Coin); //we have a coin foreach (CardIDEntity CardIDEntityC in cards) { int allowedQuantity = 2; CardDB.Card c = CardDB.Instance.getCardDataFromID(CardIDEntityC.id); if (CardIDEntityC.hold == 0 && CardIDEntityC.holdByRule == 0) { if (c.cost < manaRule) { CardIDEntityC.holdByManarule = 2; CardIDEntityC.holdReason = joinSomeTxt("hold because the card cost:", c.cost.ToString(), " is less then Manarule cost:", manaRule.ToString()); } else { CardIDEntityC.holdByManarule = -2; CardIDEntityC.holdReason = joinSomeTxt("discard because the card cost:", c.cost.ToString(), " is not less then Manarule cost:", manaRule.ToString()); } } //check Hold int hasRuleHold = 0; //0=None, 1=All, 2=Class, 11=All+Rule, 12=Class+Rule int hasRuleDiscard = 0; //0=None, -1=All, -2=Class, -11=All+Rule, -12=Class+Rule string MullRuleValueHold = ""; string MullRuleKeyHold = getMullRuleKey(c.cardIDenum, ownHeroClass, enemyHeroClass, true); if (MulliganRules.ContainsKey(MullRuleKeyHold)) { MullRuleValueHold = MulliganRules[MullRuleKeyHold]; hasRuleHold = 2; } else { MullRuleKeyHold = getMullRuleKey(c.cardIDenum, ownHeroClass, HeroEnum.None, true); //key for ALL enemy if (MulliganRules.ContainsKey(MullRuleKeyHold)) { MullRuleValueHold = MulliganRules[MullRuleKeyHold]; hasRuleHold = 1; } } if (MullRuleValueHold != "") { string[] temp = MullRuleValueHold.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); if (temp[0] == "1") allowedQuantity = 1; if (temp[1] != "/") hasRuleHold += 10; } else hasRuleHold = 0; //check Discard string MullRuleValueDiscard = ""; string MullRuleKeyDiscard = getMullRuleKey(c.cardIDenum, ownHeroClass, enemyHeroClass, false); if (MulliganRules.ContainsKey(MullRuleKeyDiscard)) { MullRuleValueDiscard = MulliganRules[MullRuleKeyDiscard]; hasRuleDiscard = -2; } else { MullRuleKeyDiscard = getMullRuleKey(c.cardIDenum, ownHeroClass, HeroEnum.None, false); //key for ALL enemy if (MulliganRules.ContainsKey(MullRuleKeyDiscard)) { MullRuleValueDiscard = MulliganRules[MullRuleKeyDiscard]; hasRuleDiscard = -1; } } if (MullRuleValueDiscard != "") { string[] temp = MullRuleValueDiscard.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); if (temp[1] != "/") hasRuleDiscard -= 10; } else hasRuleDiscard = 0; //superimpose Class rules to All rules bool useHold = false; bool useDiscard = false; bool useHoldRule = false; bool useDiscardRule = false; if (hasRuleHold == 2) { useHold = true; if (hasRuleDiscard < -10) useDiscardRule = true; } else if (hasRuleDiscard == -2) { useDiscard = true; if (hasRuleHold > 10) useHoldRule = true; } if (hasRuleHold == 1) { if (hasRuleDiscard == 0 || hasRuleDiscard < -10) useHold = true; if (hasRuleDiscard < -10) useDiscardRule = true; } else if (hasRuleDiscard == -1) { if (hasRuleHold == 0 || hasRuleHold > 10) useDiscard = true; if (hasRuleHold > 10) useHoldRule = true; } if (hasRuleDiscard == 0 && hasRuleHold > 10) useHoldRule = true; else if (hasRuleHold == 0 && hasRuleDiscard < -10) useDiscardRule = true; //apply the rules if (useDiscardRule) { string[] temp = MullRuleValueDiscard.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); if (temp[1] != "/") { string[] addedCards = temp[1].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries); MulliganRulesManual.Clear(); foreach (string s in addedCards) { MulliganRulesManual.Add(CardDB.Instance.cardIdstringToEnum(s), ""); } foreach (CardIDEntity tmp in cards) { if (CardIDEntityC.entity == tmp.entity) continue; if (MulliganRulesManual.ContainsKey(tmp.id)) { CardIDEntityC.holdByRule = -2; CardIDEntityC.holdReason = joinSomeTxt("discard by rule: ", MullRuleKeyDiscard, ":", MulliganRules[MullRuleKeyDiscard]); break; } } } } else if (useDiscard) { CardIDEntityC.hold = -2; CardIDEntityC.holdReason = joinSomeTxt("discard by rule: ", MullRuleKeyDiscard, ":", MulliganRules[MullRuleKeyDiscard]); } if (useHoldRule) { string[] temp = MullRuleValueHold.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); if (CardIDEntityC.holdByRule == 0) { string[] addedCards = temp[1].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries); MulliganRulesManual.Clear(); foreach (string s in addedCards) { MulliganRulesManual.Add(CardDB.Instance.cardIdstringToEnum(s), ""); } bool foundFreeCard = false; for (int i = 0; i < cards.Count; i++) { if (CardIDEntityC.entity == cards[i].entity) continue; if (MulliganRulesManual.ContainsKey(cards[i].id)) //we found the right card { CardIDEntityC.holdByRule = 2; CardIDEntityC.holdReason = joinSomeTxt("hold by rule: ", MullRuleKeyHold, ":", MulliganRules[MullRuleKeyHold]); if (cards[i].holdByRule < 0) //if the right card is busy, check other cards { for (int j = i; j < cards.Count; j++) { if (CardIDEntityC.entity == cards[j].entity) continue; if (MulliganRulesManual.ContainsKey(cards[j].id)) { if (cards[j].holdByRule < 0) continue; foundFreeCard = true; cards[j].holdByRule = 2; cards[j].holdReason = joinSomeTxt("hold by rule: ", MullRuleKeyHold, ":", MulliganRules[MullRuleKeyHold]); break; } } if (!foundFreeCard) { foundFreeCard = true; cards[i].holdByRule = 2; cards[i].holdReason = joinSomeTxt("hold by rule: ", MullRuleKeyHold, ":", MulliganRules[MullRuleKeyHold]); break; } } else { foundFreeCard = true; cards[i].holdByRule = 2; cards[i].holdReason = joinSomeTxt("hold by rule: ", MullRuleKeyHold, ":", MulliganRules[MullRuleKeyHold]); } if (allowedQuantity == 1) { foreach (CardIDEntity tmp in cards) { if (tmp.entity == CardIDEntityC.entity) continue; if (tmp.id == CardIDEntityC.id) { tmp.holdByRule = -2; tmp.holdReason = joinSomeTxt("discard by rule: ", MullRuleKeyHold, ":", MulliganRules[MullRuleKeyHold]); } } } } } } } else if (useHold && CardIDEntityC.holdByRule != -2) { if (CardIDEntityC.hold == 0) { CardIDEntityC.hold = 2; CardIDEntityC.holdReason = joinSomeTxt("hold by rule: ", MullRuleKeyHold, ":", MulliganRules[MullRuleKeyHold]); if (allowedQuantity == 1) { CardIDEntityC.hold = 1; foreach (CardIDEntity tmp in cards) { if (tmp.entity == CardIDEntityC.entity) continue; if (tmp.id == CardIDEntityC.id) { tmp.hold = -2; tmp.holdReason = joinSomeTxt("discard Second card by rule: ", MullRuleKeyHold, ":", MulliganRules[MullRuleKeyHold]); } } } } } } if (cards.Count == 5) cards.Remove(Coin); foreach (CardIDEntity c in cards) { if (c.holdByRule == 0) { if (c.hold == 0) { c.holdByRule = c.holdByManarule; } else { c.holdByRule = c.hold; } } } for (var i = 0; i < mulliganData.Cards.Count; i++) { mulliganData.Mulligans[i] = (cards[i].holdByRule > 0) ? false : true; Log.InfoFormat("[Mulligan] {0} {1}.", mulliganData.Cards[i].Entity.Name, cards[i].holdReason); } return; }
public bool getHoldList(MulliganData mulliganData, Behavior behave) { cards.Clear(); readRules(behave.BehaviorName()); if (!mulliganRulesLoaded) { return(false); } if (!(mulliganData.Cards.Count == 3 || mulliganData.Cards.Count == 4)) { Helpfunctions.Instance.ErrorLog("[Mulligan] Mulligan is not used, since it got number of cards: " + cards.Count.ToString()); return(false); } Log.InfoFormat("[Mulligan] Apply the {0} rules:", behave.BehaviorName()); for (var i = 0; i < mulliganData.Cards.Count; i++) { cards.Add(new CardIDEntity(mulliganData.Cards[i].Entity.Id, i)); } HeroEnum ownHeroClass = Hrtprozis.Instance.heroTAG_CLASSstringToEnum(mulliganData.UserClass.ToString()); HeroEnum enemyHeroClass = Hrtprozis.Instance.heroTAG_CLASSstringToEnum(mulliganData.OpponentClass.ToString()); int manaRule = 4; string MullRuleKey = getMullRuleKey(CardIdEnum.None, ownHeroClass, enemyHeroClass, 1); if (MulliganRules.ContainsKey(MullRuleKey)) { string[] temp = MulliganRules[MullRuleKey].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); manaRule = Convert.ToInt32(temp[2]); } else { MullRuleKey = getMullRuleKey(CardIdEnum.None, ownHeroClass, HeroEnum.None, 1); if (MulliganRules.ContainsKey(MullRuleKey)) { string[] temp = MulliganRules[MullRuleKey].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); manaRule = Convert.ToInt32(temp[2]); } } CardIDEntity Coin = new CardIDEntity("GAME_005", -888); if (cards.Count == 4) { cards.Add(Coin); //we have a coin } foreach (CardIDEntity CardIDEntityC in cards) { CardDB.Card c = CardDB.Instance.getCardDataFromID(CardIDEntityC.id); if (CardIDEntityC.hold == 0 && CardIDEntityC.holdByRule == 0) { if (c.cost < manaRule) { CardIDEntityC.holdByManarule = 2; CardIDEntityC.holdReason = joinSomeTxt("hold because the card cost:", c.cost.ToString(), " is less then Manarule cost:", manaRule.ToString()); } else { CardIDEntityC.holdByManarule = -2; CardIDEntityC.holdReason = joinSomeTxt("discard because the card cost:", c.cost.ToString(), " is not less then Manarule cost:", manaRule.ToString()); } } int allowedQuantitySimple = 0; int allowedQuantityExtra = 0; bool hasRuleClassSimple = false; bool hasRule = false; string MullRuleKeySimple = getMullRuleKey(c.cardIDenum, ownHeroClass, enemyHeroClass, 0); //Simple key for Class enemy if (MulliganRules.ContainsKey(MullRuleKeySimple)) { hasRule = true; hasRuleClassSimple = true; } else { MullRuleKeySimple = getMullRuleKey(c.cardIDenum, ownHeroClass, HeroEnum.None, 0); //Simple key for ALL enemy if (MulliganRules.ContainsKey(MullRuleKeySimple)) { hasRule = true; } } if (hasRule) { string[] val = MulliganRules[MullRuleKeySimple].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); allowedQuantitySimple = ((val[1] == "2") ? 2 : 1) * ((val[0] == "Hold") ? 1 : -1); } hasRule = false; string MullRuleKeyExtra = getMullRuleKey(c.cardIDenum, ownHeroClass, enemyHeroClass, 1); //Extra key for Class enemy if (MulliganRules.ContainsKey(MullRuleKeyExtra)) { hasRule = true; } else if (!hasRuleClassSimple) { MullRuleKeyExtra = getMullRuleKey(c.cardIDenum, ownHeroClass, HeroEnum.None, 1); //Extra key for ALL enemy if (MulliganRules.ContainsKey(MullRuleKeyExtra)) { hasRule = true; } } if (hasRule) { string[] val = MulliganRules[MullRuleKeyExtra].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); allowedQuantityExtra = ((val[1] == "2") ? 2 : 1) * ((val[0] == "Hold") ? 1 : -1); } //superimpose Class rules to All rules bool useHold = false; bool useDiscard = false; bool useHoldRule = false; bool useDiscardRule = false; if (allowedQuantitySimple != 0 && allowedQuantitySimple != allowedQuantityExtra) { if (allowedQuantitySimple > 0) { useHold = true; } else { useDiscard = true; } } if (allowedQuantityExtra != 0) { if (allowedQuantityExtra < 0) { useDiscardRule = true; } else { useHoldRule = true; } } //apply the rules string[] MullRuleValueExtra = new string[3]; if (allowedQuantityExtra != 0) { MullRuleValueExtra = MulliganRules[MullRuleKeyExtra].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); } if (useDiscardRule) { if (MullRuleValueExtra[2] != "/") { string[] addedCards = MullRuleValueExtra[2].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries); MulliganRulesManual.Clear(); foreach (string s in addedCards) { MulliganRulesManual.Add(CardDB.Instance.cardIdstringToEnum(s), ""); } foreach (CardIDEntity tmp in cards) { if (CardIDEntityC.entitiy == tmp.entitiy) { continue; } if (MulliganRulesManual.ContainsKey(tmp.id)) { CardIDEntityC.holdByRule = -2; CardIDEntityC.holdReason = joinSomeTxt("discard by rule: ", getClearRule(MullRuleKeyExtra)); break; } } } } else if (useDiscard) { CardIDEntityC.hold = -2; CardIDEntityC.holdReason = joinSomeTxt("discard by rule: ", getClearRule(MullRuleKeySimple)); } if (useHoldRule) { if (CardIDEntityC.holdByRule == 0) { string[] addedCards = MullRuleValueExtra[2].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries); MulliganRulesManual.Clear(); foreach (string s in addedCards) { MulliganRulesManual.Add(CardDB.Instance.cardIdstringToEnum(s), ""); } bool foundFreeCard = false; for (int i = 0; i < cards.Count; i++) { if (CardIDEntityC.entitiy == cards[i].entitiy) { continue; } if (MulliganRulesManual.ContainsKey(cards[i].id)) { CardIDEntityC.holdByRule = 2; CardIDEntityC.holdReason = joinSomeTxt("hold by rule: ", getClearRule(MullRuleKeyExtra)); if (cards[i].holdByRule < 0) { for (int j = i; j < cards.Count; j++) { if (CardIDEntityC.entitiy == cards[j].entitiy) { continue; } if (MulliganRulesManual.ContainsKey(cards[j].id)) { if (cards[j].holdByRule < 0) { continue; } foundFreeCard = true; cards[j].holdByRule = 2; cards[j].holdReason = joinSomeTxt("hold by rule: ", getClearRule(MullRuleKeyExtra)); break; } } if (!foundFreeCard) { foundFreeCard = true; cards[i].holdByRule = 2; cards[i].holdReason = joinSomeTxt("hold by rule: ", getClearRule(MullRuleKeyExtra)); break; } } else { foundFreeCard = true; cards[i].holdByRule = 2; cards[i].holdReason = joinSomeTxt("hold by rule: ", getClearRule(MullRuleKeyExtra)); } if (allowedQuantityExtra == 1) { foreach (CardIDEntity tmp in cards) { if (tmp.entitiy == CardIDEntityC.entitiy) { continue; } if (tmp.id == CardIDEntityC.id) { tmp.holdByRule = -2; tmp.holdReason = joinSomeTxt("discard by rule: ", getClearRule(MullRuleKeyExtra)); } } } } } } } if (useHold && CardIDEntityC.holdByRule != -2) { if (CardIDEntityC.hold == 0) { CardIDEntityC.hold = 2; CardIDEntityC.holdReason = joinSomeTxt("hold by rule: ", getClearRule(MullRuleKeySimple)); if (allowedQuantitySimple == 1) { CardIDEntityC.hold = 1; foreach (CardIDEntity tmp in cards) { if (tmp.entitiy == CardIDEntityC.entitiy) { continue; } if (tmp.id == CardIDEntityC.id) { tmp.hold = -2; tmp.holdReason = joinSomeTxt("discard Second card by rule: ", getClearRule(MullRuleKeySimple)); } } } } } } if (cards.Count == 5) { cards.Remove(Coin); } foreach (CardIDEntity c in cards) { if (c.holdByRule == 0) { if (c.hold == 0) { c.holdByRule = c.holdByManarule; } else { c.holdByRule = c.hold; } } } for (var i = 0; i < mulliganData.Cards.Count; i++) { mulliganData.Mulligans[i] = (cards[i].holdByRule > 0) ? false : true; Log.InfoFormat("[Mulligan] {0} {1}.", mulliganData.Cards[i].Entity.Name, cards[i].holdReason); } return(true); }
public void getHoldList(MulliganData mulliganData) { cards.Clear(); for (var i = 0; i < mulliganData.Cards.Count; i++) { cards.Add(new CardIDEntity(mulliganData.Cards[i].Entity.Id, i)); } HeroEnum ownHeroClass = heroTAG_CLASSstringToEnum(mulliganData.UserClass.ToString()); HeroEnum enemyHeroClass = heroTAG_CLASSstringToEnum(mulliganData.OpponentClass.ToString()); if (!(cards.Count == 3 || cards.Count == 4)) { Helpfunctions.Instance.ErrorLog("[Mulligan] Mulligan is not used, since it got number of cards: " + cards.Count.ToString()); return; } int manaRule = 4; string MullRuleKey = getMullRuleKey(CardDB.cardIDEnum.None, ownHeroClass, enemyHeroClass, false); if (MulliganRules.ContainsKey(MullRuleKey)) { string[] temp = MulliganRules[MullRuleKey].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); manaRule = Convert.ToInt32(temp[1]); } else { MullRuleKey = getMullRuleKey(CardDB.cardIDEnum.None, ownHeroClass, HeroEnum.None, false); if (MulliganRules.ContainsKey(MullRuleKey)) { string[] temp = MulliganRules[MullRuleKey].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); manaRule = Convert.ToInt32(temp[1]); } } CardIDEntity Coin = new CardIDEntity("GAME_005", -888); if (cards.Count == 4) { cards.Add(Coin); //we have a coin } foreach (CardIDEntity CardIDEntityC in cards) { int allowedQuantity = 2; CardDB.Card c = CardDB.Instance.getCardDataFromID(CardIDEntityC.id); if (CardIDEntityC.hold == 0 && CardIDEntityC.holdByRule == 0) { if (c.cost < manaRule) { CardIDEntityC.holdByManarule = 2; CardIDEntityC.holdReason = joinSomeTxt("hold because the card cost:", c.cost.ToString(), " is less then Manarule cost:", manaRule.ToString()); } else { CardIDEntityC.holdByManarule = -2; CardIDEntityC.holdReason = joinSomeTxt("discard because the card cost:", c.cost.ToString(), " is not less then Manarule cost:", manaRule.ToString()); } } //check Hold int hasRuleHold = 0; //0=None, 1=All, 2=Class, 11=All+Rule, 12=Class+Rule int hasRuleDiscard = 0; //0=None, -1=All, -2=Class, -11=All+Rule, -12=Class+Rule string MullRuleValueHold = ""; string MullRuleKeyHold = getMullRuleKey(c.cardIDenum, ownHeroClass, enemyHeroClass, true); if (MulliganRules.ContainsKey(MullRuleKeyHold)) { MullRuleValueHold = MulliganRules[MullRuleKeyHold]; hasRuleHold = 2; } else { MullRuleKeyHold = getMullRuleKey(c.cardIDenum, ownHeroClass, HeroEnum.None, true); //key for ALL enemy if (MulliganRules.ContainsKey(MullRuleKeyHold)) { MullRuleValueHold = MulliganRules[MullRuleKeyHold]; hasRuleHold = 1; } } if (MullRuleValueHold != "") { string[] temp = MullRuleValueHold.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); if (temp[0] == "1") { allowedQuantity = 1; } if (temp[1] != "/") { hasRuleHold += 10; } } else { hasRuleHold = 0; } //check Discard string MullRuleValueDiscard = ""; string MullRuleKeyDiscard = getMullRuleKey(c.cardIDenum, ownHeroClass, enemyHeroClass, false); if (MulliganRules.ContainsKey(MullRuleKeyDiscard)) { MullRuleValueDiscard = MulliganRules[MullRuleKeyDiscard]; hasRuleDiscard = -2; } else { MullRuleKeyDiscard = getMullRuleKey(c.cardIDenum, ownHeroClass, HeroEnum.None, false); //key for ALL enemy if (MulliganRules.ContainsKey(MullRuleKeyDiscard)) { MullRuleValueDiscard = MulliganRules[MullRuleKeyDiscard]; hasRuleDiscard = -1; } } if (MullRuleValueDiscard != "") { string[] temp = MullRuleValueDiscard.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); if (temp[1] != "/") { hasRuleDiscard -= 10; } } else { hasRuleDiscard = 0; } //superimpose Class rules to All rules bool useHold = false; bool useDiscard = false; bool useHoldRule = false; bool useDiscardRule = false; if (hasRuleHold == 2) { useHold = true; if (hasRuleDiscard < -10) { useDiscardRule = true; } } else if (hasRuleDiscard == -2) { useDiscard = true; if (hasRuleHold > 10) { useHoldRule = true; } } if (hasRuleHold == 1) { if (hasRuleDiscard == 0 || hasRuleDiscard < -10) { useHold = true; } if (hasRuleDiscard < -10) { useDiscardRule = true; } } else if (hasRuleDiscard == -1) { if (hasRuleHold == 0 || hasRuleHold > 10) { useDiscard = true; } if (hasRuleHold > 10) { useHoldRule = true; } } if (hasRuleDiscard == 0 && hasRuleHold > 10) { useHoldRule = true; } else if (hasRuleHold == 0 && hasRuleDiscard < -10) { useDiscardRule = true; } //apply the rules if (useDiscardRule) { string[] temp = MullRuleValueDiscard.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); if (temp[1] != "/") { string[] addedCards = temp[1].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries); MulliganRulesManual.Clear(); foreach (string s in addedCards) { MulliganRulesManual.Add(CardDB.Instance.cardIdstringToEnum(s), ""); } foreach (CardIDEntity tmp in cards) { if (CardIDEntityC.entitiy == tmp.entitiy) { continue; } if (MulliganRulesManual.ContainsKey(tmp.id)) { CardIDEntityC.holdByRule = -2; CardIDEntityC.holdReason = joinSomeTxt("discard by rule: ", MullRuleKeyDiscard, ":", MulliganRules[MullRuleKeyDiscard]); break; } } } } else if (useDiscard) { CardIDEntityC.hold = -2; CardIDEntityC.holdReason = joinSomeTxt("discard by rule: ", MullRuleKeyDiscard, ":", MulliganRules[MullRuleKeyDiscard]); } if (useHoldRule) { string[] temp = MullRuleValueHold.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); if (CardIDEntityC.holdByRule == 0) { string[] addedCards = temp[1].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries); MulliganRulesManual.Clear(); foreach (string s in addedCards) { MulliganRulesManual.Add(CardDB.Instance.cardIdstringToEnum(s), ""); } bool foundFreeCard = false; for (int i = 0; i < cards.Count; i++) { if (CardIDEntityC.entitiy == cards[i].entitiy) { continue; } if (MulliganRulesManual.ContainsKey(cards[i].id)) //we found the right card { CardIDEntityC.holdByRule = 2; CardIDEntityC.holdReason = joinSomeTxt("hold by rule: ", MullRuleKeyHold, ":", MulliganRules[MullRuleKeyHold]); if (cards[i].holdByRule < 0) //if the right card is busy, check other cards { for (int j = i; j < cards.Count; j++) { if (CardIDEntityC.entitiy == cards[j].entitiy) { continue; } if (MulliganRulesManual.ContainsKey(cards[j].id)) { if (cards[j].holdByRule < 0) { continue; } foundFreeCard = true; cards[j].holdByRule = 2; cards[j].holdReason = joinSomeTxt("hold by rule: ", MullRuleKeyHold, ":", MulliganRules[MullRuleKeyHold]); break; } } if (!foundFreeCard) { foundFreeCard = true; cards[i].holdByRule = 2; cards[i].holdReason = joinSomeTxt("hold by rule: ", MullRuleKeyHold, ":", MulliganRules[MullRuleKeyHold]); break; } } else { foundFreeCard = true; cards[i].holdByRule = 2; cards[i].holdReason = joinSomeTxt("hold by rule: ", MullRuleKeyHold, ":", MulliganRules[MullRuleKeyHold]); } if (allowedQuantity == 1) { foreach (CardIDEntity tmp in cards) { if (tmp.entitiy == CardIDEntityC.entitiy) { continue; } if (tmp.id == CardIDEntityC.id) { tmp.holdByRule = -2; tmp.holdReason = joinSomeTxt("discard by rule: ", MullRuleKeyHold, ":", MulliganRules[MullRuleKeyHold]); } } } } } } } else if (useHold && CardIDEntityC.holdByRule != -2) { if (CardIDEntityC.hold == 0) { CardIDEntityC.hold = 2; CardIDEntityC.holdReason = joinSomeTxt("hold by rule: ", MullRuleKeyHold, ":", MulliganRules[MullRuleKeyHold]); if (allowedQuantity == 1) { CardIDEntityC.hold = 1; foreach (CardIDEntity tmp in cards) { if (tmp.entitiy == CardIDEntityC.entitiy) { continue; } if (tmp.id == CardIDEntityC.id) { tmp.hold = -2; tmp.holdReason = joinSomeTxt("discard Second card by rule: ", MullRuleKeyHold, ":", MulliganRules[MullRuleKeyHold]); } } } } } } if (cards.Count == 5) { cards.Remove(Coin); } foreach (CardIDEntity c in cards) { if (c.holdByRule == 0) { if (c.hold == 0) { c.holdByRule = c.holdByManarule; } else { c.holdByRule = c.hold; } } } for (var i = 0; i < mulliganData.Cards.Count; i++) { mulliganData.Mulligans[i] = (cards[i].holdByRule > 0) ? false : true; Log.InfoFormat("[Mulligan] {0} {1}.", mulliganData.Cards[i].Entity.Name, cards[i].holdReason); } return; }
/// <summary> /// This task implements custom mulligan choosing logic for the bot. /// The user is expected to set the Mulligans list elements to true/false /// to signal to the bot which cards should/shouldn't be mulliganed. /// This task should also implement humanization factors, such as hovering /// over cards, or delaying randomly before returning, as the mulligan /// process takes place as soon as the task completes. /// </summary> /// <param name="mulliganData">An object that contains relevant data for the mulligan process.</param> /// <returns></returns> public async Task MulliganLogic(MulliganData mulliganData) { Log.InfoFormat("[Mulligan] {0} vs {1}.", mulliganData.UserClass, mulliganData.OpponentClass); var count = mulliganData.Cards.Count; /*string ownName = mulliganData.UserClass.ToString(); string enemName = mulliganData.OpponentClass.ToString(); if (Mulligan.Instance.hasmulliganrules(ownName, enemName)) { bool hascoin = false; List<Mulligan.CardIDEntity> celist = new List<Mulligan.CardIDEntity>(); for (var i = 0; i < mulliganData.Cards.Count; i++) { string id = mulliganData.Cards[i].Entity.Id if ( id != "GAME_005")// dont mulligan coin { celist.Add(new Mulligan.CardIDEntity(id, i)); } else { hascoin = true; } } if (celist.Count >= 4) hascoin = true; List<int> mullientitys = Mulligan.Instance.whatShouldIMulligan(celist, ownName, enemName, hascoin); for (var i = 0; i < mulliganData.Cards.Count; i++) { if (mullientitys.Contains(i)) { Helpfunctions.Instance.ErrorLog("Rejecting Mulligan Card " + mulliganData.Cards[i].Entity.Id + " because of your rules"); } } }*/ if (Mulligan.Instance.mulliganRulesLoaded) { Mulligan.Instance.getHoldList(mulliganData); } else { for (var i = 0; i < count; i++) { var card = mulliganData.Cards[i]; try { foreach (var tuple in _mulliganRules) { if (GetCondition(tuple.Item1, new List<RegisterScriptVariableDelegate> { scope => scope.SetVariable("mulliganData", mulliganData) })) { if (GetCondition(tuple.Item2, new List<RegisterScriptVariableDelegate> { scope => scope.SetVariable("mulliganData", mulliganData), scope => scope.SetVariable("card", card) })) { mulliganData.Mulligans[i] = true; Log.InfoFormat( "[Mulligan] {0} should be mulliganed because it matches the user's mulligan rule: [{1}] ({2}).", card.Entity.Id, tuple.Item2, tuple.Item1); } } else { Log.InfoFormat( "[Mulligan] The mulligan execution check [{0}] is false, so the mulligan criteria [{1}] will not be evaluated.", tuple.Item1, tuple.Item2); } } } catch (Exception ex) { Log.ErrorFormat("[Mulligan] An exception occurred: {0}.", ex); BotManager.Stop(); return; } } } var thinkList = new List<KeyValuePair<int, int>>(); for (var i = 0; i < count; i++) { thinkList.Add(new KeyValuePair<int, int>(i%count, RandomMulliganThinkTime())); } thinkList.Shuffle(); foreach (var entry in thinkList) { var card = mulliganData.Cards[entry.Key]; Log.InfoFormat("[Mulligan] Now thinking about mulliganing {0} for {1} ms.", card.Entity.Id, entry.Value); // Instant think time, skip the card. if (entry.Value == 0) continue; Client.MouseOver(card.InteractPoint); await Coroutine.Sleep(entry.Value); } }
public bool getHoldList(MulliganData mulliganData, Behavior behave) { this.cards.Clear(); this.readRules(behave.BehaviorName()); if (!this.mulliganRulesLoaded) { return(false); } if (!(mulliganData.Cards.Count == 3 || mulliganData.Cards.Count == 4)) { Helpfunctions.Instance.ErrorLog( $"[Mulligan] Mulligan is not used, since it got number of cards: {this.cards.Count}"); return(false); } Log.InfoFormat("[开局留牌] 应用这个 {0} 规则:", behave.BehaviorName()); for (var i = 0; i < mulliganData.Cards.Count; i++) { this.cards.Add(new CardIDEntity(mulliganData.Cards[i].Entity.Id, i)); } var ownHeroClass = mulliganData.UserClass.Convert(); var enemyHeroClass = mulliganData.OpponentClass.Convert(); var manaRule = 4; var MullRuleKey = this.getMullRuleKey(SimCard.None, ownHeroClass, enemyHeroClass, 1); if (this.MulliganRules.ContainsKey(MullRuleKey)) { var temp = this.MulliganRules[MullRuleKey].Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries); manaRule = Convert.ToInt32(temp[2]); } else { MullRuleKey = this.getMullRuleKey(SimCard.None, ownHeroClass, CardClass.INVALID, 1); if (this.MulliganRules.ContainsKey(MullRuleKey)) { var temp = this.MulliganRules[MullRuleKey].Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries); manaRule = Convert.ToInt32(temp[2]); } } var Coin = new CardIDEntity("GAME_005", -888); if (this.cards.Count == 4) { this.cards.Add(Coin); //we have a coin } foreach (var CardIDEntityC in this.cards) { var c = CardIDEntityC.id; if (CardIDEntityC.hold == 0 && CardIDEntityC.holdByRule == 0) { if (c.Cost < manaRule) { CardIDEntityC.holdByManarule = 2; CardIDEntityC.holdReason = this.joinSomeTxt("保留这些卡牌因为法力值消耗:", c.Cost.ToString(), " 小于预定值:", manaRule.ToString()); } else { CardIDEntityC.holdByManarule = -2; CardIDEntityC.holdReason = this.joinSomeTxt("弃掉这些卡牌因为法力值消耗:", c.Cost.ToString(), " 没有小于预定值:", manaRule.ToString()); } } var allowedQuantitySimple = 0; var allowedQuantityExtra = 0; var hasRuleClassSimple = false; var hasRule = false; var MullRuleKeySimple = this.getMullRuleKey(c, ownHeroClass, enemyHeroClass); //Simple key for Class enemy if (this.MulliganRules.ContainsKey(MullRuleKeySimple)) { hasRule = true; hasRuleClassSimple = true; } else { MullRuleKeySimple = this.getMullRuleKey(c, ownHeroClass); //Simple key for ALL enemy if (this.MulliganRules.ContainsKey(MullRuleKeySimple)) { hasRule = true; } } if (hasRule) { var val = this.MulliganRules[MullRuleKeySimple].Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries); allowedQuantitySimple = (val[1] == "2" ? 2 : 1) * (val[0] == "Hold" ? 1 : -1); } hasRule = false; var MullRuleKeyExtra = this.getMullRuleKey(c, ownHeroClass, enemyHeroClass, 1); //Extra key for Class enemy if (this.MulliganRules.ContainsKey(MullRuleKeyExtra)) { hasRule = true; } else if (!hasRuleClassSimple) { MullRuleKeyExtra = this.getMullRuleKey(c, ownHeroClass, CardClass.INVALID, 1); //Extra key for ALL enemy if (this.MulliganRules.ContainsKey(MullRuleKeyExtra)) { hasRule = true; } } if (hasRule) { var val = this.MulliganRules[MullRuleKeyExtra].Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries); allowedQuantityExtra = (val[1] == "2" ? 2 : 1) * (val[0] == "Hold" ? 1 : -1); } //superimpose Class rules to All rules var useHold = false; var useDiscard = false; var useHoldRule = false; var useDiscardRule = false; if (allowedQuantitySimple != 0 && allowedQuantitySimple != allowedQuantityExtra) { if (allowedQuantitySimple > 0) { useHold = true; } else { useDiscard = true; } } if (allowedQuantityExtra != 0) { if (allowedQuantityExtra < 0) { useDiscardRule = true; } else { useHoldRule = true; } } //apply the rules var MullRuleValueExtra = new string[3]; if (allowedQuantityExtra != 0) { MullRuleValueExtra = this.MulliganRules[MullRuleKeyExtra].Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries); } if (useDiscardRule) { if (MullRuleValueExtra[2] != "/") { var addedCards = MullRuleValueExtra[2].Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries); this.MulliganRulesManual.Clear(); foreach (var s in addedCards) { this.MulliganRulesManual.Add(s, ""); } foreach (var tmp in this.cards) { if (CardIDEntityC.entitiy == tmp.entitiy) { continue; } if (this.MulliganRulesManual.ContainsKey(tmp.id)) { CardIDEntityC.holdByRule = -2; CardIDEntityC.holdReason = this.joinSomeTxt("符合规则而弃掉: ", this.getClearRule(MullRuleKeyExtra)); break; } } } } else if (useDiscard) { CardIDEntityC.hold = -2; CardIDEntityC.holdReason = this.joinSomeTxt("符合规则而弃掉: ", this.getClearRule(MullRuleKeySimple)); } if (useHoldRule) { if (CardIDEntityC.holdByRule == 0) { var addedCards = MullRuleValueExtra[2].Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries); this.MulliganRulesManual.Clear(); foreach (var s in addedCards) { this.MulliganRulesManual.Add(s, ""); } var foundFreeCard = false; for (var i = 0; i < this.cards.Count; i++) { if (CardIDEntityC.entitiy == this.cards[i].entitiy) { continue; } if (this.MulliganRulesManual.ContainsKey(this.cards[i].id)) { CardIDEntityC.holdByRule = 2; CardIDEntityC.holdReason = this.joinSomeTxt("符合规则而保留: ", this.getClearRule(MullRuleKeyExtra)); if (this.cards[i].holdByRule < 0) { for (var j = i; j < this.cards.Count; j++) { if (CardIDEntityC.entitiy == this.cards[j].entitiy) { continue; } if (this.MulliganRulesManual.ContainsKey(this.cards[j].id)) { if (this.cards[j].holdByRule < 0) { continue; } foundFreeCard = true; this.cards[j].holdByRule = 2; this.cards[j].holdReason = this.joinSomeTxt("符合规则而保留: ", this.getClearRule(MullRuleKeyExtra)); break; } } if (!foundFreeCard) { foundFreeCard = true; this.cards[i].holdByRule = 2; this.cards[i].holdReason = this.joinSomeTxt("符合规则而保留: ", this.getClearRule(MullRuleKeyExtra)); break; } } else { foundFreeCard = true; this.cards[i].holdByRule = 2; this.cards[i].holdReason = this.joinSomeTxt("符合规则而保留: ", this.getClearRule(MullRuleKeyExtra)); } if (allowedQuantityExtra == 1) { foreach (var tmp in this.cards) { if (tmp.entitiy == CardIDEntityC.entitiy) { continue; } if (tmp.id == CardIDEntityC.id) { tmp.holdByRule = -2; tmp.holdReason = this.joinSomeTxt("符合规则而弃掉: ", this.getClearRule(MullRuleKeyExtra)); } } } } } } } if (useHold && CardIDEntityC.holdByRule != -2) { if (CardIDEntityC.hold == 0) { CardIDEntityC.hold = 2; CardIDEntityC.holdReason = this.joinSomeTxt("符合规则而保留: ", this.getClearRule(MullRuleKeySimple)); if (allowedQuantitySimple == 1) { CardIDEntityC.hold = 1; foreach (var tmp in this.cards) { if (tmp.entitiy == CardIDEntityC.entitiy) { continue; } if (tmp.id == CardIDEntityC.id) { tmp.hold = -2; tmp.holdReason = this.joinSomeTxt("discard Second card by rule: ", this.getClearRule(MullRuleKeySimple)); } } } } } } if (this.cards.Count == 5) { this.cards.Remove(Coin); } foreach (var c in this.cards) { if (c.holdByRule == 0) { if (c.hold == 0) { c.holdByRule = c.holdByManarule; } else { c.holdByRule = c.hold; } } } for (var i = 0; i < mulliganData.Cards.Count; i++) { mulliganData.Mulligans[i] = this.cards[i].holdByRule > 0 ? false : true; Log.InfoFormat("[开局留牌] {0} {1}.", mulliganData.Cards[i].Entity.Name, this.cards[i].holdReason); } return(true); }