Prevent getDefender crash

Optimize combat logic a bit using FCollection
This commit is contained in:
drdev
2014-10-14 02:42:28 +00:00
parent 86e3d5c9f2
commit 96980a9d30
3 changed files with 43 additions and 34 deletions

View File

@@ -2,44 +2,44 @@ package forge.game.combat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.game.GameEntityView; import forge.game.GameEntityView;
import forge.game.card.CardView; import forge.game.card.CardView;
import forge.trackable.TrackableObject; import forge.trackable.TrackableObject;
import forge.trackable.TrackableProperty; import forge.trackable.TrackableProperty;
import forge.util.FCollection;
public class CombatView extends TrackableObject { public class CombatView extends TrackableObject {
public CombatView() { public CombatView() {
super(-1); //ID not needed super(-1); //ID not needed
set(TrackableProperty.AttackersWithDefenders, new HashMap<CardView, GameEntityView>()); set(TrackableProperty.AttackersWithDefenders, new HashMap<CardView, GameEntityView>());
set(TrackableProperty.AttackersWithBlockers, new HashMap<CardView, Iterable<CardView>>()); set(TrackableProperty.AttackersWithBlockers, new HashMap<CardView, FCollection<CardView>>());
set(TrackableProperty.BandsWithDefenders, new HashMap<Iterable<CardView>, GameEntityView>()); set(TrackableProperty.BandsWithDefenders, new HashMap<FCollection<CardView>, GameEntityView>());
set(TrackableProperty.BandsWithBlockers, new HashMap<Iterable<CardView>, Iterable<CardView>>()); set(TrackableProperty.BandsWithBlockers, new HashMap<FCollection<CardView>, FCollection<CardView>>());
set(TrackableProperty.AttackersWithPlannedBlockers, new HashMap<CardView, Iterable<CardView>>()); set(TrackableProperty.AttackersWithPlannedBlockers, new HashMap<CardView, FCollection<CardView>>());
set(TrackableProperty.BandsWithPlannedBlockers, new HashMap<Iterable<CardView>, Iterable<CardView>>()); set(TrackableProperty.BandsWithPlannedBlockers, new HashMap<FCollection<CardView>, FCollection<CardView>>());
} }
private Map<CardView, GameEntityView> getAttackersWithDefenders() { private Map<CardView, GameEntityView> getAttackersWithDefenders() {
return get(TrackableProperty.AttackersWithDefenders); return get(TrackableProperty.AttackersWithDefenders);
} }
private Map<CardView, Iterable<CardView>> getAttackersWithBlockers() { private Map<CardView, FCollection<CardView>> getAttackersWithBlockers() {
return get(TrackableProperty.AttackersWithBlockers); return get(TrackableProperty.AttackersWithBlockers);
} }
private Map<Iterable<CardView>, GameEntityView> getBandsWithDefenders() { private Map<FCollection<CardView>, GameEntityView> getBandsWithDefenders() {
return get(TrackableProperty.BandsWithDefenders); return get(TrackableProperty.BandsWithDefenders);
} }
private Map<Iterable<CardView>, Iterable<CardView>> getBandsWithBlockers() { private Map<FCollection<CardView>, FCollection<CardView>> getBandsWithBlockers() {
return get(TrackableProperty.BandsWithBlockers); return get(TrackableProperty.BandsWithBlockers);
} }
private Map<CardView, Iterable<CardView>> getAttackersWithPlannedBlockers() { private Map<CardView, FCollection<CardView>> getAttackersWithPlannedBlockers() {
return get(TrackableProperty.AttackersWithPlannedBlockers); return get(TrackableProperty.AttackersWithPlannedBlockers);
} }
private Map<Iterable<CardView>, Iterable<CardView>> getBandsWithPlannedBlockers() { private Map<FCollection<CardView>, FCollection<CardView>> getBandsWithPlannedBlockers() {
return get(TrackableProperty.BandsWithPlannedBlockers); return get(TrackableProperty.BandsWithPlannedBlockers);
} }
@@ -64,7 +64,7 @@ public class CombatView extends TrackableObject {
} }
public boolean isBlocking(final CardView card) { public boolean isBlocking(final CardView card) {
for (final Iterable<CardView> blockers : getAttackersWithBlockers().values()) { for (final FCollection<CardView> blockers : getAttackersWithBlockers().values()) {
if (blockers == null) { if (blockers == null) {
continue; continue;
} }
@@ -80,7 +80,7 @@ public class CombatView extends TrackableObject {
* @return the blockers associated with an attacker, or {@code null} if the * @return the blockers associated with an attacker, or {@code null} if the
* attacker is unblocked. * attacker is unblocked.
*/ */
public Iterable<CardView> getBlockers(final CardView attacker) { public FCollection<CardView> getBlockers(final CardView attacker) {
return getAttackersWithBlockers().get(attacker); return getAttackersWithBlockers().get(attacker);
} }
@@ -89,7 +89,7 @@ public class CombatView extends TrackableObject {
* @return the blockers associated with an attacker, or {@code null} if the * @return the blockers associated with an attacker, or {@code null} if the
* attacker is unblocked (planning stage, for targeting overlay). * attacker is unblocked (planning stage, for targeting overlay).
*/ */
public Iterable<CardView> getPlannedBlockers(final CardView attacker) { public FCollection<CardView> getPlannedBlockers(final CardView attacker) {
return getAttackersWithPlannedBlockers().get(attacker); return getAttackersWithPlannedBlockers().get(attacker);
} }
@@ -101,7 +101,7 @@ public class CombatView extends TrackableObject {
* an {@link Iterable} representing an attacking band. * an {@link Iterable} representing an attacking band.
* @return an {@link Iterable} of {@link CardView} objects, or {@code null}. * @return an {@link Iterable} of {@link CardView} objects, or {@code null}.
*/ */
public Iterable<CardView> getBlockers(final Iterable<CardView> attackingBand) { public FCollection<CardView> getBlockers(final FCollection<CardView> attackingBand) {
return getBandsWithBlockers().get(attackingBand); return getBandsWithBlockers().get(attackingBand);
} }
@@ -113,12 +113,12 @@ public class CombatView extends TrackableObject {
* an {@link Iterable} representing an attacking band. * an {@link Iterable} representing an attacking band.
* @return an {@link Iterable} of {@link CardView} objects, or {@code null}. * @return an {@link Iterable} of {@link CardView} objects, or {@code null}.
*/ */
public Iterable<CardView> getPlannedBlockers(final Iterable<CardView> attackingBand) { public FCollection<CardView> getPlannedBlockers(final FCollection<CardView> attackingBand) {
return getBandsWithPlannedBlockers().get(attackingBand); return getBandsWithPlannedBlockers().get(attackingBand);
} }
public Iterable<CardView> getAttackersOf(final GameEntityView defender) { public FCollection<CardView> getAttackersOf(final GameEntityView defender) {
ArrayList<CardView> views = new ArrayList<CardView>(); FCollection<CardView> views = new FCollection<CardView>();
for (Entry<CardView, GameEntityView> entry : getAttackersWithDefenders().entrySet()) { for (Entry<CardView, GameEntityView> entry : getAttackersWithDefenders().entrySet()) {
if (entry.getValue().equals(defender)) { if (entry.getValue().equals(defender)) {
views.add(entry.getKey()); views.add(entry.getKey());
@@ -126,9 +126,9 @@ public class CombatView extends TrackableObject {
} }
return views; return views;
} }
public Iterable<Iterable<CardView>> getAttackingBandsOf(final GameEntityView defender) { public Iterable<FCollection<CardView>> getAttackingBandsOf(final GameEntityView defender) {
ArrayList<Iterable<CardView>> views = new ArrayList<Iterable<CardView>>(); ArrayList<FCollection<CardView>> views = new ArrayList<FCollection<CardView>>();
for (Entry<Iterable<CardView>, GameEntityView> entry : getBandsWithDefenders().entrySet()) { for (Entry<FCollection<CardView>, GameEntityView> entry : getBandsWithDefenders().entrySet()) {
if (entry.getValue().equals(defender)) { if (entry.getValue().equals(defender)) {
views.add(entry.getKey()); views.add(entry.getKey());
} }
@@ -137,9 +137,17 @@ public class CombatView extends TrackableObject {
} }
public void addAttackingBand(final Iterable<CardView> attackingBand, final GameEntityView defender, final Iterable<CardView> blockers, final Iterable<CardView> plannedBlockers) { public void addAttackingBand(final Iterable<CardView> attackingBand, final GameEntityView defender, final Iterable<CardView> blockers, final Iterable<CardView> plannedBlockers) {
final List<CardView> attackingBandCopy = Lists.newArrayList(attackingBand); final FCollection<CardView> attackingBandCopy = new FCollection<CardView>();
final List<CardView> blockersCopy = blockers == null ? null : Lists.newArrayList(blockers); final FCollection<CardView> blockersCopy = new FCollection<CardView>();
final List<CardView> plannedBlockersCopy = plannedBlockers == null ? null : Lists.newArrayList(plannedBlockers); final FCollection<CardView> plannedBlockersCopy = new FCollection<CardView>();
attackingBandCopy.addAll(attackingBand);
if (blockers != null) {
blockersCopy.addAll(blockers);
}
if (plannedBlockers != null) {
plannedBlockersCopy.addAll(plannedBlockers);
}
for (final CardView attacker : attackingBandCopy) { for (final CardView attacker : attackingBandCopy) {
this.getAttackersWithDefenders().put(attacker, defender); this.getAttackersWithDefenders().put(attacker, defender);

View File

@@ -118,12 +118,12 @@ public enum TrackableProperty {
OptionalTrigger(TrackableTypes.BooleanType), OptionalTrigger(TrackableTypes.BooleanType),
//Combat //Combat
AttackersWithDefenders(TrackableTypes.CardViewCollectionType), //TODO: change out for proper types when serialization needed AttackersWithDefenders(TrackableTypes.CardViewCollectionType, false), //TODO: change out for proper types when serialization needed
AttackersWithBlockers(TrackableTypes.CardViewCollectionType), AttackersWithBlockers(TrackableTypes.CardViewCollectionType, false),
BandsWithDefenders(TrackableTypes.CardViewCollectionType), BandsWithDefenders(TrackableTypes.CardViewCollectionType, false),
BandsWithBlockers(TrackableTypes.CardViewCollectionType), BandsWithBlockers(TrackableTypes.CardViewCollectionType, false),
AttackersWithPlannedBlockers(TrackableTypes.CardViewCollectionType), AttackersWithPlannedBlockers(TrackableTypes.CardViewCollectionType, false),
BandsWithPlannedBlockers(TrackableTypes.CardViewCollectionType), BandsWithPlannedBlockers(TrackableTypes.CardViewCollectionType, false),
//Game //Game
GameType(TrackableTypes.EnumType(GameType.class)), GameType(TrackableTypes.EnumType(GameType.class)),

View File

@@ -12,6 +12,7 @@ import forge.game.combat.CombatView;
import forge.game.player.PlayerView; import forge.game.player.PlayerView;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.screens.match.views.VCombat; import forge.screens.match.views.VCombat;
import forge.util.FCollection;
import forge.util.Lang; import forge.util.Lang;
/** /**
@@ -70,7 +71,7 @@ public enum CCombat implements ICDoc {
private static String getCombatDescription(final CombatView localCombat, final GameEntityView defender) { private static String getCombatDescription(final CombatView localCombat, final GameEntityView defender) {
final StringBuilder display = new StringBuilder(); final StringBuilder display = new StringBuilder();
Iterable<Iterable<CardView>> bands = localCombat.getAttackingBandsOf(defender); Iterable<FCollection<CardView>> bands = localCombat.getAttackingBandsOf(defender);
if (bands == null || Iterables.isEmpty(bands)) { if (bands == null || Iterables.isEmpty(bands)) {
return StringUtils.EMPTY; return StringUtils.EMPTY;
} }
@@ -86,7 +87,7 @@ public enum CCombat implements ICDoc {
// Associate Bands, Attackers Blockers // Associate Bands, Attackers Blockers
boolean previousBand = false; boolean previousBand = false;
for (final Iterable<CardView> band : bands) { for (final FCollection<CardView> band : bands) {
final int bandSize = Iterables.size(band); final int bandSize = Iterables.size(band);
if (bandSize == 0) { if (bandSize == 0) {
continue; continue;
@@ -97,7 +98,7 @@ public enum CCombat implements ICDoc {
display.append("\n"); display.append("\n");
} }
final Iterable<CardView> blockers = localCombat.getBlockers(band); final FCollection<CardView> blockers = localCombat.getBlockers(band);
final boolean blocked = (blockers != null); final boolean blocked = (blockers != null);
final boolean isBand = bandSize > 1; final boolean isBand = bandSize > 1;
if (isBand) { if (isBand) {