mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
Improve AI logic for cavern of souls. (#1787)
* Improve AI logic for cavern of souls. Improve AI logic for cavern of souls. - Don't count token creature types when looking for most prominent creature type, since cavern of souls doesn't help with them. - Weigh cards in hand and commanders double, as they are more likely to be cast. I tested with a Tiny Leaders deck running Geist of Saint Traft that didn't have any creature type synergy and confirmed that the changes make the AI choose Spirit for Geist, rather than Human as before. * Apply this to a few more cards. * Remove a print statement. * Address review comments.
This commit is contained in:
@@ -2378,8 +2378,9 @@ public class ComputerUtil {
|
||||
chosen = ComputerUtilCard.getMostProminentType(list, valid);
|
||||
}
|
||||
}
|
||||
else if (logic.equals("MostProminentInComputerDeck")) {
|
||||
chosen = ComputerUtilCard.getMostProminentType(ai.getAllCards(), valid);
|
||||
else if (logic.startsWith("MostProminentInComputerDeck")) {
|
||||
boolean includeTokens = !logic.endsWith("NonToken");
|
||||
chosen = ComputerUtilCard.getMostProminentType(ai.getAllCards(), valid, includeTokens);
|
||||
}
|
||||
else if (logic.equals("MostProminentInComputerGraveyard")) {
|
||||
chosen = ComputerUtilCard.getMostProminentType(ai.getCardsIn(ZoneType.Graveyard), valid);
|
||||
|
||||
@@ -762,30 +762,21 @@ public class ComputerUtilCard {
|
||||
return maxName;
|
||||
}
|
||||
|
||||
public static String getMostProminentBasicLandType(final CardCollectionView list) {
|
||||
return getMostProminentType(list, CardType.getBasicTypes());
|
||||
public static String getMostProminentType(final CardCollectionView list, final Collection<String> valid) {
|
||||
return getMostProminentType(list, valid, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getMostProminentCreatureType.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public static String getMostProminentCreatureType(final CardCollectionView list) {
|
||||
return getMostProminentType(list, CardType.getAllCreatureTypes());
|
||||
}
|
||||
public static String getMostProminentType(final CardCollectionView list, final Collection<String> valid) {
|
||||
public static String getMostProminentType(final CardCollectionView list, final Collection<String> valid, boolean includeTokens) {
|
||||
if (list.size() == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
final Map<String, Integer> typesInDeck = Maps.newHashMap();
|
||||
|
||||
// TODO JAVA 8 use getOrDefault
|
||||
for (final Card c : list) {
|
||||
if (!includeTokens && c.isToken()) {
|
||||
continue;
|
||||
}
|
||||
// Changeling are all creature types, they are not interesting for
|
||||
// counting creature types
|
||||
if (c.hasStartOfKeyword(Keyword.CHANGELING.toString())) {
|
||||
@@ -803,58 +794,55 @@ public class ComputerUtilCard {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Cards in hand and commanders are worth double, as they are more likely to be played.
|
||||
int weight = 1;
|
||||
if (c.isInZone(ZoneType.Hand) || c.isRealCommander()) {
|
||||
weight = 2;
|
||||
}
|
||||
|
||||
Set<String> cardCreatureTypes = c.getType().getCreatureTypes();
|
||||
for (String type : cardCreatureTypes) {
|
||||
Integer count = typesInDeck.get(type);
|
||||
if (count == null) {
|
||||
count = 0;
|
||||
}
|
||||
typesInDeck.put(type, count + 1);
|
||||
Integer count = typesInDeck.getOrDefault(type, 0);
|
||||
typesInDeck.put(type, count + weight);
|
||||
}
|
||||
|
||||
//also take into account abilities that generate tokens
|
||||
for (SpellAbility sa : c.getAllSpellAbilities()) {
|
||||
if (sa.getApi() != ApiType.Token) {
|
||||
continue;
|
||||
}
|
||||
if (sa.hasParam("TokenTypes")) {
|
||||
for (String var : sa.getParam("TokenTypes").split(",")) {
|
||||
if (!CardType.isACreatureType(var)) {
|
||||
continue;
|
||||
}
|
||||
Integer count = typesInDeck.get(var);
|
||||
if (count == null) {
|
||||
count = 0;
|
||||
}
|
||||
typesInDeck.put(var, count + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// same for Trigger that does make Tokens
|
||||
for (Trigger t :c .getTriggers()) {
|
||||
SpellAbility sa = t.ensureAbility();
|
||||
if (sa != null) {
|
||||
if (sa.getApi() != ApiType.Token || !sa.hasParam("TokenTypes")) {
|
||||
if (includeTokens) {
|
||||
for (SpellAbility sa : c.getAllSpellAbilities()) {
|
||||
if (sa.getApi() != ApiType.Token) {
|
||||
continue;
|
||||
}
|
||||
for (String var : sa.getParam("TokenTypes").split(",")) {
|
||||
if (!CardType.isACreatureType(var)) {
|
||||
continue;
|
||||
if (sa.hasParam("TokenTypes")) {
|
||||
for (String var : sa.getParam("TokenTypes").split(",")) {
|
||||
if (!CardType.isACreatureType(var)) {
|
||||
continue;
|
||||
}
|
||||
Integer count = typesInDeck.getOrDefault(var, 0);
|
||||
typesInDeck.put(var, count + weight);
|
||||
}
|
||||
Integer count = typesInDeck.get(var);
|
||||
if (count == null) {
|
||||
count = 0;
|
||||
}
|
||||
typesInDeck.put(var, count + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// special rule for Fabricate and Servo
|
||||
if (c.hasStartOfKeyword(Keyword.FABRICATE.toString())) {
|
||||
Integer count = typesInDeck.get("Servo");
|
||||
if (count == null) {
|
||||
count = 0;
|
||||
// same for Trigger that does make Tokens
|
||||
for (Trigger t : c.getTriggers()) {
|
||||
SpellAbility sa = t.ensureAbility();
|
||||
if (sa != null) {
|
||||
if (sa.getApi() != ApiType.Token || !sa.hasParam("TokenTypes")) {
|
||||
continue;
|
||||
}
|
||||
for (String var : sa.getParam("TokenTypes").split(",")) {
|
||||
if (!CardType.isACreatureType(var)) {
|
||||
continue;
|
||||
}
|
||||
Integer count = typesInDeck.getOrDefault(var, 0);
|
||||
typesInDeck.put(var, count + weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
// special rule for Fabricate and Servo
|
||||
if (c.hasStartOfKeyword(Keyword.FABRICATE.toString())) {
|
||||
Integer count = typesInDeck.getOrDefault("Servo", 0);
|
||||
typesInDeck.put("Servo", count + weight);
|
||||
}
|
||||
typesInDeck.put("Servo", count + 1);
|
||||
}
|
||||
} // for
|
||||
|
||||
|
||||
Reference in New Issue
Block a user