Categories and/or tags
-
@Cernel I'm adding the foreach ability along with this so you could do something like this for an attachment where you have 2 "lists" of the same length that are looped through to create in this case 4 attachments:
<attachment foreach="anyMech.Infantry:anyMechPlayers"
<variable name="anyMech.Infantry"> <element name="germanMech.Infantry"/> <element name="italianMech.Infantry"/> <element name="italianMech.Infantry"/> <element name="japaneseMech.Infantry"/> </variable>
<variable name="anyMechPlayers"> <element name="Germany"/> <element name="Italy"/> <element name="ItalianMinors"/> <element name="Japan"/> </variable>
-
@redrum Will "foreach" work for triggers (for example, allowing a trigger to fire once for each of some units in a territory?). If so, will this make "each" deprecate?
Back on the matter in case duplicates are not redundant (meaning "germanMech.Infantry+italianMech.Infantry+italianMech.Infantry+japaneseMech.Infantry" is not the same as "germanMech.Infantry+italianMech.Infantry+japaneseMech.Infantry"), it can be called "sequence".
https://en.wikipedia.org/wiki/Sequence
The only matter, at this point, is that in sequences the order is usually supposed to have significance.
I don't recall if there is a term for something repetitions sensitive but not positions sensitive (set isn't for both and sequence is for both).
-
@Cernel said in Categories and/or tags:
I don't recall if there is a term for something repetitions sensitive but not positions sensitive
Apparently, it's called "multiset".
-
I really hope that the term is at least a word known to ordinary people and not technobabble gibberish
-
@Frostion said in Categories and/or tags:
I really hope that the term is at least a word known to ordinary people and not technobabble gibberish
Knuth himself attributes the first study of multisets to the Indian mathematician Bhāskarāchārya, who described permutations of multisets around 1150. Knuth also lists other names that were proposed or used for this concept, including list, bunch, bag, heap, sample, weighted set, collection, and suite.
I just advice against list, as pretty much all the xml is a bunch of lists, so that may be confusing if you are talking about some lists.
-
@Cernel It will be available for any type of attachment. It will in ways complement "each" by allowing map makers have essentially a attachment "template" which then uses a "variable" to generate multiple attachments (should help minimize copy/paste). One of the most obvious uses of this is having separate units for each player like TWW does where you will define "infantry" and use "foreach" with a variable containing say the list of players which the engine will then generate a separate unit attachment for each player.
@Frostion I think I'm going to just stick with variable as that avoids trying to decide between all the different types of lists, sets, sequences, etc. Essentially its similar to in algebra or basic programming, you can define a variable with a symbol/name which then represents some value (list of elements). Wherever you use that variable, it then replaces it with the list of elements.
-
@Cernel Also, a "weighted set" would be a little more polished, if you can just call the element once and define a number of entries for it, rather than having to list it multiple times.
-
And now the second portion of this change which is
foreach
. This allows defining essentially an attachment "template" which usingvariables
then generates multiple attachments. This can be very useful for repetitive unit attachments, conditions, triggers, etc as it will make the XML much shorter and easier to manage/update. The following shows an example of how this can be used to define multiple similar unit attachments for TWW:Define 3 variables which vary across the unit attachments
*Notice that you can have an empty element (under Players in this case) which means that any attachment option will be skipped<variableList> <variable name="Infantry"> <element name="germanInfantry"/> <element name="russianInfantry"/> </variable> <variable name="Players"> <element name="Germany"/> <element name=""/> </variable> <variable name="Barracks"> <element name="germanBarracks"/> <element name="russianBarracks"/> </variable> </variableList>
Define unit attachment "template" using "foreach" and specifying the 3 variables (Infantry:Players:Barracks)
*The foreach makes it so it iterates through the variables' elements and replaces any @X@ that is specified in the templates which in this case the Infantry variable is used to specify what unit to attachTo by using @Infantry@<attachment foreach="$Infantry$:$Players$:$Barracks$" name="unitAttachment" attachTo="@Infantry@" javaClass="games.strategy.triplea.attachments.UnitAttachment" type="unitType"> <option name="movement" value="1"/> <option name="attack" value="2"/> <option name="defense" value="3"/> <option name="transportCost" value="2"/> <option name="isLandTransportable" value="true"/> <option name="canBeGivenByTerritoryTo" value="@Players@"/> <option name="requiresUnits" value="@Barracks@"/> <option name="canInvadeOnlyFrom" value="none"/> </attachment>
This then generates the equivalent of having 2 unit attachments
*Notice that canBeGivenByTerritoryTo is only included for germanInfantry not russianInfantry because its left empty in the Players variable<attachment name="unitAttachment" attachTo="germanInfantry" javaClass="games.strategy.triplea.attachments.UnitAttachment" type="unitType"> <option name="movement" value="1"/> <option name="attack" value="2"/> <option name="defense" value="3"/> <option name="transportCost" value="2"/> <option name="isLandTransportable" value="true"/> <option name="canBeGivenByTerritoryTo" value="Germany"/> <option name="requiresUnits" value="germanBarracks"/> <option name="canInvadeOnlyFrom" value="none"/> </attachment> <attachment name="unitAttachment" attachTo="russianInfantry" javaClass="games.strategy.triplea.attachments.UnitAttachment" type="unitType"> <option name="movement" value="1"/> <option name="attack" value="2"/> <option name="defense" value="3"/> <option name="transportCost" value="2"/> <option name="isLandTransportable" value="true"/> <option name="requiresUnits" value="russianBarracks"/> <option name="canInvadeOnlyFrom" value="none"/> </attachment>
-
@redrum said in Categories and/or tags:
*Notice that you can have an empty element (under Players in this case) which means that any attachment option will be skipped
I don't understand.
-
@Cernel So here is the variable definition with an empty second element:
<variable name="Players"> <element name="Germany"/> <element name=""/> </variable>
This is then used in the template further down in this line:
<option name="canBeGivenByTerritoryTo" value="$Players$"/>
And ends up generating the germanInfantry attachment with this:
<option name="canBeGivenByTerritoryTo" value="Germany"/>
And the russianInfantry attachment skips that option.
-
Here is another
foreach
example to generate multiple similar triggers:Variables
<variableList> <variable name="Players"> <element name="Germany"/> <element name="Brazil"/> </variable> <variable name="Phases"> <element name="germanyBattle"/> <element name="brazilBattle"/> </variable> </variableList>
Trigger Template
<attachment foreach="$Players$:$Phases$" name="triggerAttachmentLiberationUsaBy@Players@" attachTo="@Players@" javaClass="games.strategy.triplea.attachments.TriggerAttachment" type="player"> <option name="conditions" value="conditionAttachmentWashingtonlost:conditionAttachmentChicagolost"/> <option name="when" value="after:@Phases@"/> <option name="players" value="Usa"/> <option name="playerAttachmentName" value="RulesAttachment" count="conditionAttachmentLiberationUsa"/> <option name="playerProperty" value="switch" count="true"/> </attachment>
Generated Triggers
<attachment name="triggerAttachmentLiberationUsaByGermany" attachTo="Germany" javaClass="games.strategy.triplea.attachments.TriggerAttachment" type="player"> <option name="conditions" value="conditionAttachmentWashingtonlost:conditionAttachmentChicagolost"/> <option name="when" value="after:germanyBattle"/> <option name="players" value="Usa"/> <option name="playerAttachmentName" value="RulesAttachment" count="conditionAttachmentLiberationUsa"/> <option name="playerProperty" value="switch" count="true"/> </attachment> <attachment name="triggerAttachmentLiberationUsaByBrazil" attachTo="Brazil" javaClass="games.strategy.triplea.attachments.TriggerAttachment" type="player"> <option name="conditions" value="conditionAttachmentWashingtonlost:conditionAttachmentChicagolost"/> <option name="when" value="after:brazilBattle"/> <option name="players" value="Usa"/> <option name="playerAttachmentName" value="RulesAttachment" count="conditionAttachmentLiberationUsa"/> <option name="playerProperty" value="switch" count="true"/> </attachment>
-
I hope that the basic features of this feature request will be implemented in a way that will not require the mapmaker to understand or use these new and more advanced possibilities. I don't understand anything you presented in your last couple of posts @redrum.
-
@Frostion These are optional advanced XML features and don't at all need to be used (and have no impact on existing maps). They are really just providing a way to have a "find and replace" type XML feature and an "attachment template to generate multiple similar attachments". They are provided to map makers to minimize copy and paste if they want. These can be very useful to maps like TWW which have lots of repetitive XML around unit attachments, conditions, and triggers that are hard to make updates to.
-
@redrum I'm sure once a full example is provided it will be similar to learning anything else in an XML.
-
@Frostion Here is an example of how you could use this feature in the Iron War XML if you wanted. There are player attachments for retainCapital parameters for all regular players which are almost all the same.
Here is what you have now:
<attachment name="playerAttachment" attachTo="Germany" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="Balkan" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="USSR" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="Finland" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="France" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="French-Colonies" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="Britain" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="British-Colonies" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="Italy" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="South-Africa" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="British-India" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="Iraq" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="Iran" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="ANZAC" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="KNIL" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="Japan" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="Thailand" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="USA" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="China" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment> <attachment name="playerAttachment" attachTo="Brazil" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment>
If you ever wanted to say change the capital rules and instead make all players require 1 instead of 0 capitals then you'd have to update each of these attachments 1 by 1 (very unlikely that you'd want to change that but just using this as an example since these player attachments are almost all the same). The only difference between each of these attachments is that player its attachTo as each player needs one.
You could instead use this new feature to make this a bit shorter by defining a variable for the list of players that need this attachment (all of them in this case). And a kind of 'template' for the attachment that will insert the list of players into it to generate the original attachments above. This would allow you to only have to update the capital requirements for all players in one attachment rather than having 20 separate ones.
First, I define a variable named "AllPlayers" and assign a list of players to that (all of the regular ones in this case that I want to specify capital rules for). Then I create an attachment "template" where the "foreach" attribute uses this variable "AllPlayers" to indicate what players to generate a PlayerAttachment based on the template for. For each player in the variable list, it creates an attachment and inserts the "player" into the attachTo field as it specifies $AllPlayers$. This ends up generating the exact same attachments that you have in the above XML.
Here is what it would look like:
<variableList> <variable name="AllPlayers"> <element name="Germany"/> <element name="Balkan"/> <element name="Finland"/> <element name="USSR"/> <element name="Britain"/> <element name="France"/> <element name="British-Colonies"/> <element name="South-Africa"/> <element name="Italy"/> <element name="Iraq"/> <element name="Iran"/> <element name="British-India"/> <element name="French-Colonies"/> <element name="ANZAC"/> <element name="KNIL"/> <element name="Japan"/> <element name="Thailand"/> <element name="USA"/> <element name="China"/> <element name="Brazil"/> </variable> </variableList>
<attachment foreach="$AllPlayers$" name="playerAttachment" attachTo="@AllPlayers@" javaClass="games.strategy.triplea.attachments.PlayerAttachment" type="player"> <option name="retainCapitalProduceNumber" value="0"/> <option name="retainCapitalNumber" value="0"/> </attachment>
-
@redrum
I can see a lot of uses for this. I do have one question. In you example for the unitAttachment, under the "Players" variable, the last element was left blank so that when creating the attachment that value would be left out. This I understand, but what would happen if the blank value was not there?In my map 'Invasion USA' there are 30 Victory Cities, with 'Denver' being the only city with both 'city' and 'mountain' effects. So if I created a list 'AllCities':
<variableList> <variable name="AllCities"> <element name="Denver"/> <element name="Washington D.C."/> <element name="New York"/> <element name="Boston"/> <element name="Philadelphia"/> <element name="Buffalo"/> <element name="Pittsburgh"/> <element name="San Diego"/> <element name="Memphis"/> <element name="Indianapolis"/> <element name="New Orleans"/> <element name="Los Angeles"/> <element name="Milwaukee"/> <element name="Detroit"/> <element name="Houston"/> <element name="Chicago"/> <element name="San Francisco"/> <element name="Portland"/> <element name="Tampa"/> <element name="Kansas City"/> <element name="St. Louis"/> <element name="Salt Lake City"/> <element name="Seattle"/> <element name="San Antonio"/> <element name="Dallas"/> <element name="Phoenix"/> <element name="Minneapolis"/> <element name="Atlanta"/> <element name="Miami"/> <element name="Cleveland"/> </variable>
And the add another list for territoryEffect:
<variable name="MountainOnly"> <element name="mountain"/> </variable> </variableList>
And the for my territoryAttachments I used:
<attachment foreach="AllCities:MountainOnly" name="territoryAttachment" attachTo="$AllCities$" javaClass="games.strategy.triplea.attachments.TerritoryAttachment" type="territory"> <option name="production" value="6"/> <option name="unitProduction" value="2"/> <option name="resources" value="1:VCs"/> <option name="territoryEffect" value="city"/> <option name="territoryEffect" value="$MountainOnly$"/> <option name="capital" value="Americans"/> </attachment>
Would it create the following attachments?
<attachment name="territoryAttachment" attachTo="Denver" javaClass="games.strategy.triplea.attachments.TerritoryAttachment" type="territory"> <option name="production" value="6"/> <option name="unitProduction" value="2"/> <option name="resources" value="1:VCs"/> <option name="territoryEffect" value="city"/> <option name="territoryEffect" value="mountain"/> <option name="capital" value="Americans"/> </attachment> <attachment name="territoryAttachment" attachTo="Washington D.C." javaClass="games.strategy.triplea.attachments.TerritoryAttachment" type="territory"> <option name="production" value="6"/> <option name="unitProduction" value="2"/> <option name="resources" value="1:VCs"/> <option name="territoryEffect" value="city"/> <option name="capital" value="Americans"/> </attachment>
Or would I have to add the 29 extra blank elements?
Cheers...
-
@wc_sumpton Right now I'm enforcing that all variables used in the same foreach must be the same length. For this particular example, I would just define Denver separately if its the only 1 like that otherwise you would need to add 29 empty elements. Here is what I would probably do:
<variable name="AllCities"> <element name="Washington D.C."/> <element name="New York"/> <element name="Boston"/> <element name="Philadelphia"/> <element name="Buffalo"/> <element name="Pittsburgh"/> <element name="San Diego"/> <element name="Memphis"/> <element name="Indianapolis"/> <element name="New Orleans"/> <element name="Los Angeles"/> <element name="Milwaukee"/> <element name="Detroit"/> <element name="Houston"/> <element name="Chicago"/> <element name="San Francisco"/> <element name="Portland"/> <element name="Tampa"/> <element name="Kansas City"/> <element name="St. Louis"/> <element name="Salt Lake City"/> <element name="Seattle"/> <element name="San Antonio"/> <element name="Dallas"/> <element name="Phoenix"/> <element name="Minneapolis"/> <element name="Atlanta"/> <element name="Miami"/> <element name="Cleveland"/> </variable>
<attachment foreach="$AllCities$" name="territoryAttachment" attachTo="@AllCities@" javaClass="games.strategy.triplea.attachments.TerritoryAttachment" type="territory"> <option name="production" value="6"/> <option name="unitProduction" value="2"/> <option name="resources" value="1:VCs"/> <option name="territoryEffect" value="city"/> <option name="capital" value="Americans"/> </attachment>
<attachment name="territoryAttachment" attachTo="Denver" javaClass="games.strategy.triplea.attachments.TerritoryAttachment" type="territory"> <option name="production" value="6"/> <option name="unitProduction" value="2"/> <option name="resources" value="1:VCs"/> <option name="territoryEffect" value="city"/> <option name="territoryEffect" value="mountain"/> <option name="capital" value="Americans"/> </attachment>
-
@redrum That edit was an important one.
-
@Hepps Yeah, misunderstood what he was trying to do the first read through.
-
@redrum
Got-ya! Thanks for the quick reply! Wondering when you plan to implement this. Would love to play around with some ideas!Cheers...