Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate Guava Predicates and Functions to Java implementations #6047

Open
wants to merge 81 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
b46c1de
Guava migration - Preliminary
Sep 2, 2024
bb520b1
Guava migration - Create migration scaffold
Sep 2, 2024
fb16a46
Guava migration - Remove `Functions` dependency
Sep 2, 2024
4d62928
Guava migration - Migrate static libraries
Sep 2, 2024
9765279
Guava migration - Migrate Predicates
Sep 2, 2024
8702e29
Guava migration - Migrate Functions
Sep 2, 2024
ecf25a8
Guava migration - Migrate Optionals
Sep 2, 2024
6a87768
Guava migration - Migrate Suppliers
Sep 2, 2024
67f22c6
Guava migration - Migrate `Lists.transform`
Sep 2, 2024
a070fee
Guava migration - Remove forwarding overloads
Sep 2, 2024
055dff7
Guava migration - Inline Predicate varargs methods
Sep 2, 2024
16c0fa1
Guava migration - Fix lingering build errors
Sep 2, 2024
77ba9f1
Guava migration - Inline `Predicates.alwaysTrue`
Sep 3, 2024
ef011d3
Guava migration - Inline `Predicates.instanceOf`
Sep 3, 2024
4eb8fdd
Guava migration - Inline `Predicates.in`
Sep 3, 2024
6b96bca
Guava migration - Inline `Predicates.equalTo`
Sep 3, 2024
22e7465
Guava migration - Swap in `Predicate.isEqual`
Sep 3, 2024
78bc9fd
Guava migration - Inline `Predicates.not`
Sep 3, 2024
b37f872
Guava migration - Inline `Predicates.and`
Sep 4, 2024
2d233f8
Guava migration - Inline `Predicates.or`
Sep 4, 2024
0bf04c2
Guava migration - Add common helper predicates
Sep 6, 2024
85f80bb
Guava migration - Explode Predicate "Presets" subclasses
Sep 6, 2024
734bcec
Guava migration - Helper method for composing CardRules into PaperCards
Sep 6, 2024
6e3726e
Guava migration - Remove unused imports
Sep 6, 2024
4c8a94b
Guava migration - Inline `Predicates.compose`
Sep 6, 2024
efe55ef
Guava migration - Inline `Iterables.isEmpty` (Collection overload)
Sep 6, 2024
c1de0de
Guava migration - Inline `Iterables.removeAll` (Collection overload)
Sep 6, 2024
d9c54aa
Guava migration - Inline `Iterables.addAll` (Collection overload)
Sep 7, 2024
79a640c
Guava migration - Cleanup imports
Sep 7, 2024
8489866
Guava migration - Inline `Iterables.contains` (Collection overload)
Sep 7, 2024
36cff7e
Guava migration - Inline `Iterables.removeIf` (Collection overload)
Sep 7, 2024
dfac93a
Guava migration - Inline `Iterables.find` (Collection overload)
Sep 7, 2024
4716415
Guava migration - Add helper methods for FCollectionView `anyMatch` a…
Sep 8, 2024
b4015af
Guava migration - Inline `Iterables.any` and `Iterables.all` (FCollec…
Sep 8, 2024
7e3bb81
Guava migration - Inline `Iterables.any` (Collection overload)
Sep 8, 2024
cf68a75
Guava migration - Inline `Iterables.all` (Collection overload)
Sep 8, 2024
76aa196
Guava migration - Replace select usages of `Iterables.filter`
Sep 15, 2024
1644e74
Guava migration - Replace select usages of `Iterables.transform`
Sep 15, 2024
8189f13
Merge branch 'master' into code-cleanup
Sep 15, 2024
ae25137
Guava migration - Cleanup
Sep 15, 2024
7ab333a
Guava migration - ItemPool collector
Sep 16, 2024
c913340
Guava migration - Refactor edition type checks
Sep 19, 2024
c2f72bb
Guava migration - Stream support for FCollectionView
Sep 22, 2024
05d58c2
Guava migration - Add `StreamUtils.random` collectors
Sep 22, 2024
e739dad
Guava migration - Slim down quest reward logic
Sep 22, 2024
cbcfa8f
Guava migration - Replace select usages of Aggregates methods
Sep 22, 2024
d173c22
Fixed some predicate logic issues.
Sep 22, 2024
cb4c64c
Guava migration - Added PaperCard predicates for commonly forwarded C…
Sep 22, 2024
1af22ff
Guava migration - Remove CollectionSuppliers
Sep 22, 2024
a57bab1
Guava migration - Remove single use Predicate implementations
Sep 24, 2024
52112e6
Guava migration - Slight cleanup
Sep 25, 2024
d01c4e0
Guava migration - Remove unused imports
Sep 25, 2024
1395baa
Guava migration - Fix build error
Sep 25, 2024
f636910
Guava migration - Rename `StreamUtils` -> `StreamUtil` for consistency
Sep 25, 2024
0278f58
Guava migration - Create `IterableUtil` to house iterable helper meth…
Sep 25, 2024
6a04fcd
Guava migration - Remove migration scaffold
Sep 26, 2024
871947a
Guava migration - Optimize imports
Sep 26, 2024
b359812
Merge branch 'master' into code-cleanup
Sep 26, 2024
474be7b
Fix ConcurrentModificationException
Sep 26, 2024
2e769ac
Bug fix in RandomReservoir accumulator
Sep 29, 2024
c43015f
Merge branch 'master' into code-cleanup
Sep 29, 2024
31547c6
Merge branch 'master' into code-cleanup
Oct 15, 2024
6b93e62
Merge branch 'master' into code-cleanup
Oct 15, 2024
2d6952f
Swap out lingering use of `Iterables.any`
Oct 15, 2024
9be2c3d
Merge branch 'master' into code-cleanup
Oct 17, 2024
67cedad
Merge branch 'master' into code-cleanup
Oct 17, 2024
64609b0
Add some helper methods to StreamUtil;
Oct 20, 2024
c5be6f1
Merge branch 'master' into code-cleanup
Oct 20, 2024
e52a7b1
Remove unused imports
Oct 20, 2024
7a34369
Merge branch 'master' into code-cleanup
Hanmac Oct 21, 2024
d6c8e9a
Merge remote-tracking branch 'origin/master' into code-cleanup
Nov 8, 2024
903d636
Merge remote-tracking branch 'origin/code-cleanup' into code-cleanup
Nov 8, 2024
c9ba926
Guava migration - Replace `.negate()` with `Predicate.not(...)` in co…
Nov 9, 2024
7bb8ccd
Remove unused imports
Nov 9, 2024
4bbc165
Guava migration - Use `.toList()`
Nov 9, 2024
6b7ac1e
Guava migration - Use `Arrays.stream()`
Nov 9, 2024
c6ad122
Guava migration - Swap in `StreamUtil.stream`
Nov 9, 2024
2b5fc37
Remove unused imports
Nov 9, 2024
d81c5a4
Revert `.toList()` for Android compatibility
Nov 13, 2024
e879abc
Merge remote-tracking branch 'origin/master' into code-cleanup
Nov 13, 2024
c347ff5
Merge remote-tracking branch 'origin/master' into code-cleanup
Nov 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ public class RewardEdit extends FormPanel {
TextListEdit colors =new TextListEdit(new String[] { "White", "Blue", "Black", "Red", "Green" });
TextListEdit rarity =new TextListEdit(new String[] { "Basic Land", "Common", "Uncommon", "Rare", "Mythic Rare" });
TextListEdit subTypes =new TextListEdit();
TextListEdit cardTypes =new TextListEdit(Arrays.asList(CardType.CoreType.values()).stream().map(CardType.CoreType::toString).toArray(String[]::new));
TextListEdit superTypes =new TextListEdit(Arrays.asList(CardType.Supertype.values()).stream().map(CardType.Supertype::toString).toArray(String[]::new));
TextListEdit cardTypes =new TextListEdit(Arrays.stream(CardType.CoreType.values()).map(CardType.CoreType::toString).toArray(String[]::new));
TextListEdit superTypes =new TextListEdit(Arrays.stream(CardType.Supertype.values()).map(CardType.Supertype::toString).toArray(String[]::new));
TextListEdit manaCosts =new TextListEdit();
TextListEdit keyWords =new TextListEdit(Arrays.asList(Keyword.values()).stream().map(Keyword::toString).toArray(String[]::new));
TextListEdit keyWords =new TextListEdit(Arrays.stream(Keyword.values()).map(Keyword::toString).toArray(String[]::new));
JComboBox colorType =new JComboBox(new String[] { "Any", "Colorless", "MultiColor", "MonoColor"});
JTextField cardText =new JTextField();
private boolean updating=false;
Expand Down
27 changes: 13 additions & 14 deletions forge-ai/src/main/java/forge/ai/AiAttackController.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
*/
package forge.ai;

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.ai.ability.AnimateAi;
Expand All @@ -42,14 +40,13 @@
import forge.game.trigger.Trigger;
import forge.game.trigger.TriggerType;
import forge.game.zone.ZoneType;
import forge.util.Aggregates;
import forge.util.Expressions;
import forge.util.MyRandom;
import forge.util.*;
import forge.util.collect.FCollection;
import forge.util.collect.FCollectionView;
import org.apache.commons.lang3.tuple.Pair;

import java.util.*;
import java.util.function.Predicate;


/**
Expand Down Expand Up @@ -129,7 +126,7 @@ public static List<Card> getOpponentCreatures(final Player defender) {

CardCollection tappedDefenders = new CardCollection();
for (Card c : CardLists.filter(defender.getCardsIn(ZoneType.Battlefield), canAnimate)) {
for (SpellAbility sa : Iterables.filter(c.getSpellAbilities(), SpellAbilityPredicates.isApi(ApiType.Animate))) {
for (SpellAbility sa : IterableUtil.filter(c.getSpellAbilities(), SpellAbilityPredicates.isApi(ApiType.Animate))) {
if (sa.usesTargeting() || !sa.getParamOrDefault("Defined", "Self").equals("Self")) {
continue;
}
Expand All @@ -153,7 +150,7 @@ public static List<Card> getOpponentCreatures(final Player defender) {
defenders.removeAll(tappedDefenders);

// Transform (e.g. Incubator tokens)
for (SpellAbility sa : Iterables.filter(c.getSpellAbilities(), SpellAbilityPredicates.isApi(ApiType.SetState))) {
for (SpellAbility sa : IterableUtil.filter(c.getSpellAbilities(), SpellAbilityPredicates.isApi(ApiType.SetState))) {
Card transformedCopy = ComputerUtilCombat.canTransform(c);
if (transformedCopy.isCreature()) {
int saCMC = sa.getPayCosts() != null && sa.getPayCosts().hasManaCost() ?
Expand Down Expand Up @@ -615,9 +612,9 @@ private boolean doAssault() {
// TODO: the AI should ideally predict how many times it can activate
// for now, unless the opponent is tapped out, break at this point
// and do not predict the blocker limit (which is safer)
if (Iterables.any(defendingOpponent.getLandsInPlay(), CardPredicates.Presets.UNTAPPED)) {
if (defendingOpponent.getLandsInPlay().anyMatch(CardPredicates.UNTAPPED)) {
maxBlockersAfterCrew += CardLists.count(CardLists.getNotType(defendingOpponent.getCardsIn(ZoneType.Battlefield), "Creature"),
Predicates.and(CardPredicates.isType("Vehicle"), CardPredicates.Presets.UNTAPPED));
CardPredicates.isType("Vehicle").and(CardPredicates.UNTAPPED));
}
}

Expand Down Expand Up @@ -1317,7 +1314,7 @@ && isEffectiveAttacker(ai, attacker, combat, defender)) {
if (attackersLeft.isEmpty() || possibleDefenders.isEmpty()) {
break;
}
CardCollection pwDefending = new CardCollection(Iterables.filter(possibleDefenders, Card.class));
CardCollection pwDefending = new CardCollection(IterableUtil.filter(possibleDefenders, Card.class));
if (pwDefending.isEmpty()) {
// TODO for now only looks at same player as we'd have to check the others from start too
//defender = new PlayerCollection(Iterables.filter(possibleDefenders, Player.class)).min(PlayerPredicates.compareByLife());
Expand Down Expand Up @@ -1367,9 +1364,11 @@ private void calculate(final List<Card> defenders, final Combat combat) {
canTrampleOverDefenders = attacker.hasKeyword(Keyword.TRAMPLE) && attacker.getNetCombatDamage() > Aggregates.sum(validBlockers, Card::getNetToughness);

// used to check that CanKillAllDangerous check makes sense in context where creatures with dangerous abilities are present
dangerousBlockersPresent = Iterables.any(validBlockers, Predicates.or(
CardPredicates.hasKeyword(Keyword.WITHER), CardPredicates.hasKeyword(Keyword.INFECT),
CardPredicates.hasKeyword(Keyword.LIFELINK)));
dangerousBlockersPresent = validBlockers.anyMatch(
CardPredicates.hasKeyword(Keyword.WITHER)
.or(CardPredicates.hasKeyword(Keyword.INFECT))
.or(CardPredicates.hasKeyword(Keyword.LIFELINK))
);

// total power of the defending creatures, used in predicting whether a gang block can kill the attacker
defPower = CardLists.getTotalPower(validBlockers, true, false);
Expand Down Expand Up @@ -1590,7 +1589,7 @@ public static List<Card> exertAttackers(final List<Card> attackers, int aggressi
if (validTargets.isEmpty()) {
missTarget = true;
break;
} else if (sa.isCurse() && !Iterables.any(validTargets,
} else if (sa.isCurse() && validTargets.stream().noneMatch(
CardPredicates.isControlledByAnyOf(c.getController().getOpponents()))) {
// e.g. Ahn-Crop Crasher - the effect is only good when aimed at opponent's creatures
missTarget = true;
Expand Down
18 changes: 8 additions & 10 deletions forge-ai/src/main/java/forge/ai/AiBlockController.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
package forge.ai;

import java.util.*;

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import java.util.function.Predicate;

import forge.card.CardStateName;
import forge.game.GameEntity;
Expand Down Expand Up @@ -327,7 +325,7 @@ private void makeGoodBlocks(final Combat combat) {
}

private Predicate<Card> rampagesOrNeedsManyToBlock(final Combat combat) {
return Predicates.or(CardPredicates.hasKeyword(Keyword.RAMPAGE), input -> {
return CardPredicates.hasKeyword(Keyword.RAMPAGE).or(input -> {
// select creature that has a max blocker
return StaticAbilityCantAttackBlock.getMinMaxBlocker(input, combat.getDefenderPlayerByAttacker(input)).getRight() < Integer.MAX_VALUE;
});
Expand Down Expand Up @@ -368,7 +366,7 @@ private Predicate<Card> changesPTWhenBlocked(final boolean onlyForDefVsTrample)
* @param combat a {@link forge.game.combat.Combat} object.
*/
private void makeGangBlocks(final Combat combat) {
List<Card> currentAttackers = CardLists.filter(attackersLeft, Predicates.not(rampagesOrNeedsManyToBlock(combat)));
List<Card> currentAttackers = CardLists.filter(attackersLeft, rampagesOrNeedsManyToBlock(combat).negate());
List<Card> blockers;

// Try to block an attacker without first strike with a gang of first strikers
Expand Down Expand Up @@ -740,11 +738,11 @@ private void reinforceBlockersAgainstTrample(final Combat combat) {
List<Card> chumpBlockers;

List<Card> tramplingAttackers = CardLists.getKeyword(attackers, Keyword.TRAMPLE);
tramplingAttackers = CardLists.filter(tramplingAttackers, Predicates.not(rampagesOrNeedsManyToBlock(combat)));
tramplingAttackers = CardLists.filter(tramplingAttackers, rampagesOrNeedsManyToBlock(combat).negate());

// TODO - Instead of filtering out rampage-like and similar triggers, make the AI properly count P/T and
// reinforce when actually possible without losing material.
tramplingAttackers = CardLists.filter(tramplingAttackers, Predicates.not(changesPTWhenBlocked(true)));
tramplingAttackers = CardLists.filter(tramplingAttackers, changesPTWhenBlocked(true).negate());

for (final Card attacker : tramplingAttackers) {
if (CombatUtil.getMinNumBlockersForAttacker(attacker, combat.getDefenderPlayerByAttacker(attacker)) > combat.getBlockers(attacker).size()) {
Expand Down Expand Up @@ -795,11 +793,11 @@ private void reinforceBlockersAgainstTrample(final Combat combat) {
private void reinforceBlockersToKill(final Combat combat) {
List<Card> safeBlockers;
List<Card> blockers;
List<Card> targetAttackers = CardLists.filter(blockedButUnkilled, Predicates.not(rampagesOrNeedsManyToBlock(combat)));
List<Card> targetAttackers = CardLists.filter(blockedButUnkilled, rampagesOrNeedsManyToBlock(combat).negate());

// TODO - Instead of filtering out rampage-like and similar triggers, make the AI properly count P/T and
// reinforce when actually possible without losing material.
targetAttackers = CardLists.filter(targetAttackers, Predicates.not(changesPTWhenBlocked(false)));
targetAttackers = CardLists.filter(targetAttackers, changesPTWhenBlocked(false).negate());

for (final Card attacker : targetAttackers) {
blockers = getPossibleBlockers(combat, attacker, blockersLeft, false);
Expand Down Expand Up @@ -1345,7 +1343,7 @@ private boolean wouldLikeToRandomlyTrade(Card attacker, Card blocker, Combat com
boolean creatureParityOrAllowedDiff = aiCreatureCount
+ (randomTradeIfBehindOnBoard ? maxCreatDiff : 0) >= oppCreatureCount;
boolean wantToTradeWithCreatInHand = !checkingOther && randomTradeIfCreatInHand
&& ai.getZone(ZoneType.Hand).contains(CardPredicates.Presets.CREATURES)
&& ai.getZone(ZoneType.Hand).contains(CardPredicates.CREATURES)
&& aiCreatureCount + maxCreatDiffWithRepl >= oppCreatureCount;
boolean wantToSavePlaneswalker = MyRandom.percentTrue(chanceToSavePW)
&& combat.getDefenderByAttacker(attacker) instanceof Card
Expand Down
6 changes: 3 additions & 3 deletions forge-ai/src/main/java/forge/ai/AiCardMemory.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@

package forge.ai;

import java.util.HashSet;
import java.util.Set;

import forge.game.card.Card;
import forge.game.player.Player;

import java.util.HashSet;
import java.util.Set;

/**
* <p>
* AiCardMemory class.
Expand Down
Loading
Loading