fixed tests after ShardokPlayer refactor

This commit is contained in:
Dan Crosby
2017-09-13 15:15:43 -07:00
parent 68aeb398bd
commit 87531e486f
7 changed files with 138 additions and 136 deletions
+1 -4
View File
@@ -3,17 +3,14 @@ BUG: rest button not updating
PERF: multiple random playthroughs at a time
PERF: simple weights for terrain?
PERF: ShardokPlayer GetHeroIdSet
PERF: cache dirty state of game status
PERF: cache a set of 2-tile away coordinate modifiers
PERF: improve 2-tile-away performance
PERF: (possibly big) combine Move options in AI GetActions
PERF: create an UnsafePerform
PERF: (possibly big) test perf of recursive Simulate without parent pointers
PERF: further special-case root MonteCarloTreeNode to not call GetAvailableActions
HEALTH: add tests for IsLegal
HEALTH: add tests for most Engine interface commands
HEALTH: ? remove ShardokPlayer concept
FEATURE: no archery over mountains
+3 -3
View File
@@ -117,12 +117,12 @@ HeroInfo ShardokEngine::ShardokGetHeroById(HeroId heroId) {
}
ShardokResult ShardokEngine::PostAction(ActionDescriptor action, bool getResultDescription) {
if (!actionPerformer.IsLegal(action)) {
return ShardokResult{ .type = ShardokResult::ShardokResult_Illegal };
}
if (GetCurrentPlayerId() != action.player) {
return ShardokResult{ .type = ShardokResult::ShardokResult_NotYourTurn };
}
if (!actionPerformer.IsLegal(action)) {
return ShardokResult{ .type = ShardokResult::ShardokResult_Illegal };
}
return PostActionUnchecked(action, getResultDescription);
}
+36 -25
View File
@@ -130,11 +130,16 @@ void CharismaHelps(const BattalionType *type) {
double ch1 = charisma;
double ch2 = charisma + PERCENTILE_STEPPER;
HeroSPtr hero1 = GetHero1()->ToBuilder().SetCharisma(ch1).Build();
HeroSPtr hero2 = GetHero1()->ToBuilder().SetCharisma(ch2).Build();
HeroInfo hero1 = GetHero1();
hero1.charisma = ch1;
HeroInfo hero2 = hero1;
hero2.charisma = ch2;
BattalionSPtr unit1 = baseUnit->ToBuilder().SetCommander(&(*hero1)).Build();
BattalionSPtr unit2 = baseUnit->ToBuilder().SetCommander(&(*hero2)).Build();
HeroSPtr heldHero1 = Hero::FromInfo(hero1);
HeroSPtr heldHero2 = Hero::FromInfo(hero2);
BattalionSPtr unit1 = baseUnit->ToBuilder().SetCommander(heldHero1.get()).Build();
BattalionSPtr unit2 = baseUnit->ToBuilder().SetCommander(heldHero2.get()).Build();
EXPECT_TRUE(unit1->GiveMeleeDamage(TEST_ROLL) < unit2->GiveMeleeDamage(TEST_ROLL));
}
@@ -147,8 +152,8 @@ void BraveryHelps(const BattalionType *type) {
double br1 = bravery;
double br2 = bravery + PERCENTILE_STEPPER;
HeroSPtr hero1 = GetHero1()->ToBuilder().SetBravery(br1).Build();
HeroSPtr hero2 = GetHero1()->ToBuilder().SetBravery(br2).Build();
HeroSPtr hero1 = Hero::FromInfo(GetHero1())->ToBuilder().SetBravery(br1).Build();
HeroSPtr hero2 = Hero::FromInfo(GetHero1())->ToBuilder().SetBravery(br2).Build();
BattalionSPtr unit1 = baseUnit->ToBuilder().SetCommander(&(*hero1)).Build();
BattalionSPtr unit2 = baseUnit->ToBuilder().SetCommander(&(*hero2)).Build();
@@ -168,23 +173,25 @@ void ArmamentHelps(const BattalionType *type) {
BattalionSPtr unit1 = baseUnit->ToBuilder().SetArmament(arm1).Build();
BattalionSPtr unit2 = baseUnit->ToBuilder().SetArmament(arm2).Build();
uint32_t originalU1 = unit1->GetSize();
uint32_t originalU2 = unit2->GetSize();
BattalionSPtr injuredUnit1 = unit1->TakeDamage(attackingDamage, TEST_TERRAIN, TEST_DIRECTION);
BattalionSPtr injuredUnit2 = unit2->TakeDamage(attackingDamage, TEST_TERRAIN, TEST_DIRECTION);
unit1->TakeDamage(attackingDamage, TEST_TERRAIN, TEST_DIRECTION);
unit2->TakeDamage(attackingDamage, TEST_TERRAIN, TEST_DIRECTION);
EXPECT_LT(injuredUnit1->GetSize(), unit1->GetSize());
EXPECT_LT(injuredUnit2->GetSize(), unit2->GetSize());
EXPECT_LE(injuredUnit1->GetSize(), injuredUnit2->GetSize());
EXPECT_LT(unit1->GetSize(), originalU1);
EXPECT_LT(unit2->GetSize(), originalU2);
EXPECT_LE(unit1->GetSize(), unit2->GetSize());
}
// Make sure that we actually shifted (not all equal)
BattalionSPtr unit1 = baseUnit->ToBuilder().SetArmament(MIN_TESTED_PERCENTILE).Build();
BattalionSPtr unit2 = baseUnit->ToBuilder().SetArmament(MAX_TESTED_PERCENTILE).Build();
BattalionSPtr injuredUnit1 = unit1->TakeDamage(attackingDamage, TEST_TERRAIN, TEST_DIRECTION);
BattalionSPtr injuredUnit2 = unit2->TakeDamage(attackingDamage, TEST_TERRAIN, TEST_DIRECTION);
unit1->TakeDamage(attackingDamage, TEST_TERRAIN, TEST_DIRECTION);
unit2->TakeDamage(attackingDamage, TEST_TERRAIN, TEST_DIRECTION);
EXPECT_LT(injuredUnit1->GetSize(), injuredUnit2->GetSize());
EXPECT_LT(unit1->GetSize(), unit2->GetSize());
}
void BraveryHurts(const BattalionType *type) {
@@ -196,18 +203,20 @@ void BraveryHurts(const BattalionType *type) {
double brv1 = bravery;
double brv2 = bravery + PERCENTILE_STEPPER;
HeroSPtr hero1 = GetHero1()->ToBuilder().SetBravery(brv1).Build();
HeroSPtr hero2 = GetHero1()->ToBuilder().SetBravery(brv2).Build();
HeroSPtr hero1 = Hero::FromInfo(GetHero1())->ToBuilder().SetBravery(brv1).Build();
HeroSPtr hero2 = Hero::FromInfo(GetHero1())->ToBuilder().SetBravery(brv2).Build();
BattalionSPtr unit1 = baseUnit->ToBuilder().SetCommander(&(*hero1)).Build();
BattalionSPtr unit2 = baseUnit->ToBuilder().SetCommander(&(*hero2)).Build();
uint32_t originalU1 = unit1->GetSize();
uint32_t originalU2 = unit2->GetSize();
BattalionSPtr injuredUnit1 = unit1->TakeDamage(attackingDamage, TEST_TERRAIN, TEST_DIRECTION);
BattalionSPtr injuredUnit2 = unit2->TakeDamage(attackingDamage, TEST_TERRAIN, TEST_DIRECTION);
unit1->TakeDamage(attackingDamage, TEST_TERRAIN, TEST_DIRECTION);
unit2->TakeDamage(attackingDamage, TEST_TERRAIN, TEST_DIRECTION);
EXPECT_TRUE(injuredUnit1->GetSize() < unit1->GetSize());
EXPECT_TRUE(injuredUnit2->GetSize() < unit2->GetSize());
EXPECT_TRUE(injuredUnit1->GetSize() >= injuredUnit2->GetSize());
EXPECT_TRUE(unit1->GetSize() < originalU1);
EXPECT_TRUE(unit2->GetSize() < originalU2);
EXPECT_TRUE(unit1->GetSize() >= unit2->GetSize());
}
}
@@ -217,10 +226,12 @@ void FlankingHurts(const BattalionType *type) {
BattalionSPtr baseUnit = BaseUnitOfType(type);
BattalionSPtr injuredUnitFront = baseUnit->TakeDamage(attackingDamage, TEST_TERRAIN, ShardokAttackDirection_frontal);
BattalionSPtr injuredUnitFlank = baseUnit->TakeDamage(attackingDamage, TEST_TERRAIN, ShardokAttackDirection_flank);
BattalionSPtr injuredUnitRear = baseUnit->TakeDamage(attackingDamage, TEST_TERRAIN, ShardokAttackDirection_rear);
BattalionSPtr injuredUnitFront = baseUnit->copy();
injuredUnitFront->TakeDamage(attackingDamage, TEST_TERRAIN, ShardokAttackDirection_frontal);
BattalionSPtr injuredUnitFlank = baseUnit->copy();
injuredUnitFlank->TakeDamage(attackingDamage, TEST_TERRAIN, ShardokAttackDirection_flank);
BattalionSPtr injuredUnitRear = baseUnit->copy();
injuredUnitRear->TakeDamage(attackingDamage, TEST_TERRAIN, ShardokAttackDirection_rear);
EXPECT_TRUE(injuredUnitFront->GetSize() < baseUnit->GetSize());
EXPECT_TRUE(injuredUnitFlank->GetSize() < baseUnit->GetSize());
@@ -14,8 +14,8 @@
#define TEST_ROLL ((50.0))
TEST(HeroCombatTests, DoMeleeBattery) {
HeroSPtr attacker = GetHero1();
HeroSPtr defender = GetHero2();
HeroSPtr attacker = Hero::FromInfo(GetHero1());
HeroSPtr defender = Hero::FromInfo(GetHero2());
int originalAttackerSize = attacker->GetBattalion()->GetSize();
int originalDefenderSize = defender->GetBattalion()->GetSize();
+5 -5
View File
@@ -15,8 +15,8 @@
// Basic test for building a hero. Fails to build if
// Hero is not immutable.
//
TEST(HeroTest, NewBuilder) {
const HeroSPtr hero = GetHero1();
TEST(HeroTest, FromInfo) {
const HeroSPtr hero = Hero::FromInfo(GetHero1());
EXPECT_EQ(HERO1_ID, hero->GetId());
EXPECT_EQ(HERO1_NAME, hero->GetName());
@@ -43,7 +43,7 @@ TEST(HeroTest, NewBuilder) {
// Make a builder and a new hero out of it.
//
TEST(HeroTest, ToBuilder) {
HeroSPtr hero = GetHero1();
HeroSPtr hero = Hero::FromInfo(GetHero1());
HeroSPtr heroCopy = hero->ToBuilder().Build();
@@ -72,7 +72,7 @@ TEST(HeroTest, ToBuilder) {
// Alter one stat when building from an existing hero.
//
TEST(HeroTest, ToBuilderWithAdjustment) {
HeroSPtr hero = GetHero1();
HeroSPtr hero = Hero::FromInfo(GetHero1());
HeroSPtr heroCopy = hero->ToBuilder().SetStrength(HERO2_STR).Build();
@@ -96,7 +96,7 @@ TEST(HeroTest, ToBuilderWithAdjustment) {
//
TEST(HeroTest, EqualityOperator) {
HeroSPtr hero1 = GetHero1();
HeroSPtr hero1 = Hero::FromInfo(GetHero1());
HeroSPtr hero2 = hero1->ToBuilder().Build();
EXPECT_TRUE(*hero1==*hero2);
+56 -60
View File
@@ -39,37 +39,35 @@ const bool HERO1_WSCHOLAR = true;
const Coords HERO1_COORDS = Coords(3, 4);
inline HeroSPtr GetHero1() {
BattalionSPtr batt = BaseUnitOfType(GetBattalionType_LightInfantry())
->ToBuilder()
.SetTraining(75.0)
.SetArmament(50.0)
.SetMorale(60.0)
.Build();
inline HeroInfo GetHero1() {
BattalionInfo batt = BaseUnitOfType(GetBattalionType_LightInfantry())->GetInfo();
batt.training = 75.0;
batt.armament = 50.0;
batt.morale = 60.0;
return Hero::NewBuilder()
.SetId(HERO1_ID)
.SetName(HERO1_NAME)
.SetStrength(HERO1_STR)
.SetAgility(HERO1_AGI)
.SetConstitution(HERO1_CON)
.SetCharisma(HERO1_CHA)
.SetIntelligence(HERO1_INT)
.SetWisdom(HERO1_WIS)
.SetVigor(HERO1_VIG)
.SetIntegrity(HERO1_ING)
.SetGregariousness(HERO1_GRG)
.SetAmbition(HERO1_AMB)
.SetBravery(HERO1_BRV)
.SetMechanic(HERO1_MECHANIC)
.SetSiegeEngineer(HERO1_SIEGE)
.SetNavigator(HERO1_NAV)
.SetMage(HERO1_MAGE)
.SetHealer(HERO1_HEALER)
.SetWarScholar(HERO1_WSCHOLAR)
.SetBattalion(batt)
.SetLocation(HERO1_COORDS)
.Build();
return HeroInfo{
.heroId = HERO1_ID,
.name = HERO1_NAME,
.strength = HERO1_STR,
.agility = HERO1_AGI,
.constitution = HERO1_CON,
.charisma = HERO1_CHA,
.intelligence = HERO1_INT,
.wisdom = HERO1_WIS,
.vigor = HERO1_VIG,
.integrity = HERO1_ING,
.gregariousness = HERO1_GRG,
.ambition = HERO1_AMB,
.bravery = HERO1_BRV,
.mechanic = HERO1_MECHANIC,
.siegeEngineer = HERO1_SIEGE,
.navigator = HERO1_NAV,
.mage = HERO1_MAGE,
.healer = HERO1_HEALER,
.warScholar = HERO1_WSCHOLAR,
.battalion = batt,
.location = HERO1_COORDS
};
}
const HeroId HERO2_ID = 123;
@@ -96,37 +94,35 @@ const bool HERO2_WSCHOLAR = true;
const Coords HERO2_COORDS = Coords(3, 3);
inline HeroSPtr GetHero2() {
BattalionSPtr batt = BaseUnitOfType(GetBattalionType_LightInfantry())
->ToBuilder()
.SetTraining(50.0)
.SetArmament(75.0)
.SetMorale(55.0)
.Build();
inline HeroInfo GetHero2() {
BattalionInfo batt = BaseUnitOfType(GetBattalionType_LightInfantry())->GetInfo();
batt.training = 50.0;
batt.armament = 75.0;
batt.morale = 55.0;
return Hero::NewBuilder()
.SetId(HERO2_ID)
.SetName(HERO2_NAME)
.SetStrength(HERO2_STR)
.SetAgility(HERO2_AGI)
.SetConstitution(HERO2_CON)
.SetCharisma(HERO2_CHA)
.SetIntelligence(HERO2_INT)
.SetWisdom(HERO2_WIS)
.SetVigor(HERO2_VIG)
.SetIntegrity(HERO2_ING)
.SetGregariousness(HERO2_GRG)
.SetAmbition(HERO2_AMB)
.SetBravery(HERO2_BRV)
.SetMechanic(HERO2_MECHANIC)
.SetSiegeEngineer(HERO2_SIEGE)
.SetNavigator(HERO2_NAV)
.SetMage(HERO2_MAGE)
.SetHealer(HERO2_HEALER)
.SetWarScholar(HERO2_WSCHOLAR)
.SetBattalion(batt)
.SetLocation(HERO2_COORDS)
.Build();
return HeroInfo{
.heroId = HERO2_ID,
.name = HERO2_NAME,
.strength = HERO2_STR,
.agility = HERO2_AGI,
.constitution = HERO2_CON,
.charisma = HERO2_CHA,
.intelligence = HERO2_INT,
.wisdom = HERO2_WIS,
.vigor = HERO2_VIG,
.integrity = HERO2_ING,
.gregariousness = HERO2_GRG,
.ambition = HERO2_AMB,
.bravery = HERO2_BRV,
.mechanic = HERO2_MECHANIC,
.siegeEngineer = HERO2_SIEGE,
.navigator = HERO2_NAV,
.mage = HERO2_MAGE,
.healer = HERO2_HEALER,
.warScholar = HERO2_WSCHOLAR,
.battalion = batt,
.location = HERO2_COORDS
};
}
#pragma clang diagnostic pop
@@ -13,65 +13,62 @@
#include "ShardokThrowingRandomGenerator.h"
TEST(ShardokEngineTests, ShardokEngine_TwoTurnsInARow) {
HexMapSPtr hexMap = HexMapSPtr::make_shared(6, 6, false);
HexMapInfo hexMap = HexMapSPtr::make_shared(6, 6, false)->GetInfo();
std::vector<PlayerSetupInfo> defenders = { PlayerSetupInfo{HeroList{GetHero1()}} };
std::vector<PlayerSetupInfo> attackers = { PlayerSetupInfo{HeroList{GetHero2()}} };
std::vector<PlayerSetupInfo> defenders = { PlayerSetupInfo{HeroInfoList{GetHero1()}} };
std::vector<PlayerSetupInfo> attackers = { PlayerSetupInfo{HeroInfoList{GetHero2()}} };
ShardokEngine game(defenders, attackers, hexMap);
ShardokEngine game(attackers, defenders, hexMap);
HeroSPtr hero2 = game.GetPlayerForId(0)->GetHeroWithId(0);
HeroSPtr hero1 = game.GetPlayerForId(1)->GetHeroWithId(1);
HeroId hero2Id = 0;
ShardokResult result = game.PostAction(ActionDescriptor::MeleeAction(0, hero2->GetId(), HexMapDirection::east), false);
ShardokResult result = game.PostAction(ActionDescriptor::MeleeAction(0, hero2Id, HexMapDirection::east), false);
EXPECT_EQ(ShardokResult::ShardokResult_Performed, result.type);
result = game.PostAction(ActionDescriptor::EndTurnAction(0), false);
EXPECT_EQ(ShardokResult::ShardokResult_Performed, result.type);
result = game.PostAction(ActionDescriptor::MeleeAction(0, hero2->GetId(), HexMapDirection::east), false);
result = game.PostAction(ActionDescriptor::MeleeAction(0, hero2Id, HexMapDirection::east), false);
EXPECT_EQ(ShardokResult::ShardokResult_NotYourTurn, result.type);
}
TEST(ShardokEngineTests, ShardokEngine_notYourHero) {
HexMapSPtr hexMap = HexMapSPtr::make_shared(6, 6, false);
HexMapInfo hexMap = HexMapSPtr::make_shared(6, 6, false)->GetInfo();
std::vector<PlayerSetupInfo> defenders = { PlayerSetupInfo{HeroList{GetHero1()}} };
std::vector<PlayerSetupInfo> attackers = { PlayerSetupInfo{HeroList{GetHero2()}} };
std::vector<PlayerSetupInfo> defenders = { PlayerSetupInfo{HeroInfoList{GetHero1()}} };
std::vector<PlayerSetupInfo> attackers = { PlayerSetupInfo{HeroInfoList{GetHero2()}} };
HeroId hero1Id = 1;
ShardokEngine game(defenders, attackers, hexMap);
HeroSPtr hero2 = game.GetPlayerForId(0)->GetHeroWithId(0);
HeroSPtr hero1 = game.GetPlayerForId(1)->GetHeroWithId(1);
ShardokEngine game(attackers, defenders, hexMap);
// Hero1 doesn't belong to player 0
ShardokResult result = game.PostAction(ActionDescriptor::MeleeAction(0, hero1->GetId(), HexMapDirection::east), false);
ShardokResult result = game.PostAction(ActionDescriptor::MeleeAction(0, hero1Id, HexMapDirection::east), false);
EXPECT_EQ(ShardokResult::ShardokResult_Illegal, result.type);
}
TEST(ShardokEngineTests, ShardokEngine_meleeOnEmptyTile) {
HexMapSPtr hexMap = HexMapSPtr::make_shared(6, 6, false);
HexMapInfo hexMap = HexMapSPtr::make_shared(6, 6, false)->GetInfo();
std::vector<PlayerSetupInfo> defenders = { PlayerSetupInfo{HeroList{GetHero1()}} };
std::vector<PlayerSetupInfo> attackers = { PlayerSetupInfo{HeroList{GetHero2()}} };
std::vector<PlayerSetupInfo> defenders = { PlayerSetupInfo{HeroInfoList{GetHero1()}} };
std::vector<PlayerSetupInfo> attackers = { PlayerSetupInfo{HeroInfoList{GetHero2()}} };
ShardokEngine game(defenders, attackers, hexMap);
ShardokEngine game(attackers, defenders, hexMap);
HeroSPtr hero2 = game.GetPlayerForId(0)->GetHeroWithId(0);
HeroSPtr hero1 = game.GetPlayerForId(1)->GetHeroWithId(1);
HeroId hero2Id = 0;
// There is no one west of hero2
ShardokResult result = game.PostAction(ActionDescriptor::MeleeAction(0, hero2->GetId(), HexMapDirection::west), false);
ShardokResult result = game.PostAction(ActionDescriptor::MeleeAction(0, hero2Id, HexMapDirection::west), false);
EXPECT_EQ(ShardokResult::ShardokResult_Illegal, result.type);
}
TEST(ShardokEngineTests, ShardokEngine_IncrementsRound) {
HexMapSPtr hexMap = HexMapSPtr::make_shared(6, 6, false);
HexMapInfo hexMap = HexMapSPtr::make_shared(6, 6, false)->GetInfo();
std::vector<PlayerSetupInfo> defenders = { PlayerSetupInfo{HeroList{GetHero1()}} };
std::vector<PlayerSetupInfo> attackers = { PlayerSetupInfo{HeroList{GetHero2()}} };
std::vector<PlayerSetupInfo> defenders = { PlayerSetupInfo{HeroInfoList{GetHero1()}} };
std::vector<PlayerSetupInfo> attackers = { PlayerSetupInfo{HeroInfoList{GetHero2()}} };
ShardokEngine game(defenders, attackers, hexMap);
ShardokEngine game(attackers, defenders, hexMap);
EXPECT_EQ(game.GetCurrentRound(), 0);
game.PostAction(ActionDescriptor::EndTurnAction(0), false);
@@ -82,19 +79,20 @@ TEST(ShardokEngineTests, ShardokEngine_IncrementsRound) {
}
TEST(ShardokEngineTests, CheckGameStatus_attackerDestroyed) {
BattalionSPtr attackerBattalion = GetHero2()->GetBattalion()->ToBuilder().SetSize(1).Build();
HeroSPtr att = GetHero2()->ToBuilder().SetBattalion(attackerBattalion).Build();
HeroSPtr def = GetHero1();
HeroInfo att = GetHero2();
att.battalion.size = 1;
HeroInfo def = GetHero1();
std::vector<PlayerSetupInfo> defenders = { PlayerSetupInfo{HeroList{def}} };
std::vector<PlayerSetupInfo> attackers = { PlayerSetupInfo{HeroList{att}} };
HexMapInfo hexMap = HexMapSPtr::make_shared(6, 6, false)->GetInfo();
HexMapSPtr hexMap = HexMapSPtr::make_shared(6, 6, false);
ShardokEngine game(defenders, attackers, hexMap);
HeroSPtr attackerHero = game.GetPlayerForId(0)->GetHeroWithId(0);
HeroSPtr defenderHero = game.GetPlayerForId(1)->GetHeroWithId(1);
std::vector<PlayerSetupInfo> defenders = { PlayerSetupInfo{HeroInfoList{def}} };
std::vector<PlayerSetupInfo> attackers = { PlayerSetupInfo{HeroInfoList{att}} };
game.PostAction(ActionDescriptor::MeleeAction(0, attackerHero->GetId(), HexMapDirection::east), false);
ShardokEngine game(attackers, defenders, hexMap);
HeroInfo attackerHero = game.GetHeroForId(0)->GetInfo();
HeroInfo defenderHero = game.GetHeroForId(1)->GetInfo();
game.PostAction(ActionDescriptor::MeleeAction(0, attackerHero.heroId, HexMapDirection::east), false);
EXPECT_EQ(GameStatus::defenderVictory, game.GetGameStatus().state);
}