# HG changeset patch # User IBBoard # Date 1332621191 0 # Node ID 7b9ff7b1df24568f11bde99b6bdc890902aad275 # Parent 59e1fb8a476a02a60d28500de3b075c8269b2ce2 Re #394: Make requirements (or factory) more closely match Rollcall methods * Make UnitRequiresAtLeastNUnitsRequirementFactory handle "alternatives" (Rollcall's "-1,X|Y" notation) * Make RequiresAtLeastNUnitsRequirement handle alternatives/multiple unit types in one limit * Move some useful code up the classes diff -r 59e1fb8a476a -r 7b9ff7b1df24 API/Factories/Requirement/UnitRequiresAtLeastNUnitsRequirementFactory.cs --- a/API/Factories/Requirement/UnitRequiresAtLeastNUnitsRequirementFactory.cs Sat Mar 24 16:40:01 2012 +0000 +++ b/API/Factories/Requirement/UnitRequiresAtLeastNUnitsRequirementFactory.cs Sat Mar 24 20:33:11 2012 +0000 @@ -4,6 +4,7 @@ using System; using IBBoard.WarFoundry.API.Objects; using IBBoard.WarFoundry.API.Objects.Requirement; +using System.Collections.Generic; namespace IBBoard.WarFoundry.API.Factories.Requirement { @@ -28,8 +29,10 @@ //Do nothing special } - public string AppliesToID { - get { + public string AppliesToID + { + get + { return UnitRequiresAtLeastNUnitsRequirement.REQUIREMENT_ID; } } @@ -47,13 +50,8 @@ foreach (string requirement in data.Split('|')) { string[] requirementParts = requirement.Split(':'); - string unitID = requirementParts[0]; - UnitType unitType = raceFactory.GetUnitType(unitID, race); - - if (unitType == null) - { - throw new InvalidRequirementException(String.Format("Invalid unit type '{0}' for 'Requires at least N units' requirement", unitID)); - } + string unitIDs = requirementParts[0]; + UnitType[] unitTypes = GetUnitTypes(unitIDs, race, raceFactory); if (requirementParts.Length == 2) { @@ -61,19 +59,38 @@ try { - req.AddUnitTypeRequirement(unitType, Int32.Parse(amount)); + req.AddUnitTypeRequirement(Int32.Parse(amount), unitTypes); } catch (FormatException) { - throw new InvalidRequirementException(String.Format("Invalid amount '{0}' for unit type '{1}' for 'Requires at least N units' requirement", amount, unitID)); + throw new InvalidRequirementException(String.Format("Invalid amount '{0}' for unit types '{1}' for 'Requires at least N units' requirement", amount, unitIDs)); } } else { - req.AddUnitTypeRequirement(unitType); + req.AddUnitTypeRequirement(unitTypes); } } } + + private UnitType[] GetUnitTypes(string data, Race race, IRaceFactory raceFactory) + { + List unitTypes = new List(); + + foreach (string unitID in data.Split(';')) + { + UnitType unitType = raceFactory.GetUnitType(unitID, race); + + if (unitType == null) + { + throw new InvalidRequirementException(String.Format("Invalid unit type '{0}' for 'Requires at least N units' requirement", unitID)); + } + + unitTypes.Add(unitType); + } + + return unitTypes.ToArray(); + } } } diff -r 59e1fb8a476a -r 7b9ff7b1df24 API/Objects/Requirement/AbstractUnitRequirement.cs --- a/API/Objects/Requirement/AbstractUnitRequirement.cs Sat Mar 24 16:40:01 2012 +0000 +++ b/API/Objects/Requirement/AbstractUnitRequirement.cs Sat Mar 24 20:33:11 2012 +0000 @@ -157,6 +157,23 @@ return toArmy.GetUnitTypeCount(unitType) + GetCountFromObject(wfObject, unitType); } + protected int GetUnitTypesCount(Army army, UnitType[] unitTypes) + { + return GetUnitTypesCount(army, unitTypes, null); + } + + protected int GetUnitTypesCount(Army toArmy, UnitType[] unitTypes, IWarFoundryObject wfObject) + { + int count = 0; + + foreach (UnitType unitType in unitTypes) + { + count += GetUnitTypeCount(toArmy, unitType, wfObject); + } + + return count; + } + protected int GetCountFromObject(IWarFoundryObject wfObject, UnitType limitedType) { return (limitedType.Equals(wfObject) || (wfObject is Unit && ((Unit)wfObject).UnitType.Equals(limitedType))) ? 1 : 0; @@ -177,6 +194,19 @@ } public OBJECT_TYPE AllowedObject { get { return allowedObject; } } + + protected string GetUnitTypeList(UnitCountRequirementData limit) + { + List namesList = new List(); + + foreach (UnitType unitType in limit.UnitTypes) + { + namesList.Add(unitType.Name); + } + + string[] names = namesList.ToArray(); + return String.Join(" or ", names); + } } } diff -r 59e1fb8a476a -r 7b9ff7b1df24 API/Objects/Requirement/RequiresAtLeastNUnitsRequirement.cs --- a/API/Objects/Requirement/RequiresAtLeastNUnitsRequirement.cs Sat Mar 24 16:40:01 2012 +0000 +++ b/API/Objects/Requirement/RequiresAtLeastNUnitsRequirement.cs Sat Mar 24 20:33:11 2012 +0000 @@ -85,7 +85,7 @@ foreach (UnitCountRequirementData requirement in ConstraintTypes) { - if (GetUnitTypeCount(toArmy, requirement.UnitType, wfObject) < requirement.Count) + if (GetUnitTypesCount(toArmy, requirement.UnitTypes, wfObject) < requirement.Count) { isValid = Validation.Failed; break; @@ -96,7 +96,7 @@ } /// - /// Adds a requirement for there to be at least minCount of a given UnitType + /// Adds a requirement for there to be at least minCount of a given UnitType, allowing any number of of this UnitType. /// /// /// The unit type to require. @@ -106,11 +106,11 @@ /// public void AddUnitTypeRequirement(UnitType unitType, int minCount) { - ConstraintTypes.Add(new UnitCountRequirementData(unitType, minCount)); + AddUnitTypeRequirement(minCount, unitType); } /// - /// Adds a requirement for there to be one or more of a given UnitType + /// Adds a requirement for there to be one or more of a given UnitType, allowing any number of of this UnitType. /// /// /// The unit type to require. @@ -121,6 +121,34 @@ } /// + /// Adds a requirement for there to be one or more of the given UnitTypes, allowing any number of of this UnitType. If multiple unit types + /// are supplied here then they are treated as alternatives (so "unitType1, unitType2" requires one of either type). + /// + /// + /// The unit type or types to require. + /// + public void AddUnitTypeRequirement(params UnitType[] unitTypes) + { + AddUnitTypeRequirement(1, unitTypes); + } + + /// + /// Adds a requirement for there to be minCount or more of the given UnitTypes, allowing any number of of this UnitType. If multiple unit types + /// are supplied here then they are treated as alternatives (so "unitType1, unitType2" requires one of either type). + /// + /// + /// The number of units to be allowed for each 1 of unitType + /// + /// + /// The unit type or types to require. + /// + public void AddUnitTypeRequirement(int minCount, params UnitType[] unitTypes) + { + ConstraintTypes.Add(new UnitCountRequirementData(unitTypes, minCount)); + } + + + /// /// Checks whether the supplied army is currently valid according to this requirement. /// /// @@ -140,7 +168,7 @@ foreach (UnitCountRequirementData requirement in ConstraintTypes) { - if (toValidate.GetUnitTypeCount(requirement.UnitType) < requirement.Count) + if (GetUnitTypesCount(toValidate, requirement.UnitTypes) < requirement.Count) { isValid = Validation.Failed; break; @@ -166,11 +194,11 @@ foreach (UnitCountRequirementData requirement in ConstraintTypes) { - int unitCount = army.GetUnitTypeCount(requirement.UnitType); + int unitCount = GetUnitTypesCount(army, requirement.UnitTypes); if (unitCount < requirement.Count) { - failures.Add(requirement.Count + " × " + requirement.UnitType.Name + " (have " + unitCount + ")"); + failures.Add(requirement.Count + " × " + GetUnitTypeList(requirement) + " (have " + unitCount + ")"); } } @@ -188,11 +216,11 @@ foreach (UnitCountRequirementData requirement in ConstraintTypes) { - int unitCount = GetUnitTypeCount(army, requirement.UnitType, toAdd); + int unitCount = GetUnitTypesCount(army, requirement.UnitTypes, toAdd); if (unitCount < requirement.Count) { - failures.Add(requirement.Count + " × " + requirement.UnitType.Name + " (would have " + unitCount + ")"); + failures.Add(requirement.Count + " × " + GetUnitTypeList(requirement) + " (would have " + unitCount + ")"); } } diff -r 59e1fb8a476a -r 7b9ff7b1df24 API/Objects/Requirement/RequiresNUnitsForMObjectsRequirement.cs --- a/API/Objects/Requirement/RequiresNUnitsForMObjectsRequirement.cs Sat Mar 24 16:40:01 2012 +0000 +++ b/API/Objects/Requirement/RequiresNUnitsForMObjectsRequirement.cs Sat Mar 24 20:33:11 2012 +0000 @@ -50,19 +50,6 @@ return failures; } - private string GetUnitTypeList(UnitCountRequirementData limit) - { - List namesList = new List(); - - foreach (UnitType unitType in limit.UnitTypes) - { - namesList.Add(unitType.Name); - } - - string[] names = namesList.ToArray(); - return String.Join(" or ", names); - } - private bool IsValidByRequirement(IWarFoundryObject wfObject, Army toArmy, UnitCountRequirementData limit, int allowedTypeCount) { int limitedTypeCount = GetUnitTypesCount(toArmy, limit.UnitTypes, wfObject); @@ -101,18 +88,6 @@ return canAdd; } - private int GetUnitTypesCount(Army toArmy, UnitType[] unitTypes, IWarFoundryObject wfObject) - { - int count = 0; - - foreach (UnitType unitType in unitTypes) - { - count += GetUnitTypeCount(toArmy, unitType, wfObject); - } - - return count; - } - private int GetAllowedObjectCount(Army toArmy, OBJECT_TYPE obj, IWarFoundryObject wfObject) { return GetObjectCountFromArmy(toArmy, obj) + GetCountFromObject(wfObject, obj); @@ -177,11 +152,6 @@ protected abstract int GetAllowedObjectCount(Army army); - private int GetUnitTypesCount(Army army, UnitType[] unitTypes) - { - return GetUnitTypesCount(army, unitTypes, null); - } - /// /// Adds a requirement for there to be at least minCount of a given UnitType, allowing allowedCount of this UnitType ///