Mercurial > repos > IBBoard.WarFoundry.API
annotate API/Objects/Requirement/RequiresAtLeastNUnitsRequirement.cs @ 448:dbd779cdc0f9
Re #350: Add requirement to allow N of unit for specific other units
* Fix limit checking when "limited count" is not 1 (e.g. "need 2 for every 3")
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Fri, 23 Dec 2011 15:36:06 +0000 |
parents | 3882b533d99d |
children | b671085871b7 |
rev | line source |
---|---|
357 | 1 // This file (UnitRequiresAtLeastNUnitsRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 IBBoard |
337
3c4a6403a88c
* Fix capitalisation so that new files are in the namespace
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
2 // |
3c4a6403a88c
* Fix capitalisation so that new files are in the namespace
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
3 // The file and the library/program it is in are licensed and distributed, without warranty, under the GNU Affero GPL license, either version 3 of the License or (at your option) any later version. Please see COPYING for more information and the full license. |
357 | 4 using System; |
5 using System.Collections.Generic; | |
337
3c4a6403a88c
* Fix capitalisation so that new files are in the namespace
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
6 using IBBoard.WarFoundry.API.Objects; |
359
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
7 using System.Text; |
337
3c4a6403a88c
* Fix capitalisation so that new files are in the namespace
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
8 |
3c4a6403a88c
* Fix capitalisation so that new files are in the namespace
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
9 namespace IBBoard.WarFoundry.API.Objects.Requirement |
357 | 10 { |
11 /// <summary> | |
427
3882b533d99d
Re #27: Define unit requirements
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
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. |
3882b533d99d
Re #27: Define unit requirements
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
13 /// |
3882b533d99d
Re #27: Define unit requirements
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
14 /// The definition for how this requirement is built from a data file is defined in the <see cref="UnitRequiresAtLeastNUnitsRequirementFactory"/> class. |
337
3c4a6403a88c
* Fix capitalisation so that new files are in the namespace
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
15 /// </summary> |
358
dbe7ccb1e557
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
357
diff
changeset
|
16 public class RequiresAtLeastNUnitsRequirement : AbstractRequirement |
357 | 17 { |
427
3882b533d99d
Re #27: Define unit requirements
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
18 public static readonly string REQUIREMENT_ID = "RequiresAtLeastNUnits"; |
357 | 19 private List<UnitCountRequirementData> requiredTypes; |
337
3c4a6403a88c
* Fix capitalisation so that new files are in the namespace
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
20 |
3c4a6403a88c
* Fix capitalisation so that new files are in the namespace
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
21 public RequiresAtLeastNUnitsRequirement(params UnitType[] requiredUnitTypes) |
357 | 22 { |
360
777725613edb
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
359
diff
changeset
|
23 FailureStringPrefix = "Army must contain: "; |
357 | 24 requiredTypes = new List<UnitCountRequirementData>(); |
25 | |
26 foreach (UnitType unitType in requiredUnitTypes) | |
27 { | |
28 AddUnitTypeRequirement(unitType); | |
29 } | |
30 } | |
31 | |
427
3882b533d99d
Re #27: Define unit requirements
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
32 |
3882b533d99d
Re #27: Define unit requirements
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
33 public override string RequirementID |
3882b533d99d
Re #27: Define unit requirements
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
34 { |
3882b533d99d
Re #27: Define unit requirements
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
35 get |
3882b533d99d
Re #27: Define unit requirements
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
36 { |
3882b533d99d
Re #27: Define unit requirements
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
37 return REQUIREMENT_ID; |
3882b533d99d
Re #27: Define unit requirements
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
38 } |
3882b533d99d
Re #27: Define unit requirements
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
39 } |
3882b533d99d
Re #27: Define unit requirements
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
40 |
358
dbe7ccb1e557
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
357
diff
changeset
|
41 protected override bool TypeEquals (object obj) |
357 | 42 { |
358
dbe7ccb1e557
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
357
diff
changeset
|
43 RequiresAtLeastNUnitsRequirement otherReq = (RequiresAtLeastNUnitsRequirement)obj; |
dbe7ccb1e557
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
357
diff
changeset
|
44 if (!Collections.Collections.AreEqual(requiredTypes, otherReq.requiredTypes)) |
357 | 45 { |
46 return false; | |
47 } | |
48 else | |
49 { | |
358
dbe7ccb1e557
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
357
diff
changeset
|
50 return true; |
357 | 51 } |
52 } | |
53 | |
419 | 54 public override int GetHashCode() |
55 { | |
56 int hash = 0; | |
57 | |
58 foreach (UnitCountRequirementData req in requiredTypes) | |
59 { | |
60 hash += req.UnitType.GetHashCode(); | |
61 } | |
62 | |
63 return hash; | |
64 } | |
65 | |
357 | 66 /// <summary> |
67 /// Checks whether the supplied WarFoundryObject can be added to the supplied army. | |
68 /// </summary> | |
69 /// <returns> | |
70 /// A <code>Validation</code> enum to show the result of the validation | |
71 /// </returns> | |
72 /// <param name='wfObject'> | |
73 /// The object that we want to add. This may be involved in the check, or it may not affect the evaluation of the requirement | |
74 /// </param> | |
75 /// <param name='toArmy'> | |
76 /// The army to add the object to. | |
77 /// </param> | |
358
dbe7ccb1e557
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
357
diff
changeset
|
78 public override Validation AllowsAdding(WarFoundryObject wfObject, Army toArmy) |
357 | 79 { |
80 return IsApplicable(wfObject, toArmy) ? CheckAllowsAdding(wfObject, toArmy) : Validation.NotApplicable; | |
81 } | |
82 | |
358
dbe7ccb1e557
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
357
diff
changeset
|
83 protected override bool IsApplicable(Army toArmy) |
357 | 84 { |
85 return false; | |
86 } | |
87 | |
358
dbe7ccb1e557
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
357
diff
changeset
|
88 protected override bool IsApplicable(WarFoundryObject toObject) |
357 | 89 { |
90 bool isApplicable = false; | |
91 UnitType unitType = GetUnitTypeFromObject(toObject); | |
92 | |
93 if (unitType != null) | |
94 { | |
95 isApplicable = IsApplicable(unitType); | |
96 } | |
97 | |
98 return isApplicable; | |
99 } | |
100 | |
101 protected UnitType GetUnitTypeFromObject (WarFoundryObject toObject) | |
102 { | |
103 UnitType unitType = null; | |
104 | |
105 if (toObject is UnitType) | |
106 { | |
107 unitType = (UnitType)toObject; | |
108 } | |
109 else if (toObject is Unit) | |
110 { | |
111 unitType = ((Unit)toObject).UnitType; | |
337
3c4a6403a88c
* Fix capitalisation so that new files are in the namespace
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
112 } |
357 | 113 |
114 return unitType; | |
115 } | |
116 | |
117 private bool IsApplicable (UnitType unitType) | |
118 { | |
119 bool isApplicable = false; | |
120 foreach (UnitCountRequirementData requirement in requiredTypes) | |
121 { | |
122 if (requirement.UnitType.Equals(unitType)) | |
123 { | |
124 isApplicable = true; | |
125 break; | |
126 } | |
127 } | |
128 return isApplicable; | |
129 } | |
130 | |
131 private Validation CheckAllowsAdding(WarFoundryObject wfObject, Army toArmy) | |
132 { | |
133 Validation isValid = Validation.Passed; | |
134 | |
135 foreach (UnitCountRequirementData requirement in requiredTypes) | |
136 { | |
137 if (GetUnitTypeCount(toArmy, requirement.UnitType, wfObject) < requirement.Count) | |
138 { | |
139 isValid = Validation.Failed; | |
140 break; | |
141 } | |
142 } | |
143 | |
144 return isValid; | |
145 } | |
146 | |
147 private int GetUnitTypeCount(Army toArmy, UnitType unitType, WarFoundryObject wfObject) | |
148 { | |
149 return toArmy.GetUnitTypeCount(unitType) + GetCountFromObject(wfObject, unitType); | |
150 } | |
151 | |
152 private int GetCountFromObject(WarFoundryObject wfObject, UnitType limitedType) | |
153 { | |
154 return (limitedType.Equals(wfObject) || (wfObject is Unit && ((Unit)wfObject).UnitType.Equals(limitedType))) ? 1 : 0; | |
337
3c4a6403a88c
* Fix capitalisation so that new files are in the namespace
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
155 } |
357 | 156 |
157 /// <summary> | |
158 /// Adds a requirement for there to be at least minCount of a given UnitType | |
159 /// </summary> | |
160 /// <param name='unitType'> | |
161 /// The unit type to require. | |
162 /// </param> | |
163 /// <param name='minCount'> | |
164 /// The minimum number of that type that must exist. | |
165 /// </param> | |
166 public void AddUnitTypeRequirement(UnitType unitType, int minCount) | |
167 { | |
168 requiredTypes.Add(new UnitCountRequirementData(unitType, minCount)); | |
169 } | |
170 | |
171 /// <summary> | |
172 /// Adds a requirement for there to be one or more of a given UnitType | |
173 /// </summary> | |
174 /// <param name='unitType'> | |
175 /// The unit type to require. | |
176 /// </param> | |
177 public void AddUnitTypeRequirement (UnitType unitType) | |
178 { | |
179 AddUnitTypeRequirement(unitType, 1); | |
180 } | |
181 | |
182 /// <summary> | |
183 /// Checks whether the supplied army is currently valid according to this requirement. | |
184 /// </summary> | |
185 /// <returns> | |
186 /// A <code>Validation</code> enum to show the result of the validation | |
187 /// </returns> | |
188 /// <param name='toValidate'> | |
189 /// The army to validate | |
190 /// </param> | |
358
dbe7ccb1e557
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
357
diff
changeset
|
191 public override Validation ValidatesArmy(Army toValidate) |
357 | 192 { |
193 Validation isValid = Validation.Passed; | |
194 | |
195 foreach (UnitCountRequirementData requirement in requiredTypes) | |
196 { | |
197 if (toValidate.GetUnitTypeCount(requirement.UnitType) < requirement.Count) | |
198 { | |
199 isValid = Validation.Failed; | |
200 break; | |
201 } | |
202 } | |
203 | |
204 return isValid; | |
205 } | |
358
dbe7ccb1e557
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
357
diff
changeset
|
206 |
360
777725613edb
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
359
diff
changeset
|
207 protected string FailureStringPrefix { get; set; } |
777725613edb
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
359
diff
changeset
|
208 |
364
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
209 protected override string GetValidationFailedMessage(Army army) |
358
dbe7ccb1e557
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
357
diff
changeset
|
210 { |
359
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
211 StringBuilder sb = new StringBuilder(); |
360
777725613edb
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
359
diff
changeset
|
212 sb.Append(FailureStringPrefix); |
359
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
213 sb.Append(String.Join("; ", GetFailedRequirements(army).ToArray())); |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
214 sb.Append("."); |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
215 return sb.ToString(); |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
216 } |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
217 |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
218 private List<string> GetFailedRequirements(Army army) |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
219 { |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
220 List<string> failures = new List<string>(); |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
221 |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
222 foreach (UnitCountRequirementData requirement in requiredTypes) |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
223 { |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
224 int unitCount = army.GetUnitTypeCount(requirement.UnitType); |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
225 |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
226 if (unitCount < requirement.Count) |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
227 { |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
228 failures.Add(requirement.Count + " × " + requirement.UnitType.Name + " (have " + unitCount + ")"); |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
229 } |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
230 } |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
231 |
2a9c046be55a
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
358
diff
changeset
|
232 return failures; |
358
dbe7ccb1e557
Re #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
357
diff
changeset
|
233 } |
364
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
234 |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
235 protected override string GetAllowsAddingFailedMessage(UnitType toAdd, Army toArmy) |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
236 { |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
237 StringBuilder sb = new StringBuilder(); |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
238 sb.Append(FailureStringPrefix); |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
239 sb.Append(String.Join("; ", GetFailedAddingRequirements(toAdd, toArmy).ToArray())); |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
240 sb.Append("."); |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
241 return sb.ToString(); |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
242 } |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
243 |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
244 private List<string> GetFailedAddingRequirements(UnitType unitType, Army army) |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
245 { |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
246 List<string> failures = new List<string>(); |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
247 |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
248 foreach (UnitCountRequirementData requirement in requiredTypes) |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
249 { |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
250 int unitCount = GetUnitTypeCount(army, requirement.UnitType, unitType); |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
251 |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
252 if (unitCount < requirement.Count) |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
253 { |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
254 failures.Add(requirement.Count + " × " + requirement.UnitType.Name + " (would have " + unitCount + ")"); |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
255 } |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
256 } |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
257 |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
258 return failures; |
0dd8dbe8afe9
Fixes #345: Add failure message to requirements
IBBoard <dev@ibboard.co.uk>
parents:
360
diff
changeset
|
259 } |
337
3c4a6403a88c
* Fix capitalisation so that new files are in the namespace
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
260 } |
3c4a6403a88c
* Fix capitalisation so that new files are in the namespace
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
261 } |
3c4a6403a88c
* Fix capitalisation so that new files are in the namespace
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
262 |