From 77c91758d85d4c1e675932c368fa08a0b6587321 Mon Sep 17 00:00:00 2001 From: stanolacko Date: Mon, 19 Jul 2021 08:47:28 +0200 Subject: [PATCH 1/6] XML Utils attributeStringValue --- src/main/java/com/jcloisterzone/XMLUtils.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/jcloisterzone/XMLUtils.java b/src/main/java/com/jcloisterzone/XMLUtils.java index 39419499..9c757126 100644 --- a/src/main/java/com/jcloisterzone/XMLUtils.java +++ b/src/main/java/com/jcloisterzone/XMLUtils.java @@ -103,4 +103,15 @@ public static Integer attributeIntValue(Element e, String attr, Integer defaultV } return Integer.parseInt(e.getAttribute(attr)); } + + public static String attributeStringValue(Element e, String attr) { + return attributeStringValue(e, attr, null); + } + + public static String attributeStringValue(Element e, String attr, String defaultValue) { + if (!e.hasAttribute(attr)) { + return defaultValue; + } + return e.getAttribute(attr); + } } From 27fe8d130c21a040444d4b4ed0ef5ad6947f8fbf Mon Sep 17 00:00:00 2001 From: stanolacko Date: Mon, 19 Jul 2021 08:48:17 +0200 Subject: [PATCH 2/6] StringNonMergingModifier --- .../modifier/StringNonMergingModifier.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/com/jcloisterzone/feature/modifier/StringNonMergingModifier.java diff --git a/src/main/java/com/jcloisterzone/feature/modifier/StringNonMergingModifier.java b/src/main/java/com/jcloisterzone/feature/modifier/StringNonMergingModifier.java new file mode 100644 index 00000000..8528b268 --- /dev/null +++ b/src/main/java/com/jcloisterzone/feature/modifier/StringNonMergingModifier.java @@ -0,0 +1,24 @@ +package com.jcloisterzone.feature.modifier; + +import com.jcloisterzone.game.setup.SetupQuery; + +public class StringNonMergingModifier extends FeatureModifier { + + public StringNonMergingModifier(String selector, SetupQuery enabledBy) { + super(selector, enabledBy); + } + + @Override + public String mergeValues(String a, String b) { + if (a != null) { + return (b != null && a.equals(b)) ? a : null; + } else { + return (b != null) ? b : null; + } + } + + @Override + public String valueOf(String attr) { + return attr; + } +} From 1aa6f03b2260bae416a5cccfe317aec4d2d937f6 Mon Sep 17 00:00:00 2001 From: stanolacko Date: Mon, 19 Jul 2021 09:07:25 +0200 Subject: [PATCH 3/6] Famillies - city can have only one color of shields --- .../java/com/jcloisterzone/engine/Engine.java | 2 + .../game/capability/FamiliesCapability.java | 62 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/main/java/com/jcloisterzone/game/capability/FamiliesCapability.java diff --git a/src/main/java/com/jcloisterzone/engine/Engine.java b/src/main/java/com/jcloisterzone/engine/Engine.java index ace6b84d..a1894480 100644 --- a/src/main/java/com/jcloisterzone/engine/Engine.java +++ b/src/main/java/com/jcloisterzone/engine/Engine.java @@ -143,6 +143,8 @@ private GameSetup createSetupFromMessage(GameSetupMessage setupMsg) { capabilities = addCapabilities(capabilities, setupMsg,"russian-trap", RussianPromosTrapCapability.class); capabilities = addCapabilities(capabilities, setupMsg,"watchtower", WatchtowerCapability.class); + capabilities = addCapabilities(capabilities, setupMsg,"families", FamiliesCapability.class); + Map rules = HashMap.empty(); if (setupMsg.getElements().containsKey("farmers")) { rules = rules.put(Rule.FARMERS,true); diff --git a/src/main/java/com/jcloisterzone/game/capability/FamiliesCapability.java b/src/main/java/com/jcloisterzone/game/capability/FamiliesCapability.java new file mode 100644 index 00000000..85f665fd --- /dev/null +++ b/src/main/java/com/jcloisterzone/game/capability/FamiliesCapability.java @@ -0,0 +1,62 @@ +package com.jcloisterzone.game.capability; + +import com.jcloisterzone.board.*; +import com.jcloisterzone.feature.City; +import com.jcloisterzone.feature.Feature; +import com.jcloisterzone.feature.Structure; +import com.jcloisterzone.feature.modifier.StringNonMergingModifier; +import com.jcloisterzone.game.Capability; +import com.jcloisterzone.game.state.GameState; +import com.jcloisterzone.game.state.PlacedTile; +import com.jcloisterzone.reducers.PlaceTile; +import io.vavr.collection.List; + +import static com.jcloisterzone.XMLUtils.attributeIntValue; +import static com.jcloisterzone.XMLUtils.attributeStringValue; + +import org.w3c.dom.Element; + +public class FamiliesCapability extends Capability { + + public static final StringNonMergingModifier FAMILY = new StringNonMergingModifier("family", null); + + @Override + public Feature initFeature(GameState state, String tileId, Feature feature, Element xml) { + if (feature instanceof City) { + if (attributeIntValue(xml, "pennants", 0) > 0 ) { + String family = attributeStringValue(xml, "family", "blue"); + feature = ((City) feature).putModifier(FAMILY, family); + } + } + return feature; + } + + @Override + public boolean isTilePlacementAllowed(GameState state, Tile tile, PlacementOption placement) { + Position pos = placement.getPosition(); + Rotation rot = placement.getRotation(); + + state = (new PlaceTile(tile, pos, rot)).apply(state); + + List cities = state.getTileFeatures2(pos, Structure.class) + .filter(fp -> City.class.isInstance(fp._2)) + .map(t -> (City) t._2) + .toList(); + + if (cities.size()==0) { + // No city + return true; + } + + for(City city : cities) { + if (city.getModifier(state, City.PENNANTS, 0) > 0) { + if (city.getModifier(state, FAMILY, null)==null) { + // Family is null, not allowed placement, because families joined due to StringNonMergingModifier = null + return false; + } + } + } + + return true; + } +} From 70b8ab6d35c68914b442d6d3d0dc8ab5b8a029ef Mon Sep 17 00:00:00 2001 From: stanolacko Date: Mon, 19 Jul 2021 09:58:46 +0200 Subject: [PATCH 4/6] Update to NonMergingNonEmptyModifier --- .../jcloisterzone/game/capability/FamiliesCapability.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/jcloisterzone/game/capability/FamiliesCapability.java b/src/main/java/com/jcloisterzone/game/capability/FamiliesCapability.java index 85f665fd..961b6f1b 100644 --- a/src/main/java/com/jcloisterzone/game/capability/FamiliesCapability.java +++ b/src/main/java/com/jcloisterzone/game/capability/FamiliesCapability.java @@ -4,7 +4,7 @@ import com.jcloisterzone.feature.City; import com.jcloisterzone.feature.Feature; import com.jcloisterzone.feature.Structure; -import com.jcloisterzone.feature.modifier.StringNonMergingModifier; +import com.jcloisterzone.feature.modifier.StringNonMergingNomEmptyModifier; import com.jcloisterzone.game.Capability; import com.jcloisterzone.game.state.GameState; import com.jcloisterzone.game.state.PlacedTile; @@ -18,7 +18,7 @@ public class FamiliesCapability extends Capability { - public static final StringNonMergingModifier FAMILY = new StringNonMergingModifier("family", null); + public static final StringNonMergingNomEmptyModifier FAMILY = new StringNonMergingNomEmptyModifier("family", null); @Override public Feature initFeature(GameState state, String tileId, Feature feature, Element xml) { @@ -36,6 +36,9 @@ public boolean isTilePlacementAllowed(GameState state, Tile tile, PlacementOptio Position pos = placement.getPosition(); Rotation rot = placement.getRotation(); + System.out.println("\n"); + System.out.println(pos); + System.out.println(rot); state = (new PlaceTile(tile, pos, rot)).apply(state); List cities = state.getTileFeatures2(pos, Structure.class) From a4eaefb4f738392157ed053a70abc93b3726dc4a Mon Sep 17 00:00:00 2001 From: stanolacko Date: Mon, 19 Jul 2021 22:19:18 +0200 Subject: [PATCH 5/6] Fix modifier usage to find "merged" different values as empty string --- .../jcloisterzone/game/capability/FamiliesCapability.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/jcloisterzone/game/capability/FamiliesCapability.java b/src/main/java/com/jcloisterzone/game/capability/FamiliesCapability.java index 961b6f1b..8b80827e 100644 --- a/src/main/java/com/jcloisterzone/game/capability/FamiliesCapability.java +++ b/src/main/java/com/jcloisterzone/game/capability/FamiliesCapability.java @@ -4,7 +4,7 @@ import com.jcloisterzone.feature.City; import com.jcloisterzone.feature.Feature; import com.jcloisterzone.feature.Structure; -import com.jcloisterzone.feature.modifier.StringNonMergingNomEmptyModifier; +import com.jcloisterzone.feature.modifier.StringNonMergingNonEmptyModifier; import com.jcloisterzone.game.Capability; import com.jcloisterzone.game.state.GameState; import com.jcloisterzone.game.state.PlacedTile; @@ -18,7 +18,7 @@ public class FamiliesCapability extends Capability { - public static final StringNonMergingNomEmptyModifier FAMILY = new StringNonMergingNomEmptyModifier("family", null); + public static final StringNonMergingNonEmptyModifier FAMILY = new StringNonMergingNonEmptyModifier("family", null); @Override public Feature initFeature(GameState state, String tileId, Feature feature, Element xml) { @@ -53,7 +53,7 @@ public boolean isTilePlacementAllowed(GameState state, Tile tile, PlacementOptio for(City city : cities) { if (city.getModifier(state, City.PENNANTS, 0) > 0) { - if (city.getModifier(state, FAMILY, null)==null) { + if (city.getModifier(state, FAMILY, null).equals("")) { // Family is null, not allowed placement, because families joined due to StringNonMergingModifier = null return false; } From da908451c1d5d3cb395a38cbcbbf56708e51f1b3 Mon Sep 17 00:00:00 2001 From: stanolacko Date: Mon, 19 Jul 2021 22:37:42 +0200 Subject: [PATCH 6/6] Removed attributeStringValue and use xml.has/getAttribute --- .../jcloisterzone/game/capability/FamiliesCapability.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/jcloisterzone/game/capability/FamiliesCapability.java b/src/main/java/com/jcloisterzone/game/capability/FamiliesCapability.java index 8b80827e..3c37069c 100644 --- a/src/main/java/com/jcloisterzone/game/capability/FamiliesCapability.java +++ b/src/main/java/com/jcloisterzone/game/capability/FamiliesCapability.java @@ -24,7 +24,10 @@ public class FamiliesCapability extends Capability { public Feature initFeature(GameState state, String tileId, Feature feature, Element xml) { if (feature instanceof City) { if (attributeIntValue(xml, "pennants", 0) > 0 ) { - String family = attributeStringValue(xml, "family", "blue"); + String family = "blue"; + if (xml.hasAttribute("family")) { + family = xml.getAttribute("family"); + } feature = ((City) feature).putModifier(FAMILY, family); } } @@ -36,9 +39,6 @@ public boolean isTilePlacementAllowed(GameState state, Tile tile, PlacementOptio Position pos = placement.getPosition(); Rotation rot = placement.getRotation(); - System.out.println("\n"); - System.out.println(pos); - System.out.println(rot); state = (new PlaceTile(tile, pos, rot)).apply(state); List cities = state.getTileFeatures2(pos, Structure.class)