From 972af35ecf89d7d88d988106e0ebea877f80e532 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Thu, 31 Oct 2019 12:02:23 +0100 Subject: [PATCH] Initial support for ordering choices and getting them ready for execution. --- src/Battling/Flow/ChoiceQueue.cpp | 1 + src/Battling/Flow/ChoiceQueue.hpp | 28 +++++++++++++++ src/Battling/Flow/TurnHandler.cpp | 5 +++ src/Battling/Flow/TurnHandler.hpp | 15 ++++++++ src/Battling/Flow/TurnOrdering.cpp | 18 ++++++++++ src/Battling/Flow/TurnOrdering.hpp | 14 ++++++++ src/Battling/Models/Battle.cpp | 36 +++++++++++++++++-- src/Battling/Models/Battle.hpp | 9 +++++ src/Battling/TurnChoices/AttackTurnChoice.hpp | 7 +++- src/Battling/TurnChoices/BaseTurnChoice.hpp | 2 ++ tests/BattleTests/TurnOrderTests.cpp | 26 ++++++++++++++ 11 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 src/Battling/Flow/ChoiceQueue.cpp create mode 100644 src/Battling/Flow/ChoiceQueue.hpp create mode 100644 src/Battling/Flow/TurnHandler.cpp create mode 100644 src/Battling/Flow/TurnHandler.hpp create mode 100644 src/Battling/Flow/TurnOrdering.cpp create mode 100644 src/Battling/Flow/TurnOrdering.hpp create mode 100644 tests/BattleTests/TurnOrderTests.cpp diff --git a/src/Battling/Flow/ChoiceQueue.cpp b/src/Battling/Flow/ChoiceQueue.cpp new file mode 100644 index 0000000..1f0d465 --- /dev/null +++ b/src/Battling/Flow/ChoiceQueue.cpp @@ -0,0 +1 @@ +#include "ChoiceQueue.hpp" diff --git a/src/Battling/Flow/ChoiceQueue.hpp b/src/Battling/Flow/ChoiceQueue.hpp new file mode 100644 index 0000000..03f2edb --- /dev/null +++ b/src/Battling/Flow/ChoiceQueue.hpp @@ -0,0 +1,28 @@ +#ifndef CREATURELIB_CHOICEQUEUE_HPP +#define CREATURELIB_CHOICEQUEUE_HPP + +#include +#include "../TurnChoices/BaseTurnChoice.hpp" + +namespace CreatureLib::Battling{ + class ChoiceQueue { + std::vector _queue; + size_t _current = 0; + public: + ChoiceQueue(const std::vector& queue) + :_queue(queue){} + + const BaseTurnChoice* Dequeue(){ + auto b = _queue[_current]; + _current++; + return b; + } + + bool HasNext() const{ + return _current < _queue.size(); + } + }; +} + + +#endif //CREATURELIB_CHOICEQUEUE_HPP diff --git a/src/Battling/Flow/TurnHandler.cpp b/src/Battling/Flow/TurnHandler.cpp new file mode 100644 index 0000000..366e139 --- /dev/null +++ b/src/Battling/Flow/TurnHandler.cpp @@ -0,0 +1,5 @@ +#include "TurnHandler.hpp" + +void CreatureLib::Battling::TurnHandler::RunTurn(CreatureLib::Battling::ChoiceQueue &queue) { + +} diff --git a/src/Battling/Flow/TurnHandler.hpp b/src/Battling/Flow/TurnHandler.hpp new file mode 100644 index 0000000..0c71b88 --- /dev/null +++ b/src/Battling/Flow/TurnHandler.hpp @@ -0,0 +1,15 @@ +#ifndef CREATURELIB_TURNHANDLER_HPP +#define CREATURELIB_TURNHANDLER_HPP + +#include "ChoiceQueue.hpp" + +namespace CreatureLib::Battling { + class Battle; + + class TurnHandler { + public: + static void RunTurn(ChoiceQueue& queue); + }; +} + +#endif //CREATURELIB_TURNHANDLER_HPP diff --git a/src/Battling/Flow/TurnOrdering.cpp b/src/Battling/Flow/TurnOrdering.cpp new file mode 100644 index 0000000..be77e70 --- /dev/null +++ b/src/Battling/Flow/TurnOrdering.cpp @@ -0,0 +1,18 @@ +#include "TurnOrdering.hpp" + +#include + +using namespace CreatureLib::Battling; + +bool ___ChoiceOrderFunc(const BaseTurnChoice* a, const BaseTurnChoice* b){ + auto aKind = a->GetKind(); + auto bKind = b->GetKind(); + if (aKind != bKind) + return aKind > bKind; + //FIXME: choices need to be ordered when they're the same type + throw 1; +} + +void TurnOrdering::OrderChoices(std::vector &vec) { + std::sort(vec.begin(), vec.end(), ___ChoiceOrderFunc); +} diff --git a/src/Battling/Flow/TurnOrdering.hpp b/src/Battling/Flow/TurnOrdering.hpp new file mode 100644 index 0000000..097965c --- /dev/null +++ b/src/Battling/Flow/TurnOrdering.hpp @@ -0,0 +1,14 @@ +#ifndef CREATURELIB_TURNORDERING_HPP +#define CREATURELIB_TURNORDERING_HPP + +#include "../TurnChoices/BaseTurnChoice.hpp" +#include + +namespace CreatureLib::Battling { + class TurnOrdering { + public: + static void OrderChoices(std::vector& vec); + }; +} + +#endif //CREATURELIB_TURNORDERING_HPP diff --git a/src/Battling/Models/Battle.cpp b/src/Battling/Models/Battle.cpp index 6ba41af..e9b88c5 100644 --- a/src/Battling/Models/Battle.cpp +++ b/src/Battling/Models/Battle.cpp @@ -1,11 +1,15 @@ #include "Battle.hpp" +#include "../Flow/TurnHandler.hpp" #include "../TurnChoices/AttackTurnChoice.hpp" +#include "../Flow/TurnOrdering.hpp" -const CreatureLib::Battling::BattleLibrary *CreatureLib::Battling::Battle::GetLibrary() const { +using namespace CreatureLib::Battling; + +const BattleLibrary *Battle::GetLibrary() const { return _library; } -bool CreatureLib::Battling::Battle::CanUse(CreatureLib::Battling::BaseTurnChoice *choice) { +bool Battle::CanUse(BaseTurnChoice *choice) { if (choice->GetKind() == TurnChoiceKind::Attack){ //HOOK: change number of uses needed. return static_cast(choice)->GetAttack()->GetRemainingUses() > 1; @@ -13,9 +17,35 @@ bool CreatureLib::Battling::Battle::CanUse(CreatureLib::Battling::BaseTurnChoice return true; } -bool CreatureLib::Battling::Battle::TrySetChoice(CreatureLib::Battling::BaseTurnChoice *choice) { +bool Battle::TrySetChoice(BaseTurnChoice *choice) { if (!CanUse(choice)) return false; choice->GetUser()->GetBattleSide()->SetChoice(choice); + CheckChoicesSetAndRun(); return true; } + +void Battle::CheckChoicesSetAndRun() { + for (auto side: _sides){ + if (!side->AllChoicesSet()){ + return; + } + } + auto choices = std::vector(_numberOfSides * _creaturesPerSide); + auto i = 0; + for (auto side: _sides){ + for (auto choice: side->GetChoices()){ + choices[i] = choice; + i++; + } + } + TurnOrdering::OrderChoices(choices); + auto choiceQueue = ChoiceQueue(choices); + this->_currentTurnQueue = &choiceQueue; + TurnHandler::RunTurn(choiceQueue); + this->_currentTurnQueue = nullptr; +} + +ChoiceQueue* Battle::GetCurrentTurnQueue() const { + return _currentTurnQueue; +} diff --git a/src/Battling/Models/Battle.hpp b/src/Battling/Models/Battle.hpp index 03ff862..4e514b6 100644 --- a/src/Battling/Models/Battle.hpp +++ b/src/Battling/Models/Battle.hpp @@ -5,16 +5,25 @@ #include "BattleSide.hpp" #include "../Library/BattleLibrary.hpp" #include "../TurnChoices/BaseTurnChoice.hpp" +#include "../Flow/ChoiceQueue.hpp" namespace CreatureLib::Battling { class Battle { const BattleLibrary* _library; + uint8_t _numberOfSides; + uint8_t _creaturesPerSide; std::vector _sides; + + ChoiceQueue* _currentTurnQueue = nullptr; public: const BattleLibrary* GetLibrary() const; virtual bool CanUse(BaseTurnChoice* choice); virtual bool TrySetChoice(BaseTurnChoice* choice); + + void CheckChoicesSetAndRun(); + + ChoiceQueue* GetCurrentTurnQueue() const; }; } diff --git a/src/Battling/TurnChoices/AttackTurnChoice.hpp b/src/Battling/TurnChoices/AttackTurnChoice.hpp index 87d46ca..96ff886 100644 --- a/src/Battling/TurnChoices/AttackTurnChoice.hpp +++ b/src/Battling/TurnChoices/AttackTurnChoice.hpp @@ -8,11 +8,16 @@ namespace CreatureLib::Battling{ class AttackTurnChoice : public BaseTurnChoice { LearnedAttack* _attack; public: - AttackTurnChoice(Creature* c) : BaseTurnChoice(c){} + AttackTurnChoice(Creature* c, LearnedAttack* attack) + : BaseTurnChoice(c), _attack(attack){} inline LearnedAttack* GetAttack() const{ return _attack; } + + TurnChoiceKind GetKind() const override { + return TurnChoiceKind ::Attack; + } }; } diff --git a/src/Battling/TurnChoices/BaseTurnChoice.hpp b/src/Battling/TurnChoices/BaseTurnChoice.hpp index 9dfbe1b..05e150d 100644 --- a/src/Battling/TurnChoices/BaseTurnChoice.hpp +++ b/src/Battling/TurnChoices/BaseTurnChoice.hpp @@ -4,6 +4,8 @@ #include "TurnChoiceKind.hpp" namespace CreatureLib::Battling{ + class Creature; + class BaseTurnChoice { Creature* _user; protected: diff --git a/tests/BattleTests/TurnOrderTests.cpp b/tests/BattleTests/TurnOrderTests.cpp new file mode 100644 index 0000000..21db5c1 --- /dev/null +++ b/tests/BattleTests/TurnOrderTests.cpp @@ -0,0 +1,26 @@ +#ifdef TESTS_BUILD + +#include "../TestLibrary/TestLibrary.cpp" +#include "../../src/Battling/TurnChoices/PassTurnChoice.hpp" +#include "../../src/Battling/TurnChoices/AttackTurnChoice.hpp" +#include "../../src/Battling/Flow/TurnOrdering.hpp" + +using namespace CreatureLib::Battling; + +TEST_CASE( "Turn ordering: Attack before pass", "[Battling]" ) { + auto choice1 = new PassTurnChoice(nullptr); + auto choice2 = new AttackTurnChoice(nullptr, nullptr); + auto vec = std::vector{choice1, choice2}; + TurnOrdering::OrderChoices(vec); + CHECK(vec[0] == choice2); + CHECK(vec[1] == choice1); + vec = std::vector{choice2, choice1}; + TurnOrdering::OrderChoices(vec); + CHECK(vec[0] == choice2); + CHECK(vec[1] == choice1); + + delete choice1; + delete choice2; +} + +#endif \ No newline at end of file