--- /dev/null
+#include "BattleTest.h"
+
+#include "../../src/battle/Battle.h"
+#include "../../src/battle/PartyLayout.h"
+
+#include <stdexcept>
+
+CPPUNIT_TEST_SUITE_REGISTRATION(test_battle::BattleTest);
+
+using battle::AttackChoice;
+using battle::Battle;
+using battle::PartyLayout;
+using math::Vector;
+
+
+namespace test_battle {
+
+void BattleTest::setUp() {
+ positions[0] = Vector<int>(0, 0);
+ positions[1] = Vector<int>(1, 1);
+ twoLayout = new PartyLayout;
+ twoLayout->SetPositions(positions, 2);
+
+ positions[2] = Vector<int>(0, 0);
+ positions[3] = Vector<int>(1, 1);
+ positions[4] = Vector<int>(2, 2);
+ positions[5] = Vector<int>(3, 3);
+ positions[6] = Vector<int>(4, 4);
+ fiveLayout = new PartyLayout;
+ fiveLayout->SetPositions(positions + 2, 5);
+
+ hero.SetMaxHealth(8);
+ hero.SetHealth(8);
+ hero.GetStats().SetAgility(10);
+
+ monster.SetMaxHealth(8);
+ monster.SetHealth(8);
+ monster.GetStats().SetAgility(20);
+}
+
+void BattleTest::tearDown() {
+ monster = battle::Monster();
+ hero = common::Hero();
+ capsule = common::Capsule();
+ delete fiveLayout;
+ delete twoLayout;
+}
+
+
+void BattleTest::testSetup() {
+ CPPUNIT_ASSERT_THROW(Battle battle(0, twoLayout), std::invalid_argument);
+ CPPUNIT_ASSERT_THROW(Battle battle(fiveLayout, 0), std::invalid_argument);
+
+ Battle battle(fiveLayout, twoLayout);
+ CPPUNIT_ASSERT_EQUAL(0, battle.NumHeroes());
+ CPPUNIT_ASSERT_EQUAL(4, battle.MaxHeroes());
+ CPPUNIT_ASSERT(!battle.HeroPositionOccupied(0));
+ // number of monsters is always max
+ CPPUNIT_ASSERT_EQUAL(2, battle.NumMonsters());
+ CPPUNIT_ASSERT_EQUAL(2, battle.MaxMonsters());
+ CPPUNIT_ASSERT(!battle.MonsterPositionOccupied(0));
+ CPPUNIT_ASSERT(!battle.HasCapsule());
+
+ battle.AddHero(hero);
+ CPPUNIT_ASSERT_EQUAL(1, battle.NumHeroes());
+ CPPUNIT_ASSERT_EQUAL(4, battle.MaxHeroes());
+ CPPUNIT_ASSERT(battle.HeroPositionOccupied(0));
+ CPPUNIT_ASSERT_EQUAL(2, battle.NumMonsters());
+ CPPUNIT_ASSERT_EQUAL(2, battle.MaxMonsters());
+ CPPUNIT_ASSERT(!battle.HasCapsule());
+
+ battle.AddHero(hero);
+ CPPUNIT_ASSERT(battle.HeroPositionOccupied(1));
+ battle.AddHero(hero);
+ CPPUNIT_ASSERT(battle.HeroPositionOccupied(2));
+ battle.AddHero(hero);
+ CPPUNIT_ASSERT(battle.HeroPositionOccupied(3));
+ CPPUNIT_ASSERT_EQUAL(4, battle.NumHeroes());
+ CPPUNIT_ASSERT_THROW(battle.AddHero(hero), std::overflow_error);
+ CPPUNIT_ASSERT_EQUAL(4, battle.NumHeroes());
+
+ battle.AddMonster(monster);
+ CPPUNIT_ASSERT_EQUAL(4, battle.NumHeroes());
+ CPPUNIT_ASSERT_EQUAL(4, battle.MaxHeroes());
+ CPPUNIT_ASSERT_EQUAL(2, battle.NumMonsters());
+ CPPUNIT_ASSERT_EQUAL(2, battle.MaxMonsters());
+ CPPUNIT_ASSERT(battle.MonsterPositionOccupied(0));
+ CPPUNIT_ASSERT(!battle.HasCapsule());
+
+ battle.AddMonster(monster);
+ CPPUNIT_ASSERT(battle.MonsterPositionOccupied(1));
+ CPPUNIT_ASSERT_EQUAL(2, battle.NumMonsters());
+ CPPUNIT_ASSERT_THROW(battle.AddMonster(monster), std::overflow_error);
+ CPPUNIT_ASSERT_EQUAL(2, battle.NumMonsters());
+}
+
+void BattleTest::testHeroAttackSelection() {
+ Battle battle(fiveLayout, twoLayout);
+ loadBattle(battle);
+
+ // turns start out with the cursor before the first hero
+ battle.NextHero();
+ CPPUNIT_ASSERT(!battle.AttackSelectionDone());
+ CPPUNIT_ASSERT(!battle.HasChosenAttackType());
+
+ battle.ActiveHero().GetAttackChoice().SetType(AttackChoice::SWORD);
+ battle.ActiveHero().GetAttackChoice().Selection().SetSingle();
+ battle.ActiveHero().GetAttackChoice().Selection().Select();
+ CPPUNIT_ASSERT(battle.HasChosenAttackType());
+
+ battle.NextHero();
+ CPPUNIT_ASSERT(!battle.AttackSelectionDone());
+ CPPUNIT_ASSERT(!battle.HasChosenAttackType());
+
+ battle.ActiveHero().GetAttackChoice().SetType(AttackChoice::DEFEND);
+ CPPUNIT_ASSERT(battle.HasChosenAttackType());
+ CPPUNIT_ASSERT(!battle.AttackSelectionDone());
+
+ battle.NextHero();
+ CPPUNIT_ASSERT(!battle.AttackSelectionDone());
+ CPPUNIT_ASSERT(!battle.HasChosenAttackType());
+ CPPUNIT_ASSERT(!battle.AttackSelectionDone());
+
+ battle.ActiveHero().GetAttackChoice().SetType(AttackChoice::DEFEND);
+ CPPUNIT_ASSERT(battle.HasChosenAttackType());
+
+ battle.NextHero();
+ CPPUNIT_ASSERT(!battle.AttackSelectionDone());
+ CPPUNIT_ASSERT(!battle.HasChosenAttackType());
+ CPPUNIT_ASSERT(!battle.AttackSelectionDone());
+
+ battle.ActiveHero().GetAttackChoice().SetType(AttackChoice::DEFEND);
+ CPPUNIT_ASSERT(battle.HasChosenAttackType());
+ CPPUNIT_ASSERT(!battle.AttackSelectionDone());
+
+ battle.NextHero();
+ CPPUNIT_ASSERT(battle.AttackSelectionDone());
+}
+
+void BattleTest::testBattleRound() {
+ Battle battle(fiveLayout, twoLayout);
+ loadBattle(battle);
+ selectHeroAttacks(battle);
+
+ battle.CalculateAttackOrder();
+
+ // 2 monsters with agl 20, 4 heroes with agl 10
+ // atk of all participants is 0, so no damage should be dealt
+
+ battle.NextAttack();
+ battle.CalculateDamage();
+ const Battle::Order *attack = &battle.CurrentAttack();
+ CPPUNIT_ASSERT(!battle.AttacksFinished());
+ CPPUNIT_ASSERT(attack->IsMonster());
+ CPPUNIT_ASSERT(attack->index >= 0 && attack->index < battle.MaxMonsters());
+ battle.ApplyDamage();
+
+ battle.NextAttack();
+ battle.CalculateDamage();
+ attack = &battle.CurrentAttack();
+ CPPUNIT_ASSERT(!battle.AttacksFinished());
+ CPPUNIT_ASSERT(attack->IsMonster());
+ CPPUNIT_ASSERT(attack->index >= 0 && attack->index < battle.MaxMonsters());
+ battle.ApplyDamage();
+
+ battle.NextAttack();
+ battle.CalculateDamage();
+ attack = &battle.CurrentAttack();
+ CPPUNIT_ASSERT(!battle.AttacksFinished());
+ CPPUNIT_ASSERT(attack->IsHero());
+ CPPUNIT_ASSERT(attack->index >= 0 && attack->index < battle.NumHeroes());
+ battle.ApplyDamage();
+
+ battle.NextAttack();
+ battle.CalculateDamage();
+ attack = &battle.CurrentAttack();
+ CPPUNIT_ASSERT(!battle.AttacksFinished());
+ CPPUNIT_ASSERT(attack->IsHero());
+ CPPUNIT_ASSERT(attack->index >= 0 && attack->index < battle.NumHeroes());
+ battle.ApplyDamage();
+
+ battle.NextAttack();
+ battle.CalculateDamage();
+ attack = &battle.CurrentAttack();
+ CPPUNIT_ASSERT(!battle.AttacksFinished());
+ CPPUNIT_ASSERT(attack->IsHero());
+ CPPUNIT_ASSERT(attack->index >= 0 && attack->index < battle.NumHeroes());
+ battle.ApplyDamage();
+
+ battle.NextAttack();
+ battle.CalculateDamage();
+ attack = &battle.CurrentAttack();
+ CPPUNIT_ASSERT(!battle.AttacksFinished());
+ CPPUNIT_ASSERT(attack->IsHero());
+ CPPUNIT_ASSERT(attack->index >= 0 && attack->index < battle.NumHeroes());
+ battle.ApplyDamage();
+
+ battle.NextAttack();
+ CPPUNIT_ASSERT(battle.AttacksFinished());
+}
+
+
+void BattleTest::loadBattle(Battle &battle) {
+ battle.AddHero(hero);
+ battle.AddHero(hero);
+ battle.AddHero(hero);
+ battle.AddHero(hero);
+ battle.AddMonster(monster);
+ battle.AddMonster(monster);
+}
+
+void BattleTest::selectHeroAttacks(Battle &battle) {
+ battle.NextHero();
+ battle.ActiveHero().GetAttackChoice().SetType(AttackChoice::SWORD);
+ battle.ActiveHero().GetAttackChoice().Selection().SetSingle();
+ battle.ActiveHero().GetAttackChoice().Selection().Select();
+ battle.NextHero();
+ battle.ActiveHero().GetAttackChoice().SetType(AttackChoice::DEFEND);
+ battle.NextHero();
+ battle.ActiveHero().GetAttackChoice().SetType(AttackChoice::DEFEND);
+ battle.NextHero();
+ battle.ActiveHero().GetAttackChoice().SetType(AttackChoice::DEFEND);
+ battle.NextHero();
+}
+
+
+}