ScienceScore FindBestScienceWildcard(int nWildScienceSymbols, ScienceSymbols copiedSymbols, int groupMultiplier) { ScienceScore tmpResult = new ScienceScore(); ScienceScore bestResult = tmpResult; int maxScienceScore = 0; // this player's science cards: int nCompass = playedStructure.Where(x => x.effect is ScienceEffect && ((ScienceEffect)x.effect).symbol == ScienceEffect.Symbol.Compass).Count(); int nGear = playedStructure.Where(x => x.effect is ScienceEffect && ((ScienceEffect)x.effect).symbol == ScienceEffect.Symbol.Gear).Count(); int nTablet = playedStructure.Where(x => x.effect is ScienceEffect && ((ScienceEffect)x.effect).symbol == ScienceEffect.Symbol.Tablet).Count(); // now add wild cards and symbols copied from neighbors by mask effect cards. // if wild cards are in play, we choose the best combination of wilds to get the maximum overall // score, with Aristotle's bonus factored in. In some cases, Aristotle's effect will mean it's // more beneficial to use the wild card(s) to make more groups rather than like symbols. // For example: 1/2/5+1 wild. Without Aristotle, the maximum score is 1/2/6 = 48. // But with Aristotle's bonus, it's better to use the wild card to make a 2nd set instead // 1/2/6 = 51 with Aristotle but if you use the wild to make 2/2/5, that group is worth 53 points. for (int nWildTablets = 0; nWildTablets <= Math.Min(nWildScienceSymbols, copiedSymbols.nTablet); ++nWildTablets) { for (int nWildCompasses = 0; nWildCompasses <= Math.Min(nWildScienceSymbols - nWildTablets, copiedSymbols.nCompass); ++nWildCompasses) { int mWildGears = Math.Min(nWildScienceSymbols - (nWildTablets + nWildCompasses), copiedSymbols.nGear); int score = CalculateScienceGroupScore(nTablet + nWildTablets, nCompass + nWildCompasses, nGear + mWildGears, groupMultiplier, out tmpResult); if (score > maxScienceScore) { maxScienceScore = score; bestResult = tmpResult; } } } return bestResult; }
int CalculateScienceGroupScore(int nCompass, int nGear, int nTablet, int groupMultiplier, out ScienceScore ss) { ss.sym.nCompass = nCompass; ss.sym.nGear = nGear; ss.sym.nTablet = nTablet; ss.groupMultiplier = groupMultiplier; // Compute output values ss.baseScore = ss.sym.nCompass * ss.sym.nCompass + ss.sym.nGear * ss.sym.nGear + ss.sym.nTablet * ss.sym.nTablet; ss.nGroups = Math.Min(Math.Min(ss.sym.nCompass, ss.sym.nGear), ss.sym.nTablet); ss.TotalPoints = ss.baseScore + ss.nGroups * ss.groupMultiplier; return ss.TotalPoints; }