2
0

ResourceTraderTest.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * RecruitHeroBehaviorTest.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. */
  9. #include "Global.h"
  10. #include "gmock/gmock.h"
  11. #include "gtest/gtest.h"
  12. #include "AI/Nullkiller2/Engine/ResourceTrader.h"
  13. #include "test/nullkiller2/Nulkiller2TestUtils.h"
  14. class MockMarket final : public IMarket
  15. {
  16. ObjectInstanceID id;
  17. int marketEfficiency;
  18. public:
  19. explicit MockMarket(const int marketEfficiency) : marketEfficiency(marketEfficiency), IMarket(nullptr) {}
  20. ~MockMarket() override = default;
  21. MOCK_METHOD(std::set<EMarketMode>, availableModes, (), (const, override));
  22. ObjectInstanceID getObjInstanceID() const override
  23. {
  24. return id;
  25. }
  26. int getMarketEfficiency() const override
  27. {
  28. return marketEfficiency;
  29. }
  30. };
  31. class MockBuildAnalyzer final : public NK2AI::BuildAnalyzer
  32. {
  33. public:
  34. explicit MockBuildAnalyzer() : BuildAnalyzer(nullptr) {}
  35. MOCK_METHOD(bool, isGoldPressureOverMax, (), (const, override));
  36. };
  37. class MockCCallback final : public CCallback
  38. {
  39. public:
  40. MockCCallback() : CCallback(nullptr, std::nullopt, nullptr) {}
  41. MOCK_METHOD(
  42. void,
  43. trade,
  44. (const ObjectInstanceID marketId, EMarketMode mode, TradeItemSell id1, TradeItemBuy id2, ui32 val1, const CGHeroInstance * hero),
  45. (override)
  46. );
  47. };
  48. TEST(Nullkiller2_Engine_ResourceTrader, tradeHelper_crystalsToGold)
  49. {
  50. const TResources missingNow01 = Nulkiller2TestUtils::res(0, 0, 0, 4000, 0, 0, 75000);
  51. const TResources missingNow02 = Nulkiller2TestUtils::res(0, 0, 0, 0, 0, 0, 10000);
  52. const TResources income = Nulkiller2TestUtils::res(2, 2, 2, 4000, 2, 2, 1000);
  53. const TResources freeAfterMissingTotal = Nulkiller2TestUtils::res(1000, 1000, 1000, 0, 1002, 1000, 0);
  54. MockBuildAnalyzer ba;
  55. EXPECT_CALL(ba, isGoldPressureOverMax()).Times(0);
  56. MockMarket m01(1);
  57. MockMarket m20(20); // maxes out at 0.5 effectiveness anyway after 9 castles
  58. MockCCallback cc;
  59. // Case: sells 50% of crystals
  60. EXPECT_CALL(cc, trade(m01.getObjInstanceID(), EMarketMode::RESOURCE_RESOURCE, TradeItemSell(GameResID(4)), TradeItemBuy(GameResID(6)), 501, nullptr)).Times(1);
  61. NK2AI::ResourceTrader::tradeHelper(NK2AI::ResourceTrader::EXPENDABLE_BULK_RATIO, m01, missingNow01, income, freeAfterMissingTotal, ba, cc);
  62. // Case: only 200 crystals because that's enough for getting the desired goal
  63. EXPECT_CALL(cc, trade(m01.getObjInstanceID(), EMarketMode::RESOURCE_RESOURCE, TradeItemSell(GameResID(4)), TradeItemBuy(GameResID(6)), 200, nullptr)).Times(1);
  64. NK2AI::ResourceTrader::tradeHelper(NK2AI::ResourceTrader::EXPENDABLE_BULK_RATIO, m01, missingNow02, income, freeAfterMissingTotal, ba, cc);
  65. // Case: only 40 crystals because that's enough for getting the desired goal
  66. EXPECT_CALL(cc, trade(m20.getObjInstanceID(), EMarketMode::RESOURCE_RESOURCE, TradeItemSell(GameResID(4)), TradeItemBuy(GameResID(6)), 40, nullptr)).Times(1);
  67. NK2AI::ResourceTrader::tradeHelper(NK2AI::ResourceTrader::EXPENDABLE_BULK_RATIO, m20, missingNow02, income, freeAfterMissingTotal, ba, cc);
  68. }
  69. TEST(Nullkiller2_Engine_ResourceTrader, tradeHelper_goldToGems)
  70. {
  71. const TResources missingNow01 = Nulkiller2TestUtils::res(0, 0, 0, 4000, 0, 200, 0);
  72. const TResources missingNow02 = Nulkiller2TestUtils::res(0, 0, 0, 4000, 0, 4, 0);
  73. const TResources income = Nulkiller2TestUtils::res(2, 2, 2, 4000, 2, 2, 1000);
  74. const TResources freeAfterMissingTotal = Nulkiller2TestUtils::res(100, 100, 100, 0, 0, 0, 100000);
  75. MockBuildAnalyzer ba;
  76. EXPECT_CALL(ba, isGoldPressureOverMax()).Times(3).WillRepeatedly(testing::Return(false));
  77. MockMarket m(1);
  78. MockMarket m20(20); // maxes out at 0.5 effectiveness anyway after 9 castles
  79. MockCCallback cc;
  80. // Case: sells 50% of gold
  81. EXPECT_CALL(cc, trade(m.getObjInstanceID(), EMarketMode::RESOURCE_RESOURCE, TradeItemSell(GameResID(6)), TradeItemBuy(GameResID(5)), 50000, nullptr)).Times(1);
  82. NK2AI::ResourceTrader::tradeHelper(NK2AI::ResourceTrader::EXPENDABLE_BULK_RATIO, m, missingNow01, income, freeAfterMissingTotal, ba, cc);
  83. // Case: only 20,000 gold because that's enough for getting the desired goal
  84. EXPECT_CALL(cc, trade(m.getObjInstanceID(), EMarketMode::RESOURCE_RESOURCE, TradeItemSell(GameResID(6)), TradeItemBuy(GameResID(5)), 20000, nullptr)).Times(1);
  85. NK2AI::ResourceTrader::tradeHelper(NK2AI::ResourceTrader::EXPENDABLE_BULK_RATIO, m, missingNow02, income, freeAfterMissingTotal, ba, cc);
  86. // Case: only 4,000 gold because that's enough for getting the desired goal
  87. EXPECT_CALL(cc, trade(m20.getObjInstanceID(), EMarketMode::RESOURCE_RESOURCE, TradeItemSell(GameResID(6)), TradeItemBuy(GameResID(5)), 4000, nullptr)).Times(1);
  88. NK2AI::ResourceTrader::tradeHelper(NK2AI::ResourceTrader::EXPENDABLE_BULK_RATIO, m20, missingNow02, income, freeAfterMissingTotal, ba, cc);
  89. }