comparison API/Objects/Requirement/RequiresAtLeastNUnitsRequirement.cs @ 455:afc6410e4efc

Re #379: Fix validation of requirements to check for unit * Move to "Unit" requirements, since we assume things depend on units * Rename some classes to more meaningful names from unit-based change * Rename "requires N for M" requirement as we can make it more flexible
author IBBoard <dev@ibboard.co.uk>
date Wed, 22 Feb 2012 20:45:39 +0000
parents dace3b7779ca
children 52baffdd2ab9
comparison
equal deleted inserted replaced
454:def5d333c5e8 455:afc6410e4efc
11 /// <summary> 11 /// <summary>
12 /// A requirement where a WarFoundryObject requires at least N units of any of the specified unit types before any number of that object can be taken in an army. 12 /// A requirement where a WarFoundryObject requires at least N units of any of the specified unit types before any number of that object can be taken in an army.
13 /// 13 ///
14 /// The definition for how this requirement is built from a data file is defined in the <see cref="UnitRequiresAtLeastNUnitsRequirementFactory"/> class. 14 /// The definition for how this requirement is built from a data file is defined in the <see cref="UnitRequiresAtLeastNUnitsRequirementFactory"/> class.
15 /// </summary> 15 /// </summary>
16 public class RequiresAtLeastNUnitsRequirement : AbstractRequirement 16 public class RequiresAtLeastNUnitsRequirement<OBJECT_TYPE> : AbstractUnitRequirement<OBJECT_TYPE> where OBJECT_TYPE : IWarFoundryObject
17 { 17 {
18 public static readonly string REQUIREMENT_ID = "RequiresAtLeastNUnits"; 18 public static readonly string REQUIREMENT_ID = "RequiresAtLeastNUnits";
19 private List<UnitCountRequirementData> requiredTypes; 19
20 20 public RequiresAtLeastNUnitsRequirement(OBJECT_TYPE requirementOn, params UnitType[] requiredUnitTypes) : base(requirementOn, requiredUnitTypes)
21 public RequiresAtLeastNUnitsRequirement(params UnitType[] requiredUnitTypes) 21 {
22 { 22 //Do nothing
23 requiredTypes = new List<UnitCountRequirementData>();
24
25 foreach (UnitType unitType in requiredUnitTypes)
26 {
27 AddUnitTypeRequirement(unitType);
28 }
29 } 23 }
30 24
31 public override string RequirementID 25 public override string RequirementID
32 { 26 {
33 get 27 get
36 } 30 }
37 } 31 }
38 32
39 protected override bool TypeEquals(object obj) 33 protected override bool TypeEquals(object obj)
40 { 34 {
41 RequiresAtLeastNUnitsRequirement otherReq = (RequiresAtLeastNUnitsRequirement)obj; 35 RequiresAtLeastNUnitsRequirement<OBJECT_TYPE> otherReq = (RequiresAtLeastNUnitsRequirement<OBJECT_TYPE>)obj;
42 if (!Collections.Collections.AreEqual(requiredTypes, otherReq.requiredTypes)) 36 if (!Collections.Collections.AreEqual(RequiredTypes, otherReq.RequiredTypes))
43 { 37 {
44 return false; 38 return false;
45 } 39 }
46 else 40 else
47 { 41 {
51 45
52 public override int GetHashCode() 46 public override int GetHashCode()
53 { 47 {
54 int hash = 0; 48 int hash = 0;
55 49
56 foreach (UnitCountRequirementData req in requiredTypes) 50 foreach (UnitCountRequirementData req in RequiredTypes)
57 { 51 {
58 hash += req.UnitType.GetHashCode(); 52 hash += req.UnitType.GetHashCode();
59 } 53 }
60 54
61 return hash; 55 return hash;
71 /// The object that we want to add. This may be involved in the check, or it may not affect the evaluation of the requirement 65 /// The object that we want to add. This may be involved in the check, or it may not affect the evaluation of the requirement
72 /// </param> 66 /// </param>
73 /// <param name='toArmy'> 67 /// <param name='toArmy'>
74 /// The army to add the object to. 68 /// The army to add the object to.
75 /// </param> 69 /// </param>
76 public override Validation AllowsAdding(WarFoundryObject wfObject, Army toArmy) 70 public override Validation AllowsAdding(IWarFoundryObject wfObject, Army toArmy)
77 { 71 {
78 return IsApplicable(wfObject, toArmy) ? CheckAllowsAdding(wfObject, toArmy) : Validation.NotApplicable; 72 return IsApplicable(wfObject, toArmy) ? CheckAllowsAdding(wfObject, toArmy) : Validation.NotApplicable;
79 } 73 }
80 74
81 protected override bool IsApplicable(Army toArmy) 75 protected override bool IsApplicable(Army toArmy)
82 { 76 {
83 return false; 77 return false;
84 } 78 }
85 79
86 protected override bool IsApplicable(WarFoundryObject toObject) 80 protected override bool IsApplicable(IWarFoundryObject toObject)
87 { 81 {
88 bool isApplicable = false; 82 bool isApplicable = false;
89 UnitType unitType = GetUnitTypeFromObject(toObject); 83 UnitType unitType = GetUnitTypeFromObject(toObject);
90 84
91 if (unitType != null) 85 if (unitType != null)
94 } 88 }
95 89
96 return isApplicable; 90 return isApplicable;
97 } 91 }
98 92
99 protected UnitType GetUnitTypeFromObject(WarFoundryObject toObject)
100 {
101 UnitType unitType = null;
102
103 if (toObject is UnitType)
104 {
105 unitType = (UnitType)toObject;
106 }
107 else if (toObject is Unit)
108 {
109 unitType = ((Unit)toObject).UnitType;
110 }
111
112 return unitType;
113 }
114
115 private bool IsApplicable(UnitType unitType) 93 private bool IsApplicable(UnitType unitType)
116 { 94 {
117 bool isApplicable = false; 95 bool isApplicable = false;
118 foreach (UnitCountRequirementData requirement in requiredTypes) 96 foreach (UnitCountRequirementData requirement in RequiredTypes)
119 { 97 {
120 if (requirement.UnitType.Equals(unitType)) 98 if (requirement.UnitType.Equals(unitType))
121 { 99 {
122 isApplicable = true; 100 isApplicable = true;
123 break; 101 break;
124 } 102 }
125 } 103 }
126 return isApplicable; 104 return isApplicable;
127 } 105 }
128 106
129 private Validation CheckAllowsAdding(WarFoundryObject wfObject, Army toArmy) 107 private Validation CheckAllowsAdding(IWarFoundryObject wfObject, Army toArmy)
130 { 108 {
131 Validation isValid = Validation.Passed; 109 Validation isValid = Validation.Passed;
132 110
133 foreach (UnitCountRequirementData requirement in requiredTypes) 111 foreach (UnitCountRequirementData requirement in RequiredTypes)
134 { 112 {
135 if (GetUnitTypeCount(toArmy, requirement.UnitType, wfObject) < requirement.Count) 113 if (GetUnitTypeCount(toArmy, requirement.UnitType, wfObject) < requirement.Count)
136 { 114 {
137 isValid = Validation.Failed; 115 isValid = Validation.Failed;
138 break; 116 break;
140 } 118 }
141 119
142 return isValid; 120 return isValid;
143 } 121 }
144 122
145 private int GetUnitTypeCount(Army toArmy, UnitType unitType, WarFoundryObject wfObject)
146 {
147 return toArmy.GetUnitTypeCount(unitType) + GetCountFromObject(wfObject, unitType);
148 }
149
150 private int GetCountFromObject(WarFoundryObject wfObject, UnitType limitedType)
151 {
152 return (limitedType.Equals(wfObject) || (wfObject is Unit && ((Unit)wfObject).UnitType.Equals(limitedType))) ? 1 : 0;
153 }
154
155 /// <summary> 123 /// <summary>
156 /// Adds a requirement for there to be at least minCount of a given UnitType 124 /// Adds a requirement for there to be at least minCount of a given UnitType
157 /// </summary> 125 /// </summary>
158 /// <param name='unitType'> 126 /// <param name='unitType'>
159 /// The unit type to require. 127 /// The unit type to require.
161 /// <param name='minCount'> 129 /// <param name='minCount'>
162 /// The minimum number of that type that must exist. 130 /// The minimum number of that type that must exist.
163 /// </param> 131 /// </param>
164 public void AddUnitTypeRequirement(UnitType unitType, int minCount) 132 public void AddUnitTypeRequirement(UnitType unitType, int minCount)
165 { 133 {
166 requiredTypes.Add(new UnitCountRequirementData(unitType, minCount)); 134 RequiredTypes.Add(new UnitCountRequirementData(unitType, minCount));
167 } 135 }
168 136
169 /// <summary> 137 /// <summary>
170 /// Adds a requirement for there to be one or more of a given UnitType 138 /// Adds a requirement for there to be one or more of a given UnitType
171 /// </summary> 139 /// </summary>
172 /// <param name='unitType'> 140 /// <param name='unitType'>
173 /// The unit type to require. 141 /// The unit type to require.
174 /// </param> 142 /// </param>
175 public void AddUnitTypeRequirement(UnitType unitType) 143 public override void AddUnitTypeRequirement(UnitType unitType)
176 { 144 {
177 AddUnitTypeRequirement(unitType, 1); 145 AddUnitTypeRequirement(unitType, 1);
178 } 146 }
179 147
180 /// <summary> 148 /// <summary>
188 /// </param> 156 /// </param>
189 public override Validation ValidatesArmy(Army toValidate) 157 public override Validation ValidatesArmy(Army toValidate)
190 { 158 {
191 Validation isValid = Validation.Passed; 159 Validation isValid = Validation.Passed;
192 160
193 foreach (UnitCountRequirementData requirement in requiredTypes) 161 foreach (UnitCountRequirementData requirement in RequiredTypes)
194 { 162 {
195 if (toValidate.GetUnitTypeCount(requirement.UnitType) < requirement.Count) 163 if (toValidate.GetUnitTypeCount(requirement.UnitType) < requirement.Count)
196 { 164 {
197 isValid = Validation.Failed; 165 isValid = Validation.Failed;
198 break; 166 break;
209 177
210 private List<string> GetFailedRequirements(Army army) 178 private List<string> GetFailedRequirements(Army army)
211 { 179 {
212 List<string> failures = new List<string>(); 180 List<string> failures = new List<string>();
213 181
214 foreach (UnitCountRequirementData requirement in requiredTypes) 182 foreach (UnitCountRequirementData requirement in RequiredTypes)
215 { 183 {
216 int unitCount = army.GetUnitTypeCount(requirement.UnitType); 184 int unitCount = army.GetUnitTypeCount(requirement.UnitType);
217 185
218 if (unitCount < requirement.Count) 186 if (unitCount < requirement.Count)
219 { 187 {
222 } 190 }
223 191
224 return failures; 192 return failures;
225 } 193 }
226 194
227 protected override string GetFailedAddingRequirementsString(UnitType toAdd, Army toArmy) 195 protected override string GetFailedAddingRequirementsString(IWarFoundryObject toAdd, Army toArmy)
228 { 196 {
229 return String.Join("; ", GetFailedAddingRequirements(toAdd, toArmy).ToArray()); 197 return String.Join("; ", GetFailedAddingRequirements(toAdd, toArmy).ToArray());
230 } 198 }
231 199
232 private List<string> GetFailedAddingRequirements(UnitType unitType, Army army) 200 private List<string> GetFailedAddingRequirements(IWarFoundryObject toAdd, Army army)
233 { 201 {
234 List<string> failures = new List<string>(); 202 List<string> failures = new List<string>();
235 203
236 foreach (UnitCountRequirementData requirement in requiredTypes) 204 foreach (UnitCountRequirementData requirement in RequiredTypes)
237 { 205 {
238 int unitCount = GetUnitTypeCount(army, requirement.UnitType, unitType); 206 int unitCount = GetUnitTypeCount(army, requirement.UnitType, toAdd);
239 207
240 if (unitCount < requirement.Count) 208 if (unitCount < requirement.Count)
241 { 209 {
242 failures.Add(requirement.Count + " × " + requirement.UnitType.Name + " (would have " + unitCount + ")"); 210 failures.Add(requirement.Count + " × " + requirement.UnitType.Name + " (would have " + unitCount + ")");
243 } 211 }
244 } 212 }
245 213
246 return failures; 214 return failures;
215 }
216
217 protected override int GetObjectCountFromArmy(Army toArmy)
218 {
219 return 0;
247 } 220 }
248 } 221 }
249 } 222 }
250 223