2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or
5
* (at your option) any later version.
6
* This program is distributed in the hope that it will be useful,
7
* but WITHOUT ANY WARRANTY; without even the implied warranty of
8
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9
* GNU General Public License for more details.
10
* You should have received a copy of the GNU General Public License
11
* along with this program; if not, write to the Free Software
12
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
package games.strategy.triplea.delegate;
17
import static games.strategy.triplea.delegate.BattleStepStrings.*;
18
import static games.strategy.triplea.delegate.GameDataTestUtil.*;
19
import games.strategy.engine.data.Change;
20
import games.strategy.engine.data.ChangeFactory;
21
import games.strategy.engine.data.ChangePerformer;
22
import games.strategy.engine.data.GameData;
23
import games.strategy.engine.data.ITestDelegateBridge;
24
import games.strategy.engine.data.PlayerID;
25
import games.strategy.engine.data.RepairRule;
26
import games.strategy.engine.data.Route;
27
import games.strategy.engine.data.TechnologyFrontier;
28
import games.strategy.engine.data.Territory;
29
import games.strategy.engine.data.Unit;
30
import games.strategy.engine.data.UnitType;
31
import games.strategy.engine.random.ScriptedRandomSource;
32
import games.strategy.net.GUID;
33
import games.strategy.triplea.Constants;
34
import games.strategy.triplea.TripleAUnit;
35
import games.strategy.triplea.attatchments.TechAttachment;
36
import games.strategy.triplea.attatchments.TerritoryAttachment;
37
import games.strategy.triplea.attatchments.UnitAttachment;
38
import games.strategy.triplea.delegate.dataObjects.CasualtyDetails;
39
import games.strategy.triplea.delegate.dataObjects.MoveValidationResult;
40
import games.strategy.triplea.delegate.dataObjects.PlaceableUnits;
41
import games.strategy.triplea.delegate.dataObjects.TechResults;
42
import games.strategy.triplea.player.ITripleaPlayer;
43
import games.strategy.triplea.ui.display.DummyDisplay;
44
import games.strategy.triplea.util.DummyTripleAPlayer;
45
import games.strategy.triplea.xml.LoadGameUtil;
46
import games.strategy.util.IntegerMap;
47
import games.strategy.util.Match;
49
import java.lang.reflect.InvocationHandler;
50
import java.lang.reflect.Method;
51
import java.lang.reflect.Proxy;
52
import java.util.ArrayList;
53
import java.util.Arrays;
54
import java.util.Collection;
55
import java.util.Collections;
56
import java.util.HashMap;
57
import java.util.Iterator;
58
import java.util.List;
61
import junit.framework.TestCase;
64
public class WW2V3_41_Test extends TestCase {
66
private GameData m_data;
69
protected void setUp() throws Exception
71
m_data = LoadGameUtil.loadGame("AA50", "ww2v3_1941.xml");
75
protected void tearDown() throws Exception
81
public void testDefendingTrasnportsAutoKilled()
83
Territory sz13 = m_data.getMap().getTerritory("13 Sea Zone");
84
Territory sz12 = m_data.getMap().getTerritory("12 Sea Zone");
87
PlayerID british = m_data.getPlayerList().getPlayerID("British");
89
MoveDelegate moveDelegate = moveDelegate(m_data);
90
ITestDelegateBridge bridge = getDelegateBridge(british);
91
bridge.setStepName("CombatMove");
92
moveDelegate.start(bridge, m_data);
96
Route sz12To13 = new Route();
97
sz12To13.setStart(sz12);
101
String error = moveDelegate.move(sz12.getUnits().getUnits(), sz12To13);
102
assertEquals(error,null);
105
assertEquals(sz13.getUnits().size(), 3);
109
//the transport was not removed automatically
110
assertEquals(sz13.getUnits().size(), 3);
112
BattleDelegate bd = battleDelegate(m_data);
113
assertFalse(bd.getBattleTracker().getPendingBattleSites(false).isEmpty());
119
public void testUnplacedDie()
121
PlaceDelegate del = placeDelegate(m_data);
122
del.start(getDelegateBridge( british(m_data)), m_data);
124
addTo(british(m_data),
125
transports(m_data).create(1,british(m_data)));
130
assertEquals(1, british(m_data).getUnits().size());
134
public void testPlaceEmpty()
136
PlaceDelegate del = placeDelegate(m_data);
137
del.start(getDelegateBridge( british(m_data)), m_data);
139
addTo(british(m_data),
140
transports(m_data).create(1,british(m_data)));
142
String error = del.placeUnits(Collections.EMPTY_LIST, territory("United Kingdom", m_data));
147
public void testTechTokens()
150
PlayerID germans = m_data.getPlayerList().getPlayerID("Germans");
152
ITestDelegateBridge delegateBridge = getDelegateBridge(germans);
153
delegateBridge.setStepName("germanTech");
154
TechnologyDelegate techDelegate = techDelegate(m_data);
155
techDelegate.start(delegateBridge, m_data);
156
TechnologyFrontier mech = new TechnologyFrontier("",m_data);
157
mech.addAdvance(TechAdvance.MECHANIZED_INFANTRY);
160
new ChangePerformer(m_data).perform(ChangeFactory.changeResourcesChange(germans, m_data.getResourceList().getResource(Constants.TECH_TOKENS), 1));
162
//Check to make sure it was successful
163
int initTokens = germans.getResources().getQuantity("techTokens");
164
assertEquals(1,initTokens);
167
delegateBridge.setRandomSource(new ScriptedRandomSource(new int[]{ 3 }));
168
TechResults roll = techDelegate.rollTech(1, mech, 0);
170
//Check to make sure it failed
171
assertEquals(0, roll.getHits());
172
int midTokens = germans.getResources().getQuantity("techTokens");
173
assertEquals(1,midTokens);
176
//Make a Successful roll
177
delegateBridge.setRandomSource(new ScriptedRandomSource(new int[]{ 5 }));
178
TechResults roll2 = techDelegate.rollTech(1, mech, 0);
180
//Check to make sure it succeeded and all tokens were removed
181
assertEquals(1, roll2.getHits());
182
int finalTokens = germans.getResources().getQuantity("techTokens");
183
assertEquals(0,finalTokens);
186
public void testInfantryLoadOnlyTransports()
188
Territory gibraltar = territory("Gibraltar", m_data);
189
//add a tank to gibralter
190
PlayerID british = british(m_data);
191
addTo(gibraltar, infantry(m_data).create(1,british));
193
MoveDelegate moveDelegate = moveDelegate(m_data);
194
ITestDelegateBridge bridge = getDelegateBridge(british);
195
bridge.setStepName("CombatMove");
196
moveDelegate.start(bridge, m_data);
197
bridge.setRemote(new DummyTripleAPlayer());
199
Territory sz9 = territory("9 Sea Zone", m_data);
200
Territory sz13 = territory("13 Sea Zone", m_data);
201
Route sz9ToSz13 = new Route(
203
territory("12 Sea Zone", m_data),
207
//move the transport to attack, this is suicide but valid
208
move(sz9.getUnits().getMatches(Matches.UnitIsTransport), sz9ToSz13);
212
load(gibraltar.getUnits().getUnits(), new Route(gibraltar, sz13));
216
bridge.setStepName("combat");
218
BattleDelegate battleDelegate = battleDelegate(m_data);
219
battleDelegate.start(bridge, m_data);
221
assertTrue(battleDelegate.getBattles().isEmpty());
225
public void testLoadedTransportAttackKillsLoadedUnits()
227
PlayerID british = british(m_data);
229
MoveDelegate moveDelegate = moveDelegate(m_data);
230
ITestDelegateBridge bridge = getDelegateBridge(british);
231
bridge.setStepName("CombatMove");
232
bridge.setRemote(new DummyTripleAPlayer() {
235
public boolean selectAttackSubs(Territory unitTerritory) {
239
moveDelegate.start(bridge, m_data);
241
Territory sz9 = territory("9 Sea Zone", m_data);
242
Territory sz7 = territory("7 Sea Zone", m_data);
243
Territory uk = territory("United Kingdom", m_data);
245
Route sz9ToSz7 = new Route(
247
territory("8 Sea Zone", m_data),
251
//move the transport to attack, this is suicide but valid
252
List<Unit> transports = sz9.getUnits().getMatches(Matches.UnitIsTransport);
253
move(transports, sz9ToSz7);
256
load(uk.getUnits().getMatches(Matches.UnitIsInfantry), new Route(uk, sz7));
258
moveDelegate(m_data).end();
260
bridge.setStepName("combat");
262
BattleDelegate battleDelegate = battleDelegate(m_data);
263
battleDelegate.start(bridge, m_data);
265
assertEquals(2,new TransportTracker().transporting(transports.get(0)).size());
268
assertValid(battleDelegate.fightBattle(sz7, false));
270
//make sure the infantry die with the transport
271
assertTrue(sz7.getUnits().toString(), sz7.getUnits().getMatches(Matches.unitOwnedBy(british)).isEmpty());
274
public void testCanRetreatIntoEmptyEnemyTerritory()
276
Territory eastPoland = territory("East Poland", m_data);
277
Territory ukraine = territory("Ukraine", m_data);
278
Territory poland = territory("Poland", m_data);
279
//remove all units from east poland
280
removeFrom(eastPoland, eastPoland.getUnits().getUnits());
283
MoveDelegate moveDelegate = moveDelegate(m_data);
284
ITestDelegateBridge delegateBridge = getDelegateBridge(germans(m_data));
285
delegateBridge.setStepName("CombatMove");
286
moveDelegate.start(delegateBridge, m_data);
288
Territory bulgaria = territory("Bulgaria Romania", m_data);
290
//attack from bulgraia
291
move(bulgaria.getUnits().getUnits(), new Route(bulgaria, ukraine));
292
//add an air attack from east poland
293
move(poland.getUnits().getMatches(Matches.UnitIsAir), new Route(poland, eastPoland, ukraine));
295
//we should not be able to retreat to east poland!
296
//that territory is still owned by the enemy
297
MustFightBattle battle = (MustFightBattle)
298
MoveDelegate.getBattleTracker(m_data).getPendingBattle(ukraine, false);
300
assertFalse(battle.getAttackerRetreatTerritories().contains(eastPoland));
303
public void testCanRetreatIntoBlitzedTerritory()
305
Territory eastPoland = territory("East Poland", m_data);
306
Territory ukraine = territory("Ukraine", m_data);
307
Territory poland = territory("Poland", m_data);
308
//remove all units from east poland
309
removeFrom(eastPoland, eastPoland.getUnits().getUnits());
312
MoveDelegate moveDelegate = moveDelegate(m_data);
313
ITestDelegateBridge delegateBridge = getDelegateBridge(germans(m_data));
314
delegateBridge.setStepName("CombatMove");
315
moveDelegate.start(delegateBridge, m_data);
317
Territory bulgaria = territory("Bulgaria Romania", m_data);
319
//attack from bulgraia
320
move(bulgaria.getUnits().getUnits(), new Route(bulgaria, ukraine));
322
move(poland.getUnits().getMatches(Matches.UnitCanBlitz), new Route(poland, eastPoland, ukraine));
324
//we should not be able to retreat to east poland!
325
//that territory was just conquered
326
MustFightBattle battle = (MustFightBattle)
327
MoveDelegate.getBattleTracker(m_data).getPendingBattle(ukraine, false);
329
assertTrue(battle.getAttackerRetreatTerritories().contains(eastPoland));
332
public void testCantBlitzFactoryOrAA()
335
Territory poland = territory("Poland", m_data);
336
Territory eastPoland = territory("East Poland", m_data);
337
Territory ukraine = territory("Ukraine", m_data);
338
//remove all units from east poland
339
removeFrom(eastPoland, eastPoland.getUnits().getUnits());
341
//Add a russian factory
342
addTo(eastPoland, factory(m_data).create(1, russians(m_data)));
344
MoveDelegate moveDelegate = moveDelegate(m_data);
345
ITestDelegateBridge delegateBridge = getDelegateBridge(germans(m_data));
346
delegateBridge.setStepName("CombatMove");
347
moveDelegate.start(delegateBridge, m_data);
350
String errorResults = moveDelegate.move(poland.getUnits().getMatches(Matches.UnitCanBlitz), new Route(poland, eastPoland, ukraine));
351
assertError(errorResults);
357
//remove all units from east poland
358
removeFrom(eastPoland, eastPoland.getUnits().getUnits());
360
//Add a russian factory
361
addTo(eastPoland, aaGun(m_data).create(1, russians(m_data)));
363
moveDelegate = moveDelegate(m_data);
364
delegateBridge = getDelegateBridge(germans(m_data));
365
delegateBridge.setStepName("CombatMove");
366
moveDelegate.start(delegateBridge, m_data);
369
errorResults = moveDelegate.move(poland.getUnits().getMatches(Matches.UnitCanBlitz), new Route(poland, eastPoland, ukraine));
370
assertError(errorResults);
373
public void testMultipleAAInTerritory()
376
Territory poland = territory("Poland", m_data);
377
Territory germany = territory("Germany", m_data);//Add a russian factory
378
addTo(poland, aaGun(m_data).create(1, germans(m_data)));
380
MoveDelegate moveDelegate = moveDelegate(m_data);
381
ITestDelegateBridge delegateBridge = getDelegateBridge(germans(m_data));
382
delegateBridge.setStepName("NonCombatMove");
383
moveDelegate.start(delegateBridge, m_data);
385
int preCount = germany.getUnits().getUnitCount();
389
String errorResults = moveDelegate.move(poland.getUnits().getMatches(Matches.UnitIsAA), new Route(poland, germany));
390
assertValid(errorResults);
391
assertEquals(germany.getUnits().getUnitCount(), preCount +1);
396
Territory finland = territory("Finland", m_data);
397
Territory sz5 = territory("5 Sea Zone", m_data);
398
addTo(finland, aaGun(m_data).create(1, germans(m_data)));
400
moveDelegate = moveDelegate(m_data);
401
delegateBridge = getDelegateBridge(germans(m_data));
402
delegateBridge.setStepName("NonCombatMove");
403
moveDelegate.start(delegateBridge, m_data);
406
errorResults = moveDelegate.move(finland.getUnits().getMatches(Matches.UnitIsAA), new Route(finland, sz5), sz5.getUnits().getMatches(Matches.UnitIsTransport));
407
assertValid(errorResults);
410
errorResults = moveDelegate.move(sz5.getUnits().getMatches(Matches.UnitIsAA), new Route(sz5, germany));
411
assertValid(errorResults);
412
assertEquals(germany.getUnits().getUnitCount(), preCount +2);
417
UnitType aaGun = m_data.getUnitTypeList().getUnitType("aaGun");
418
IntegerMap<UnitType> map = new IntegerMap<UnitType>();
422
PlayerID germans = m_data.getPlayerList().getPlayerID("Germans");
423
PlaceDelegate placeDelegate = placeDelegate(m_data);
424
delegateBridge.setStepName("Place");
425
delegateBridge.setPlayerID(germans);
426
placeDelegate.start(getDelegateBridge( germans(m_data)), m_data);
427
addTo(germans(m_data), aaGun(m_data).create(1,germans(m_data)));
429
errorResults = placeDelegate.placeUnits(getUnits(map, germans), germany);
430
assertValid(errorResults);
431
assertEquals(germany.getUnits().getUnitCount(), preCount +3);
434
public void testMechanizedInfantry()
437
PlayerID germans = m_data.getPlayerList().getPlayerID("Germans");
438
ITestDelegateBridge delegateBridge = getDelegateBridge(germans(m_data));
439
TechTracker.addAdvance(germans, m_data, delegateBridge, TechAdvance.MECHANIZED_INFANTRY);
441
//Set up the move delegate
442
MoveDelegate moveDelegate = moveDelegate(m_data);
443
delegateBridge.setStepName("CombatMove");
444
moveDelegate.start(delegateBridge, m_data);
446
//Set up the territories
447
Territory poland = territory("Poland", m_data);
448
Territory eastPoland = territory("East Poland", m_data);
449
Territory belorussia = territory("Belorussia", m_data);
451
//Set up the unit types
452
UnitType infantryType = m_data.getUnitTypeList().getUnitType("infantry");
454
//Remove all units from east poland
455
removeFrom(eastPoland, eastPoland.getUnits().getUnits());
457
//Get total number of units in territories to start
458
Integer preCountIntPoland = poland.getUnits().size();
459
Integer preCountIntBelorussia = belorussia.getUnits().size();
462
Collection<Unit> moveUnits = poland.getUnits().getUnits(infantryType, 3);
463
moveUnits.addAll(poland.getUnits().getMatches(Matches.UnitCanBlitz));
465
//add a INVALID blitz attack
466
String errorResults = moveDelegate.move(moveUnits, new Route(poland, eastPoland, belorussia));
467
assertError(errorResults);
469
//Fix the number of units
471
moveUnits.addAll(poland.getUnits().getUnits(infantryType, 2));
472
moveUnits.addAll(poland.getUnits().getMatches(Matches.UnitCanBlitz));
474
//add a VALID blitz attack
475
String validResults = moveDelegate.move(moveUnits, new Route(poland, eastPoland, belorussia));
476
assertValid(validResults);
478
//Get number of units in territories after move (adjusted for movement)
479
Integer postCountIntPoland = poland.getUnits().size() +4;
480
Integer postCountIntBelorussia = belorussia.getUnits().size() -4;
482
//Compare the number of units before and after
483
assertEquals(preCountIntPoland, postCountIntPoland);
484
assertEquals(preCountIntBelorussia, postCountIntBelorussia);
488
public void testJetPower()
491
PlayerID germans = m_data.getPlayerList().getPlayerID("Germans");
492
ITestDelegateBridge delegateBridge = getDelegateBridge( germans(m_data));
493
TechTracker.addAdvance(germans, m_data, delegateBridge, TechAdvance.JET_POWER);
495
//Set up the territories
496
Territory poland = territory("Poland", m_data);
497
Territory eastPoland = territory("East Poland", m_data);
499
//Set up the unit types
500
UnitType fighterType = m_data.getUnitTypeList().getUnitType("fighter");
502
delegateBridge.setStepName("germanBattle");
503
while(!m_data.getSequence().getStep().getName().equals("germanBattle")) {
504
m_data.getSequence().next();
507
//With JET_POWER attacking fighter hits on 4 (0 base)
508
List<Unit> germanFighter = (List<Unit>) poland.getUnits().getUnits(fighterType, 1);
509
delegateBridge.setRandomSource(new ScriptedRandomSource(new int[]
511
DiceRoll roll1 = DiceRoll.rollDice(germanFighter, false, germans, delegateBridge, m_data, new MockBattle(eastPoland), "");
512
assertEquals(1, roll1.getHits());
515
//With JET_POWER defending fighter misses on 5 (0 base)
516
delegateBridge.setRandomSource(new ScriptedRandomSource(new int[]
518
DiceRoll roll2 = DiceRoll.rollDice(germanFighter, true, germans, delegateBridge, m_data, new MockBattle(eastPoland), "");
519
assertEquals(0, roll2.getHits());
522
public void testBidPlace()
524
ITestDelegateBridge bridge = getDelegateBridge(british(m_data));
525
bridge.setStepName("placeBid");
526
bidPlaceDelegate(m_data).start(bridge, m_data);
528
//create 20 british infantry
529
addTo(british(m_data), infantry(m_data).create(20, british(m_data)));
531
Territory uk = territory("United Kingdom", m_data);
532
Collection<Unit> units = british(m_data).getUnits().getUnits();
533
PlaceableUnits placeable = bidPlaceDelegate(m_data).getPlaceableUnits(units, uk);
534
assertEquals(20, placeable.getMaxUnits());
535
assertNull(placeable.getErrorMessage());
537
String error = bidPlaceDelegate(m_data).placeUnits(units, uk);
541
public void testFactoryPlace()
544
PlayerID british = m_data.getPlayerList().getPlayerID("British");
545
ITestDelegateBridge delegateBridge = getDelegateBridge( british(m_data));
547
//Set up the territories
548
Territory egypt = territory("Union of South Africa", m_data);
550
//Set up the unit types
551
UnitType factoryType = m_data.getUnitTypeList().getUnitType("factory");
553
//Set up the move delegate
554
PlaceDelegate placeDelegate = placeDelegate(m_data);
555
delegateBridge.setStepName("Place");
556
delegateBridge.setPlayerID(british);
557
placeDelegate.start(delegateBridge, m_data);
560
IntegerMap<UnitType> map = new IntegerMap<UnitType>();
561
map.add(factoryType, 1);
562
addTo(british(m_data), factory(m_data).create(1,british(m_data)));
564
String response = placeDelegate.placeUnits(getUnits(map, british), egypt);
565
assertValid(response);
567
//placeUnits performPlace
568
//get production and unit production values
569
TerritoryAttachment ta = TerritoryAttachment.get(egypt);
570
assertEquals(ta.getUnitProduction(), ta.getProduction());
573
public void testChinesePlacement()
576
* This tests that Chinese can place units in any territory, that they can
577
* place in just conquered territories, and that they can place in territories
578
* with up to 3 Chinese units in them.
581
PlayerID chinese = m_data.getPlayerList().getPlayerID("Chinese");
582
ITestDelegateBridge delegateBridge = getDelegateBridge( chinese(m_data));
583
delegateBridge.setPlayerID(chinese);
584
delegateBridge.setStepName("CombatMove");
586
MoveDelegate moveDelegate = moveDelegate(m_data);
587
moveDelegate.start(delegateBridge, m_data);
588
//Set up the territories
589
Territory yunnan = territory("Yunnan", m_data);
590
Territory kiangsu = territory("Kiangsu", m_data);
591
Territory hupeh = territory("Hupeh", m_data);
593
//Set up the unit types
594
UnitType infantryType = m_data.getUnitTypeList().getUnitType("infantry");
597
removeFrom(kiangsu, kiangsu.getUnits().getUnits());
600
Collection<Unit> moveUnits = hupeh.getUnits().getUnits();
601
String validResults = moveDelegate.move(moveUnits, new Route(hupeh, kiangsu));
602
assertValid(validResults);
605
* Place units in just captured territory
607
PlaceDelegate placeDelegate = placeDelegate(m_data);
608
delegateBridge.setStepName("Place");
609
placeDelegate.start(delegateBridge, m_data);
612
IntegerMap<UnitType> map = new IntegerMap<UnitType>();
613
map.add(infantryType, 3);
614
addTo(chinese(m_data), infantry(m_data).create(1,chinese(m_data)));
615
//Get the number of units before placing
616
int preCount = kiangsu.getUnits().getUnitCount();
619
String response = placeDelegate.placeUnits(getUnits(map, chinese), kiangsu);
620
assertValid(response);
621
assertEquals(preCount+1, kiangsu.getUnits().getUnitCount());
624
* Place units in a territory with up to 3 Chinese units
627
map = new IntegerMap<UnitType>();
628
map.add(infantryType, 3);
629
addTo(chinese(m_data), infantry(m_data).create(3,chinese(m_data)));
630
//Get the number of units before placing
631
preCount = yunnan.getUnits().getUnitCount();
634
response = placeDelegate.placeUnits(getUnits(map, chinese), yunnan);
635
assertValid(response);
637
int midCount = yunnan.getUnits().getUnitCount();
639
//Make sure they were all placed
640
assertEquals(preCount, midCount - 3);
643
* Place units in a territory with 3 or more Chinese units
645
map = new IntegerMap<UnitType>();
646
map.add(infantryType, 1);
647
addTo(chinese(m_data), infantry(m_data).create(1,chinese(m_data)));
648
response = placeDelegate.placeUnits(getUnits(map, chinese), yunnan);
649
assertError(response);
651
//Make sure none were placed
652
int postCount = yunnan.getUnits().getUnitCount();
653
assertEquals(midCount, postCount);
656
public void testPlaceInOccupiedSZ()
659
PlayerID germans = m_data.getPlayerList().getPlayerID("Germans");
660
ITestDelegateBridge delegateBridge = getDelegateBridge( british(m_data));
662
//Clear all units from the SZ and add an enemy unit
663
Territory sz5 = territory("5 Sea Zone", m_data);
664
removeFrom(sz5, sz5.getUnits().getUnits());
665
addTo(sz5, destroyer(m_data).create(1,british(m_data)));
667
//Set up the unit types
668
UnitType transportType = m_data.getUnitTypeList().getUnitType("transport");
670
//Set up the move delegate
671
PlaceDelegate placeDelegate = placeDelegate(m_data);
672
delegateBridge.setStepName("Place");
673
delegateBridge.setPlayerID(germans);
674
placeDelegate.start(delegateBridge, m_data);
677
IntegerMap<UnitType> map = new IntegerMap<UnitType>();
678
map.add(transportType, 1);
679
addTo(germans(m_data), transports(m_data).create(1,germans(m_data)));
681
String response = placeDelegate.placeUnits(getUnits(map, germans), sz5);
682
assertValid(response);
685
public void testMoveUnitsThroughSubs()
687
ITestDelegateBridge bridge = getDelegateBridge(british(m_data));
688
bridge.setStepName("nonCombatMove");
689
moveDelegate(m_data).start(bridge, m_data);
691
Territory sz6 = territory("6 Sea Zone", m_data);
692
Route route = new Route(
694
territory("7 Sea Zone", m_data),
695
territory("8 Sea Zone", m_data)
698
String error = moveDelegate(m_data).move(sz6.getUnits().getUnits(), route);
699
assertNull(error,error);
702
public void testMoveUnitsThroughTransports()
704
ITestDelegateBridge bridge = getDelegateBridge(british(m_data));
705
bridge.setStepName("nonCombatMove");
706
moveDelegate(m_data).start(bridge, m_data);
708
Territory sz12 = territory("12 Sea Zone", m_data);
709
Route route = new Route(
711
territory("13 Sea Zone", m_data),
712
territory("14 Sea Zone", m_data)
715
String error = moveDelegate(m_data).move(sz12.getUnits().getUnits(), route);
716
assertNull(error,error);
719
public void testLoadThroughSubs()
721
ITestDelegateBridge bridge = getDelegateBridge(british(m_data));
722
bridge.setStepName("nonCombatMove");
723
MoveDelegate moveDelegate = moveDelegate(m_data);
724
moveDelegate.start(bridge, m_data);
726
Territory sz8 = territory("8 Sea Zone", m_data);
727
Territory sz7 = territory("7 Sea Zone", m_data);
728
Territory sz6 = territory("6 Sea Zone", m_data);
729
Territory uk = territory("United Kingdom", m_data);
733
addTo(sz8, transports(m_data).create(1,british(m_data)));
735
//move the transport where to the sub is
736
assertValid(moveDelegate.move(sz8.getUnits().getUnits(), new Route(sz8,sz7)));
740
load(uk.getUnits().getMatches(Matches.UnitIsInfantry), new Route(uk, sz7));
742
//move the transport out
743
assertValid(moveDelegate.move(sz7.getUnits().getMatches(Matches.unitOwnedBy(british(m_data))),
744
new Route(sz7,sz6)));
748
public void testAttackUndoAndAttackAgain()
750
MoveDelegate move = moveDelegate(m_data);
751
ITestDelegateBridge bridge = getDelegateBridge(italians(m_data));
752
bridge.setStepName("CombatMove");
753
move.start(bridge, m_data);
755
Territory sz14 = territory("14 Sea Zone", m_data);
756
Territory sz13 = territory("13 Sea Zone", m_data);
757
Territory sz12 = territory("12 Sea Zone", m_data);
759
Route r = new Route(sz14,sz13,sz12);
761
//move the battleship
762
move(sz14.getUnits().getMatches(Matches.UnitIsTwoHit), r );
765
move(sz14.getUnits().getMatches(Matches.UnitIsNotTransport), r );
770
move(sz14.getUnits().getMatches(Matches.UnitIsNotTransport), r );
772
MustFightBattle mfb = (MustFightBattle) MoveDelegate.getBattleTracker(m_data).getPendingBattle(sz12, false);
774
//only 3 attacking units
775
//the battleship and the two cruisers
776
assertEquals(3, mfb.getAttackingUnits().size());
780
public void testAttackSubsOnSubs()
782
String defender = "Germans";
783
String attacker = "British";
785
Territory attacked = territory("31 Sea Zone", m_data);
786
Territory from = territory("32 Sea Zone", m_data);
788
//1 sub attacks 1 sub
789
addTo(from, submarine(m_data).create(1,british(m_data)));
790
addTo(attacked, submarine(m_data).create(1,germans(m_data)));
792
ITestDelegateBridge bridge = getDelegateBridge(british(m_data));
793
bridge.setStepName("CombatMove");
794
moveDelegate(m_data).start(bridge, m_data);
796
move(from.getUnits().getUnits(), new Route(from,attacked));
798
moveDelegate(m_data).end();
800
MustFightBattle battle = (MustFightBattle) MoveDelegate.getBattleTracker(m_data).getPendingBattle(attacked, false);
802
List<String> steps = battle.determineStepStrings(true, bridge);
805
defender + SUBS_SUBMERGE,
806
attacker + SUBS_SUBMERGE,
807
attacker + SUBS_FIRE,
808
defender + SELECT_SUB_CASUALTIES,
809
defender + SUBS_FIRE,
810
attacker + SELECT_SUB_CASUALTIES,
811
REMOVE_SNEAK_ATTACK_CASUALTIES,
813
attacker + ATTACKER_WITHDRAW
818
bridge.setRemote(new DummyTripleAPlayer());
820
//fight, each sub should fire
822
ScriptedRandomSource randomSource = new ScriptedRandomSource(
823
0,0,ScriptedRandomSource.ERROR);
824
bridge.setRandomSource(randomSource);
825
battle.fight(bridge);
827
assertEquals(2, randomSource.getTotalRolled());
828
assertTrue(attacked.getUnits().isEmpty());
832
public void testAttackSubsOnDestroyer()
834
String defender = "Germans";
835
String attacker = "British";
837
Territory attacked = territory("31 Sea Zone", m_data);
838
Territory from = territory("32 Sea Zone", m_data);
840
//1 sub attacks 1 sub and 1 destroyer
841
//defender sneak attacks, not attacker
842
addTo(from, submarine(m_data).create(1,british(m_data)));
843
addTo(attacked, submarine(m_data).create(1,germans(m_data)));
844
addTo(attacked, destroyer(m_data).create(1,germans(m_data)));
846
ITestDelegateBridge bridge = getDelegateBridge(british(m_data));
847
bridge.setStepName("CombatMove");
848
moveDelegate(m_data).start(bridge, m_data);
850
move(from.getUnits().getUnits(), new Route(from,attacked));
852
moveDelegate(m_data).end();
854
MustFightBattle battle = (MustFightBattle) MoveDelegate.getBattleTracker(m_data).getPendingBattle(attacked, false);
856
List<String> steps = battle.determineStepStrings(true, bridge);
859
defender + SUBS_SUBMERGE,
861
defender + SUBS_FIRE,
862
attacker + SELECT_SUB_CASUALTIES,
864
REMOVE_SNEAK_ATTACK_CASUALTIES,
866
attacker + SUBS_FIRE,
867
defender + SELECT_SUB_CASUALTIES,
870
attacker + SELECT_CASUALTIES,
872
attacker + ATTACKER_WITHDRAW
879
bridge.setRemote(new DummyTripleAPlayer());
881
//defending subs sneak attack and hit
882
//no chance to return fire
883
ScriptedRandomSource randomSource = new ScriptedRandomSource(
884
0,ScriptedRandomSource.ERROR);
885
bridge.setRandomSource(randomSource);
886
battle.fight(bridge);
888
assertEquals(1, randomSource.getTotalRolled());
889
assertTrue(attacked.getUnits().getMatches(Matches.unitIsOwnedBy(british(m_data))).isEmpty());
890
assertEquals(2, attacked.getUnits().size());
893
public void testAttackDestroyerAndSubsAgainstSub()
895
String defender = "Germans";
896
String attacker = "British";
898
Territory attacked = territory("31 Sea Zone", m_data);
899
Territory from = territory("32 Sea Zone", m_data);
901
//1 sub and 1 destroyer attack 1 sub
902
//defender sneak attacks, not attacker
903
addTo(from, submarine(m_data).create(1,british(m_data)));
904
addTo(from, destroyer(m_data).create(1,british(m_data)));
905
addTo(attacked, submarine(m_data).create(1,germans(m_data)));
907
ITestDelegateBridge bridge = getDelegateBridge(british(m_data));
908
bridge.setStepName("CombatMove");
909
moveDelegate(m_data).start(bridge, m_data);
911
move(from.getUnits().getUnits(), new Route(from,attacked));
913
moveDelegate(m_data).end();
915
MustFightBattle battle = (MustFightBattle) MoveDelegate.getBattleTracker(m_data).getPendingBattle(attacked, false);
917
List<String> steps = battle.determineStepStrings(true, bridge);
920
attacker + SUBS_SUBMERGE,
922
attacker + SUBS_FIRE,
923
defender + SELECT_SUB_CASUALTIES,
925
REMOVE_SNEAK_ATTACK_CASUALTIES,
927
defender + SUBS_FIRE,
928
attacker + SELECT_SUB_CASUALTIES,
931
defender + SELECT_CASUALTIES,
934
attacker + ATTACKER_WITHDRAW
939
bridge.setRemote(new DummyTripleAPlayer());
941
//attacking subs sneak attack and hit
942
//no chance to return fire
943
ScriptedRandomSource randomSource = new ScriptedRandomSource(
944
0,ScriptedRandomSource.ERROR);
945
bridge.setRandomSource(randomSource);
946
battle.fight(bridge);
948
assertEquals(1, randomSource.getTotalRolled());
949
assertTrue(attacked.getUnits().getMatches(Matches.unitIsOwnedBy(germans(m_data))).isEmpty());
950
assertEquals(2, attacked.getUnits().size());
955
public void testAttackDestroyerAndSubsAgainstSubAndDestroyer()
957
String defender = "Germans";
958
String attacker = "British";
960
Territory attacked = territory("31 Sea Zone", m_data);
961
Territory from = territory("32 Sea Zone", m_data);
963
//1 sub and 1 destroyer attack 1 sub and 1 destroyer
965
addTo(from, submarine(m_data).create(1,british(m_data)));
966
addTo(from, destroyer(m_data).create(1,british(m_data)));
967
addTo(attacked, submarine(m_data).create(1,germans(m_data)));
968
addTo(attacked, destroyer(m_data).create(1,germans(m_data)));
970
ITestDelegateBridge bridge = getDelegateBridge(british(m_data));
971
bridge.setStepName("CombatMove");
972
moveDelegate(m_data).start(bridge, m_data);
974
move(from.getUnits().getUnits(), new Route(from,attacked));
976
moveDelegate(m_data).end();
978
MustFightBattle battle = (MustFightBattle) MoveDelegate.getBattleTracker(m_data).getPendingBattle(attacked, false);
980
List<String> steps = battle.determineStepStrings(true, bridge);
985
attacker + SUBS_FIRE,
986
defender + SELECT_SUB_CASUALTIES,
987
defender + SUBS_FIRE,
988
attacker + SELECT_SUB_CASUALTIES,
991
defender + SELECT_CASUALTIES,
994
attacker + SELECT_CASUALTIES,
997
attacker + ATTACKER_WITHDRAW
1002
bridge.setRemote(new DummyTripleAPlayer(){
1005
public CasualtyDetails selectCasualties(Collection<Unit> selectFrom,
1006
Map<Unit, Collection<Unit>> dependents, int count, String message,
1007
DiceRoll dice, PlayerID hit, List<Unit> defaultCasualties, GUID battleID) {
1009
return new CasualtyDetails(
1010
Arrays.asList(selectFrom.iterator().next()),
1011
Collections.<Unit>emptyList(), false);
1016
//attacking subs sneak attack and hit
1017
//no chance to return fire
1018
ScriptedRandomSource randomSource = new ScriptedRandomSource(
1019
0,0,0,0,ScriptedRandomSource.ERROR);
1020
bridge.setRandomSource(randomSource);
1021
battle.fight(bridge);
1023
assertEquals(4, randomSource.getTotalRolled());
1024
assertEquals(0, attacked.getUnits().size());
1027
public void testLimitBombardtoNumberOfUnloaded()
1029
MoveDelegate move = moveDelegate(m_data);
1030
ITestDelegateBridge bridge = getDelegateBridge(italians(m_data));
1031
bridge.setRemote(new DummyTripleAPlayer()
1034
public boolean selectShoreBombard(Territory unitTerritory) {
1038
bridge.setStepName("CombatMove");
1039
move.start(bridge, m_data);
1041
Territory sz14 = territory("14 Sea Zone", m_data);
1042
Territory sz15 = territory("15 Sea Zone", m_data);
1043
Territory eg = territory("Egypt", m_data);
1044
Territory li = territory("Libya", m_data);
1045
Territory balkans = territory("Balkans", m_data);
1047
//Clear all units from the attacked terr
1048
removeFrom(eg, eg.getUnits().getUnits());
1051
PlayerID british = m_data.getPlayerList().getPlayerID("British");
1052
addTo(eg, infantry(m_data).create(2,british));
1054
//load the transports
1055
load(balkans.getUnits().getMatches(Matches.UnitIsInfantry), new Route(balkans,sz14));
1058
move(sz14.getUnits().getUnits(), new Route(sz14,sz15));
1060
//move troops from Libya
1061
move(li.getUnits().getMatches(Matches.unitOwnedBy(italians(m_data))), new Route(li, eg));
1063
//unload the transports
1064
move(sz15.getUnits().getMatches(Matches.UnitIsLand), new Route(sz15,eg));
1068
//start the battle phase, this will ask the user to bombard
1069
battleDelegate(m_data).start(bridge,m_data);
1071
MustFightBattle mfb = (MustFightBattle) MoveDelegate.getBattleTracker(m_data).getPendingBattle(eg, false);
1074
//only 2 battleships are allowed to bombard
1075
assertEquals(2, mfb.getBombardingUnits().size());
1077
//Show that bombard casualties can return fire
1079
* Note- the 3 & 2 hits below show default behavior of bombarding at attack strength
1081
bridge.setRandomSource(new ScriptedRandomSource(3,2,0,0,6,6,6,6));
1082
battleDelegate(m_data).start(bridge, m_data);
1084
battleDelegate(m_data).fightBattle(eg, false);
1087
assertEquals(2, eg.getUnits().size());
1090
public void testBombardStrengthVariable()
1092
MoveDelegate move = moveDelegate(m_data);
1093
ITestDelegateBridge bridge = getDelegateBridge(italians(m_data));
1094
bridge.setRemote(new DummyTripleAPlayer()
1097
public boolean selectShoreBombard(Territory unitTerritory) {
1101
bridge.setStepName("CombatMove");
1102
move.start(bridge, m_data);
1103
Territory sz14 = territory("14 Sea Zone", m_data);
1104
Territory sz15 = territory("15 Sea Zone", m_data);
1105
Territory eg = territory("Egypt", m_data);
1106
Territory balkans = territory("Balkans", m_data);
1109
removeFrom(eg, eg.getUnits().getUnits());
1110
removeFrom(sz14, sz14.getUnits().getUnits());
1112
//Add 2 inf to the attacked terr
1113
PlayerID british = m_data.getPlayerList().getPlayerID("British");
1114
addTo(eg, infantry(m_data).create(2,british));
1116
//create/load the destroyers and transports
1117
PlayerID italians = m_data.getPlayerList().getPlayerID("Italians");
1118
addTo(sz14, transports(m_data).create(1,italians));
1119
addTo(sz14, destroyer(m_data).create(2,italians));
1121
//load the transports
1122
load(balkans.getUnits().getMatches(Matches.UnitIsInfantry), new Route(balkans,sz14));
1125
move(sz14.getUnits().getUnits(), new Route(sz14,sz15));
1127
//unload the transports
1128
move(sz15.getUnits().getMatches(Matches.UnitIsLand), new Route(sz15,eg));
1131
//Set the tech for DDs bombard
1132
TechAttachment.get(italians).setDestroyerBombard("true");
1134
//Set the bombard strength for the DDs
1135
Collection<Unit> dds = Match.getMatches(sz15.getUnits().getUnits(), Matches.UnitIsDestroyer);
1136
Iterator<Unit> ddIter= dds.iterator();
1137
while(ddIter.hasNext())
1139
Unit unit = ddIter.next();
1140
UnitAttachment ua = UnitAttachment.get(unit.getType());
1143
//start the battle phase, this will ask the user to bombard
1144
battleDelegate(m_data).start(bridge,m_data);
1146
MustFightBattle mfb = (MustFightBattle) MoveDelegate.getBattleTracker(m_data).getPendingBattle(eg, false);
1148
//Show that bombard casualties can return fire
1149
//destroyer bombard hit/miss on rolls of 4 & 3
1152
bridge.setRandomSource(new ScriptedRandomSource(3,2,6,6,1,1));
1154
battleDelegate(m_data).start(bridge, m_data);
1155
battleDelegate(m_data).fightBattle(eg, false);
1157
//1 defending inf remaining
1158
assertEquals(1, eg.getUnits().size());
1161
public void testAmphAttackUndoAndAttackAgainBombard()
1163
MoveDelegate move = moveDelegate(m_data);
1164
ITestDelegateBridge bridge = getDelegateBridge(italians(m_data));
1165
bridge.setRemote(new DummyTripleAPlayer()
1168
public boolean selectShoreBombard(Territory unitTerritory) {
1172
bridge.setStepName("CombatMove");
1173
move.start(bridge, m_data);
1175
Territory sz14 = territory("14 Sea Zone", m_data);
1176
Territory sz15 = territory("15 Sea Zone", m_data);
1177
Territory eg = territory("Egypt", m_data);
1178
Territory li = territory("Libya", m_data);
1179
Territory balkans = territory("Balkans", m_data);
1181
//load the transports
1182
load(balkans.getUnits().getMatches(Matches.UnitIsInfantry), new Route(balkans,sz14));
1185
move(sz14.getUnits().getUnits(), new Route(sz14,sz15));
1187
//move troops from Libya
1188
move(li.getUnits().getMatches(Matches.unitOwnedBy(italians(m_data))), new Route(li, eg));
1190
//unload the transports
1191
move(sz15.getUnits().getMatches(Matches.UnitIsLand), new Route(sz15,eg));
1193
//undo amphibious landing
1194
move.undoMove(move.getMovesMade().size() -1);
1197
move(sz15.getUnits().getMatches(Matches.UnitIsLand), new Route(sz15,eg) );
1201
//start the battle phase, this will ask the user to bombard
1202
battleDelegate(m_data).start(bridge,m_data);
1204
MustFightBattle mfb = (MustFightBattle) MoveDelegate.getBattleTracker(m_data).getPendingBattle(eg, false);
1207
//only 2 battleships are allowed to bombard
1208
assertEquals(2, mfb.getBombardingUnits().size());
1211
//TODO this test needs work kev
1212
public void testAAFireWithRadar()
1214
PlayerID russians = russians(m_data);
1215
PlayerID germans = germans(m_data);
1216
TechAttachment.get(russians).setAARadar("true");
1218
MoveDelegate move = moveDelegate(m_data);
1219
ITestDelegateBridge bridge = getDelegateBridge(germans);
1220
bridge.setStepName("CombatMove");
1222
Territory poland = territory("Poland", m_data);
1223
Territory russia = territory("Russia", m_data);
1225
//Add bomber to Poland and attack
1226
addTo(poland, bomber(m_data).create(1,germans));
1228
//The game will ask us if we want to move bomb, say yes.
1229
InvocationHandler handler = new InvocationHandler()
1231
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
1237
ITripleaPlayer player = (ITripleaPlayer) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[] {ITripleaPlayer.class}, handler );
1238
bridge.setRemote(player);
1240
//Perform the combat movement
1241
move.start(bridge, m_data);
1242
move(poland.getUnits().getMatches(Matches.UnitIsStrategicBomber), m_data.getMap().getRoute(poland, russia));
1246
//start the battle phase
1247
battleDelegate(m_data).start(bridge,m_data);
1248
//aa guns rolls 1, hits
1249
bridge.setRandomSource(new ScriptedRandomSource( new int[] {0, ScriptedRandomSource.ERROR} ));
1250
StrategicBombingRaidBattle battle = (StrategicBombingRaidBattle) battleDelegate(m_data).getBattleTracker().getPendingBattle(russia, true);
1252
//aa guns rolls 1, hits
1253
//bridge.setRandomSource(new ScriptedRandomSource( new int[] {0, 6} ));
1255
int PUsBeforeRaid = russians.getResources().getQuantity(m_data.getResourceList().getResource(Constants.PUS));
1257
battle.fight(bridge);
1259
int PUsAfterRaid = russians.getResources().getQuantity(m_data.getResourceList().getResource(Constants.PUS));
1261
//Changed to match StrategicBombingRaidBattle changes
1262
assertEquals(PUsBeforeRaid , PUsAfterRaid);
1265
public void testCarrierWithAlliedPlanes()
1267
Territory sz8 = territory("8 Sea Zone", m_data);
1268
Territory sz1 = territory("1 Sea Zone", m_data);
1270
addTo(sz8, carrier(m_data).create(1, british(m_data)));
1271
addTo(sz8, fighter(m_data).create(1, americans(m_data)));
1273
Route route = new Route(sz8, sz1);
1276
ITestDelegateBridge bridge = getDelegateBridge(british(m_data));
1277
bridge.setStepName("CombatMove");
1278
moveDelegate(m_data).start(bridge, m_data);
1280
move(sz8.getUnits().getUnits(), route);
1282
//make sure the fighter moved
1283
assertTrue(sz8.getUnits().getUnits().isEmpty());
1284
assertFalse(sz1.getUnits().getMatches(Matches.UnitIsAir).isEmpty());
1287
public void testAirCanLandWithAlliedFighters()
1289
//germany owns madagascar, with 2 fighters in it
1290
//also 1 carrier, and 1 allied fighter in sz 40
1291
//the fighters should not be able to move from madagascar
1292
//to sz 40, since with the allied fighter, their is no room
1295
Territory madagascar = territory("French Madagascar", m_data);
1296
PlayerID germans = germans(m_data);
1297
madagascar.setOwner(germans);
1299
Territory sz40 = territory("40 Sea Zone", m_data);
1300
addTo(sz40, carrier(m_data).create(1, germans));
1301
addTo(sz40, fighter(m_data).create(1, italians(m_data)));
1302
addTo(madagascar, fighter(m_data).create(2, germans));
1304
Route route = m_data.getMap().getRoute(madagascar, sz40);
1306
ITestDelegateBridge bridge = getDelegateBridge(germans);
1307
bridge.setStepName("CombatMove");
1308
moveDelegate(m_data).start(bridge, m_data);
1309
//don't allow kamikaze
1310
bridge.setRemote(new DummyTripleAPlayer() {
1312
public boolean confirmMoveKamikaze() {
1317
String error = moveDelegate(m_data).move(madagascar.getUnits().getUnits(), route);
1321
public void testMechInfSimple()
1323
PlayerID germans = germans(m_data);
1324
Territory france = territory("France", m_data);
1325
Territory germany = territory("Germany", m_data);
1326
Territory poland = territory("Poland", m_data);
1328
TechAttachment.get(germans).setMechanizedInfantry("true");
1330
ITestDelegateBridge bridge = getDelegateBridge(germans);
1331
bridge.setStepName("CombatMove");
1333
moveDelegate(germans.getData()).start(bridge, germans.getData());
1335
Route r = new Route(france,germany,poland);
1336
List<Unit> toMove = new ArrayList<Unit>();
1338
//1 armour and 1 infantry
1339
toMove.addAll(france.getUnits().getMatches(Matches.UnitCanBlitz));
1340
toMove.add(france.getUnits().getMatches(Matches.UnitIsInfantry).get(0));
1345
public void testMechInfUnitAlreadyMovedSimple()
1347
PlayerID germans = germans(m_data);
1348
Territory france = territory("France", m_data);
1349
Territory germany = territory("Germany", m_data);
1351
TechAttachment.get(germans).setMechanizedInfantry("true");
1353
ITestDelegateBridge bridge = getDelegateBridge(germans);
1354
bridge.setStepName("CombatMove");
1355
moveDelegate(germans.getData()).start(bridge, germans.getData());
1357
//get rid of the infantry in france
1358
removeFrom(france, france.getUnits().getMatches(Matches.UnitIsInfantry));
1360
//move an infantry from germany to france
1361
move(germany.getUnits().getMatches(Matches.UnitIsInfantry).subList(0, 1), new Route(germany,france));
1363
//try to move all the units in france, the infantry should not be able to move
1364
Route r = new Route(france,germany);
1365
String error = moveDelegate(m_data).move(france.getUnits().getUnits(), r);
1367
assertFalse(error == null);
1370
public void testParatroopsWalkOnWater()
1372
PlayerID germans = germans(m_data);
1373
Territory france = territory("France", m_data);
1374
TechAttachment.get(germans).setParatroopers("true");
1376
Route r = m_data.getMap().getRoute(france, territory("7 Sea Zone", m_data));
1377
Collection<Unit> paratroopers = france.getUnits().getMatches(Matches.UnitIsAirTransportable);
1378
assertFalse(paratroopers.isEmpty());
1380
MoveValidationResult results = MoveValidator.validateMove(
1382
r, germans, Collections.<Unit>emptyList(), false, null, m_data);
1383
assertFalse(results.isMoveValid());
1386
public void testBomberWithTankOverWaterParatroopers()
1389
PlayerID germans = germans(m_data);
1390
TechAttachment.get(germans).setParatroopers("true");
1392
Territory sz5 = territory("5 Sea Zone", m_data);
1393
Territory germany = territory("Germany", m_data);
1394
Territory karelia = territory("Karelia S.S.R.", m_data);
1396
addTo(germany, armour(m_data).create(1, germans));
1398
Route r = new Route(germany, sz5, karelia);
1400
Collection<Unit> toMove = germany.getUnits().getMatches(Matches.UnitCanBlitz);
1401
toMove.addAll(germany.getUnits().getMatches(Matches.UnitIsStrategicBomber));
1402
assertEquals(2, toMove.size());
1404
MoveValidationResult results = MoveValidator.validateMove(
1406
r, germans, Collections.<Unit>emptyList(), false, null, m_data);
1407
assertFalse(results.isMoveValid());
1410
public void testBomberTankOverWater()
1412
//can't transport a tank over water using a bomber
1414
PlayerID germans = germans(m_data);
1415
Territory sz5 = territory("5 Sea Zone", m_data);
1416
Territory germany = territory("Germany", m_data);
1417
Territory karelia = territory("Karelia S.S.R.", m_data);
1419
addTo(germany, armour(m_data).create(1, germans));
1423
Route r = new Route(germany, sz5, karelia);
1425
Collection<Unit> toMove = germany.getUnits().getMatches(Matches.UnitCanBlitz);
1426
toMove.addAll(germany.getUnits().getMatches(Matches.UnitIsStrategicBomber));
1427
assertEquals(2, toMove.size());
1429
MoveValidationResult results = MoveValidator.validateMove(
1431
r, germans, Collections.<Unit>emptyList(), false, null, m_data);
1432
assertFalse(results.isMoveValid());
1436
public void testMoveParatroopersAsNonPartroops()
1438
//move a bomber and a paratrooper
1439
//one step, but as a normal movement
1441
PlayerID germans = germans(m_data);
1442
Territory germany = territory("Germany", m_data);
1443
Territory nwe = territory("Northwestern Europe", m_data);
1445
ITestDelegateBridge bridge = getDelegateBridge(germans);
1446
bridge.setStepName("CombatMove");
1447
moveDelegate(m_data).start(bridge, m_data);
1449
TechAttachment.get(germans).setParatroopers("true");
1451
List<Unit> paratrooper = germany.getUnits().getMatches(Matches.UnitIsAirTransportable);
1452
paratrooper = paratrooper.subList(0,1);
1453
List<Unit> bomberAndParatroop = new ArrayList<Unit>(paratrooper);
1454
bomberAndParatroop.addAll(germany.getUnits().getMatches(Matches.UnitIsAirTransport));
1456
//move to nwe, this is a valid move, and it not a partroop move
1457
move(bomberAndParatroop, new Route(germany, nwe));
1460
public void testCantMoveParatroopersThatMovedPreviously()
1462
//make sure infantry can't be moved as paratroopers after moving
1464
PlayerID germans = germans(m_data);
1465
Territory germany = territory("Germany", m_data);
1466
Territory nwe = territory("Northwestern Europe", m_data);
1467
Territory poland = territory("Poland", m_data);
1468
Territory eastPoland = territory("East Poland", m_data);
1470
ITestDelegateBridge bridge = getDelegateBridge(germans);
1471
bridge.setStepName("CombatMove");
1472
moveDelegate(m_data).start(bridge, m_data);
1474
TechAttachment.get(germans).setParatroopers("true");
1476
List<Unit> paratrooper = nwe.getUnits().getMatches(Matches.UnitIsAirTransportable);
1478
move(paratrooper, new Route(nwe,germany));
1480
List<Unit> bomberAndParatroop = new ArrayList<Unit>(paratrooper);
1481
bomberAndParatroop.addAll(germany.getUnits().getMatches(Matches.UnitIsAirTransport));
1483
//move the units to east poland
1484
String error = moveDelegate(m_data).move(bomberAndParatroop, new Route(germany, poland, eastPoland));
1488
public void testCantTransportParatroopersWithBombersThatMovedPreviously()
1490
//make sure bombers can't move then pick up paratroopers
1492
PlayerID germans = germans(m_data);
1493
Territory germany = territory("Germany", m_data);
1494
Territory bulgaria = territory("Bulgaria Romania", m_data);
1495
Territory poland = territory("Poland", m_data);
1496
Territory ukraine = territory("Ukraine", m_data);
1498
ITestDelegateBridge bridge = getDelegateBridge(germans);
1499
bridge.setStepName("CombatMove");
1500
moveDelegate(m_data).start(bridge, m_data);
1502
TechAttachment.get(germans).setParatroopers("true");
1504
//Move the bomber first
1505
List<Unit> bomber = germany.getUnits().getMatches(Matches.UnitIsAirTransport);
1506
move(bomber, new Route(germany,poland));
1508
//Pick up a paratrooper
1509
List<Unit> bomberAndParatroop = new ArrayList<Unit>(bomber);
1510
bomberAndParatroop.addAll(poland.getUnits().getUnits(m_data.getUnitTypeList().getUnitType("infantry"), 1));
1513
String error = moveDelegate(m_data).move(bomberAndParatroop, new Route(poland, bulgaria, ukraine));
1517
public void testMoveOneParatrooperPerBomber()
1519
//make sure only 1 paratroop per bomber can be moved
1521
PlayerID germans = germans(m_data);
1522
Territory germany = territory("Germany", m_data);
1523
Territory nwe = territory("Northwestern Europe", m_data);
1524
Territory poland = territory("Poland", m_data);
1525
Territory eastPoland = territory("East Poland", m_data);
1527
ITestDelegateBridge bridge = getDelegateBridge(germans);
1528
bridge.setStepName("CombatMove");
1529
moveDelegate(m_data).start(bridge, m_data);
1531
TechAttachment.get(germans).setParatroopers("true");
1533
List<Unit> bomberAndParatroop = new ArrayList<Unit>();
1534
bomberAndParatroop.addAll(germany.getUnits().getMatches(Matches.UnitIsAirTransport));
1536
bomberAndParatroop.addAll(germany.getUnits().getUnits(m_data.getUnitTypeList().getUnitType("infantry"), 2));
1538
//move the units to east poland
1539
String error = moveDelegate(m_data).move(bomberAndParatroop, new Route(germany, poland, eastPoland));
1544
public void testParatroopersMoveTwice()
1546
//After a battle move to put a bomber + infantry (paratroop) in a first enemy
1547
//territory, you can make a new move (in the same battle move round) to put
1548
//bomber+ infantry in a more internal enemy territory.
1549
PlayerID germans = germans(m_data);
1550
Territory germany = territory("Germany", m_data);
1551
Territory poland = territory("Poland", m_data);
1552
Territory eastPoland = territory("East Poland", m_data);
1553
Territory beloRussia = territory("Belorussia", m_data);
1555
ITestDelegateBridge bridge = getDelegateBridge(germans);
1556
bridge.setStepName("CombatMove");
1557
moveDelegate(m_data).start(bridge, m_data);
1559
TechAttachment.get(germans).setParatroopers("true");
1561
List<Unit> paratroopers = germany.getUnits().getMatches(Matches.UnitIsAirTransportable);
1562
paratroopers = paratroopers.subList(0, 1);
1563
List<Unit> bomberAndParatroop = new ArrayList<Unit>(paratroopers);
1564
bomberAndParatroop.addAll(germany.getUnits().getMatches(Matches.UnitIsAirTransport));
1566
Route route = new Route(germany, poland, eastPoland);
1567
List<Unit> airTransports = germany.getUnits().getMatches(Matches.UnitIsAirTransport);
1568
TransportTracker tracker = new TransportTracker();
1569
for(Unit airTransport:airTransports)
1571
for(Unit unit : paratroopers)
1573
Change change = tracker.loadTransportChange((TripleAUnit)airTransport, unit, germans);
1574
bridge.addChange(change);
1578
//move the units to east poland
1579
String error = moveDelegate(m_data).move(bomberAndParatroop, route); //airTransports
1582
//try to move them further, this should fail
1583
error = moveDelegate(m_data).move(bomberAndParatroop, new Route(eastPoland, beloRussia));
1588
public void testParatroopersFlyOverBlitzedTerritory()
1590
//We should be able to blitz a territory, then fly over it with paratroops to battle.
1591
PlayerID germans = germans(m_data);
1592
Territory germany = territory("Germany", m_data);
1593
Territory poland = territory("Poland", m_data);
1594
Territory eastPoland = territory("East Poland", m_data);
1595
Territory beloRussia = territory("Belorussia", m_data);
1598
removeFrom(eastPoland, eastPoland.getUnits().getUnits());
1601
ITestDelegateBridge bridge = getDelegateBridge(germans);
1602
bridge.setStepName("CombatMove");
1603
moveDelegate(m_data).start(bridge, m_data);
1604
TechAttachment.get(germans).setParatroopers("true");
1606
List<Unit> paratrooper = germany.getUnits().getMatches(Matches.UnitIsAirTransportable);
1607
paratrooper = paratrooper.subList(0, 1);
1608
List<Unit> bomberAndParatroop = new ArrayList<Unit>(paratrooper);
1609
bomberAndParatroop.addAll(germany.getUnits().getMatches(Matches.UnitIsAirTransport));
1611
List<Unit> tanks = poland.getUnits().getMatches(Matches.UnitCanBlitz);
1612
move(tanks, new Route(poland, eastPoland, beloRussia));
1614
TransportTracker tracker = new TransportTracker();
1615
List<Unit> airTransports = Match.getMatches(bomberAndParatroop, Matches.UnitIsAirTransport);
1616
for(Unit airTransport : airTransports)
1618
for(Unit unit : paratrooper)
1620
Change change = tracker.loadTransportChange((TripleAUnit)airTransport, unit, germans);
1621
bridge.addChange(change);
1626
//Verify paratroops can overfly blitzed territory
1627
String error = moveDelegate(m_data).move(bomberAndParatroop, new Route(germany, poland, eastPoland, beloRussia));
1631
public void testAmphibAttackWithPlanesOnlyAskRetreatOnce()
1633
PlayerID germans = germans(m_data);
1634
ITestDelegateBridge bridge = getDelegateBridge(germans);
1635
bridge.setStepName("CombatMove");
1636
moveDelegate(m_data).start(bridge, m_data);
1638
Territory france = territory("France", m_data);
1639
Territory egypt = territory("Egypt", m_data);
1640
Territory balkans = territory("Balkans", m_data);
1641
Territory libya = territory("Libya", m_data);
1642
Territory germany = territory("Germany", m_data);
1643
Territory sz13 = territory("13 Sea Zone", m_data);
1644
Territory sz14 = territory("14 Sea Zone", m_data);
1645
Territory sz15 = territory("15 Sea Zone", m_data);
1647
bridge.setRemote(new DummyTripleAPlayer() {
1649
public Territory retreatQuery(GUID battleID, boolean submerge,
1650
Collection<Territory> possibleTerritories,
1652
assertFalse(message.contains(MustFightBattle.RETREAT_PLANES));
1657
bridge.setDisplay(new DummyDisplay() {
1660
public void listBattleSteps(GUID battleID, List<String> steps) {
1661
for(String s : steps) {
1662
assertFalse(s.contains(BattleStepStrings.PLANES_WITHDRAW));
1666
//move units for amphib assault
1667
load(france.getUnits().getMatches(Matches.UnitIsInfantry),
1668
new Route(france, sz13));
1669
move(sz13.getUnits().getUnits(), new Route(sz13,sz14,sz15));
1670
move(sz15.getUnits().getMatches(Matches.UnitIsInfantry), new Route(sz15, egypt));
1673
load(libya.getUnits().getMatches(Matches.UnitIsArtillery),
1674
new Route(libya, egypt));
1677
move(germany.getUnits().getMatches(Matches.UnitIsStrategicBomber), new Route(germany, balkans, sz14, sz15, egypt));
1680
moveDelegate(m_data).end();
1682
bridge.setStepName("Combat");
1684
//cook the dice so that all miss first round,all hit second round
1685
bridge.setRandomSource(new ScriptedRandomSource(5,5,5,5,5,5,5,5,5,1,1,1,1,1,1,1,1,1));
1686
battleDelegate(m_data).start(bridge, m_data);
1688
battleDelegate(m_data).fightBattle(egypt, false);
1693
public void testDefencelessTransportsDie()
1695
PlayerID british = british(m_data);
1697
ITestDelegateBridge bridge = getDelegateBridge(british);
1698
bridge.setStepName("CombatMove");
1699
moveDelegate(m_data).start(bridge, m_data);
1701
Territory uk = territory("United Kingdom", m_data);
1702
Territory sz5 = territory("5 Sea Zone", m_data);
1705
removeFrom(sz5, sz5.getUnits().getMatches(Matches.UnitIsSub));
1707
bridge.setRemote(new DummyTripleAPlayer() {
1709
public Territory retreatQuery(GUID battleID, boolean submerge,
1710
Collection<Territory> possibleTerritories,
1712
//we should not be asked to retreat
1713
throw new IllegalStateException("Should not be asked to retreat:" + message);
1717
move(uk.getUnits().getMatches(Matches.UnitIsAir), m_data.getMap().getRoute(uk, sz5) );
1719
//move units for amphib assault
1720
moveDelegate(m_data).end();
1722
bridge.setStepName("Combat");
1724
//cook the dice so that 1 british fighters hits, and nothing else
1725
//this will leave 1 transport alone in the sea zone
1726
bridge.setRandomSource(new ScriptedRandomSource(1,5,5,5,5,5,5,5,5));
1727
battleDelegate(m_data).start(bridge, m_data);
1729
battleDelegate(m_data).fightBattle(sz5, false);
1731
//make sure the transports died
1732
assertTrue(sz5.getUnits().getMatches(Matches.unitIsOwnedBy(germans(m_data))).isEmpty());
1737
public void testFighterLandsWhereCarrierCanBePlaced()
1739
PlayerID germans = germans(m_data);
1741
//germans have 1 carrier to place
1742
addTo(germans, carrier(m_data).create(1, germans));
1744
//start the move phase
1745
ITestDelegateBridge bridge = getDelegateBridge(germans);
1746
bridge.setStepName("CombatMove");
1747
moveDelegate(m_data).start(bridge, m_data);
1749
bridge.setRemote(new DummyTripleAPlayer(){
1752
public boolean confirmMoveHariKari() {
1756
//the fighter should be able to move and hover in the sea zone
1757
//the fighter has no movement left
1758
Territory neEurope = territory("Northwestern Europe", m_data);
1759
Route route = new Route(
1761
territory("Germany", m_data),
1762
territory("Poland", m_data),
1763
territory("Baltic States", m_data),
1764
territory("5 Sea Zone", m_data)
1768
//the fighter should be able to move, and hover in the sea zone until the carrier is placed
1769
move(neEurope.getUnits().getMatches(Matches.UnitIsAir), route);
1773
public void testFighterCantHoverWithNoCarrierToPlace()
1776
//start the move phase
1777
ITestDelegateBridge bridge = getDelegateBridge(germans(m_data));
1778
bridge.setStepName("CombatMove");
1779
moveDelegate(m_data).start(bridge, m_data);
1781
bridge.setRemote(new DummyTripleAPlayer(){
1784
public boolean confirmMoveHariKari() {
1788
//the fighter should not be able to move and hover in the sea zone
1789
//since their are no carriers to place
1790
//the fighter has no movement left
1791
Territory neEurope = territory("Northwestern Europe", m_data);
1792
Route route = new Route(
1794
territory("Germany", m_data),
1795
territory("Poland", m_data),
1796
territory("Baltic States", m_data),
1797
territory("5 Sea Zone", m_data)
1800
String error = moveDelegate(m_data).move(neEurope.getUnits().getMatches(Matches.UnitIsAir), route);
1801
assertNotNull(error);
1805
public void testRepair()
1807
Territory germany = territory("Germany", m_data);
1808
Unit factory = germany.getUnits().getMatches(Matches.UnitIsFactory).get(0);
1809
PurchaseDelegate del = purchaseDelegate(m_data);
1810
del.start(getDelegateBridge(germans(m_data)), m_data);
1813
PlayerID germans = m_data.getPlayerList().getPlayerID("Germans");
1814
int initPUs = germans.getResources().getQuantity("PUs");
1817
IntegerMap<Unit> startHits = new IntegerMap<Unit>();
1818
startHits.put(factory, 1);
1819
new ChangePerformer(m_data).perform(ChangeFactory.unitsHit(startHits));
1820
new ChangePerformer(m_data).perform(ChangeFactory.attachmentPropertyChange(TerritoryAttachment.get(germany), "9", "unitProduction"));
1822
assertEquals(factory.getHits(), 1);
1824
RepairRule repair = germans(m_data).getRepairFrontier().getRules().get(0);
1825
IntegerMap<RepairRule> repairs = new IntegerMap<RepairRule>();
1826
repairs.put(repair, 1);
1827
String error = del.purchaseRepair(Collections.singletonMap(Match.getMatches(germany.getUnits().getUnits(), Matches.UnitIsFactoryOrCanBeDamaged).iterator().next(), repairs));
1830
assertEquals(factory.getHits(), 0);
1833
int midPUs = germans.getResources().getQuantity("PUs");
1834
assertEquals(initPUs, midPUs + 1);
1837
* INCREASED_FACTORY_PRODUCTION repairs
1839
//Set up INCREASED_FACTORY_PRODUCTION
1840
ITestDelegateBridge delegateBridge = getDelegateBridge(germans(m_data));
1841
TechTracker.addAdvance(germans, m_data, delegateBridge, TechAdvance.INCREASED_FACTORY_PRODUCTION);
1844
startHits = new IntegerMap<Unit>();
1845
startHits.put(factory, 2);
1846
new ChangePerformer(m_data).perform(ChangeFactory.unitsHit(startHits));
1847
new ChangePerformer(m_data).perform(ChangeFactory.attachmentPropertyChange(TerritoryAttachment.get(germany), "8", "unitProduction"));
1849
assertEquals(factory.getHits(), 2);
1851
repair = germans(m_data).getRepairFrontier().getRules().get(0);
1852
repairs = new IntegerMap<RepairRule>();
1853
repairs.put(repair, 2);
1854
error = del.purchaseRepair(Collections.singletonMap(Match.getMatches(germany.getUnits().getUnits(), Matches.UnitIsFactoryOrCanBeDamaged).iterator().next(), repairs));
1857
assertEquals(factory.getHits(), 0);
1860
int finalPUs = germans.getResources().getQuantity("PUs");
1861
assertEquals(midPUs, finalPUs + 1);
1865
public void testRepairMoreThanDamaged()
1867
Territory germany = territory("Germany", m_data);
1868
Unit factory = germany.getUnits().getMatches(Matches.UnitIsFactory).get(0);
1869
PurchaseDelegate del = purchaseDelegate(m_data);
1870
del.start(getDelegateBridge(germans(m_data)), m_data);
1873
IntegerMap<Unit> startHits = new IntegerMap<Unit>();
1874
startHits.put(factory, 1);
1875
new ChangePerformer(m_data).perform(ChangeFactory.unitsHit(startHits));
1876
new ChangePerformer(m_data).perform(ChangeFactory.attachmentPropertyChange(TerritoryAttachment.get(germany), "9", "unitProduction"));
1878
assertEquals(factory.getHits(), 1);
1880
RepairRule repair = germans(m_data).getRepairFrontier().getRules().get(0);
1881
IntegerMap<RepairRule> repairs = new IntegerMap<RepairRule>();
1882
//we have 1 damaged marker, but trying to repair 2
1883
repairs.put(repair, 2);
1884
String error = del.purchaseRepair(Collections.singletonMap(Match.getMatches(germany.getUnits().getUnits(), Matches.UnitIsFactoryOrCanBeDamaged).iterator().next(), repairs));
1888
public void testOccupiedTerrOfAttachment()
1891
PlayerID british = m_data.getPlayerList().getPlayerID("British");
1892
ITestDelegateBridge delegateBridge = getDelegateBridge(british(m_data));
1894
//Set up the move delegate
1895
MoveDelegate moveDelegate = moveDelegate(m_data);
1896
delegateBridge.setStepName("CombatMove");
1897
moveDelegate.start(delegateBridge, m_data);
1899
//Set up the territories
1900
Territory hupeh = territory("Hupeh", m_data);
1901
Territory kiangsu = territory("Kiangsu", m_data);
1904
removeFrom(kiangsu, kiangsu.getUnits().getUnits());
1905
removeFrom(hupeh, hupeh.getUnits().getUnits());
1907
//Set up the unit types
1908
addTo(hupeh, infantry(m_data).create(1,british));
1911
Collection<Unit> moveUnits = hupeh.getUnits().getUnits();
1913
//Get Owner prior to battle
1914
String preOwner = kiangsu.getOwner().getName();
1915
assertEquals(preOwner, "Japanese");
1917
//add a VALID attack
1918
String validResults = moveDelegate.move(moveUnits, new Route(hupeh, kiangsu));
1919
assertValid(validResults);
1921
//Ensure owner after attack doesn't match attacker
1922
String postOwner = kiangsu.getOwner().getName();
1923
assertNotSame(postOwner, "British");
1925
//Check that original owner is now owner
1926
assertEquals(postOwner, "Chinese");
1929
public void testOccupiedTerrOfAttachmentWithCapital()
1932
PlayerID british = m_data.getPlayerList().getPlayerID("British");
1933
ITestDelegateBridge delegateBridge = getDelegateBridge(british(m_data));
1935
//Set up the move delegate
1936
MoveDelegate moveDelegate = moveDelegate(m_data);
1937
delegateBridge.setStepName("CombatMove");
1938
moveDelegate.start(delegateBridge, m_data);
1940
//Set up the territories
1941
Territory hupeh = territory("Hupeh", m_data);
1942
Territory kiangsu = territory("Kiangsu", m_data);
1943
Territory mongolia = territory("Mongolia", m_data);
1945
//Remove original capital
1946
TerritoryAttachment taMongolia = TerritoryAttachment.get(mongolia);
1947
taMongolia.setCapital(null);
1949
//Set as NEW capital
1950
TerritoryAttachment taKiangsu = TerritoryAttachment.get(kiangsu);
1951
taKiangsu.setCapital("Chinese");
1954
removeFrom(kiangsu, kiangsu.getUnits().getUnits());
1955
removeFrom(hupeh, hupeh.getUnits().getUnits());
1957
//Set up the unit types
1958
addTo(hupeh, infantry(m_data).create(1,british));
1961
Collection<Unit> moveUnits = hupeh.getUnits().getUnits();
1963
//Get Owner prior to battle
1964
String preOwner = kiangsu.getOwner().getName();
1965
assertEquals(preOwner, "Japanese");
1967
//add a VALID attack
1968
String validResults = moveDelegate.move(moveUnits, new Route(hupeh, kiangsu));
1969
assertValid(validResults);
1971
//Ensure owner after attack doesn't match attacker
1972
String postOwner = kiangsu.getOwner().getName();
1973
assertNotSame(postOwner, "British");
1975
//Check that original owner is now owner
1976
assertEquals(postOwner, "Chinese");
1979
public void testTwoStepBlitz()
1981
ITestDelegateBridge delegateBridge = getDelegateBridge(british(m_data));
1983
//Set up the territories
1984
Territory libya = territory("Libya", m_data);
1985
Territory egypt = territory("Egypt", m_data);
1986
Territory morrocco = territory("Morocco Algeria", m_data);
1989
removeFrom(libya, libya.getUnits().getUnits());
1991
//Set up the move delegate
1992
MoveDelegate moveDelegate = moveDelegate(m_data);
1993
delegateBridge.setStepName("CombatMove");
1994
moveDelegate.start(delegateBridge, m_data);
1996
//blitz in two steps
1997
Collection<Unit> armour = egypt.getUnits().getMatches(Matches.UnitCanBlitz);
1999
move(armour, new Route(egypt, libya));
2000
assertEquals(libya.getOwner(), british(m_data));
2001
move(armour, new Route(libya, morrocco));
2005
/***********************************************************/
2006
/***********************************************************/
2007
/***********************************************************/
2008
/***********************************************************/
2010
* Add Utilities here
2013
private Collection<Unit> getUnits(IntegerMap<UnitType> units, PlayerID from)
2015
Iterator<UnitType> iter = units.keySet().iterator();
2016
Collection<Unit> rVal = new ArrayList<Unit>(units.totalValues());
2017
while(iter.hasNext())
2019
UnitType type = iter.next();
2020
rVal.addAll(from.getUnits().getUnits(type, units.getInt(type)));
2026
/***********************************************************/
2027
/***********************************************************/
2028
/***********************************************************/
2029
/***********************************************************/
2031
* Add assertions here
2033
public void assertValid(String string)
2035
assertNull(string,string);
2038
public void assertError(String string)
2040
assertNotNull(string,string);