From 23937d561bc52ffb1023665a6a3500b5c763524e Mon Sep 17 00:00:00 2001 From: Trifon Trifonov Date: Thu, 3 Nov 2022 12:01:16 +0200 Subject: [PATCH] =?UTF-8?q?=D0=A5=D0=BE=D0=B4=20=D0=BD=D0=B0=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BD=D1=8F=20=D1=81=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=B2=D1=8A=D0=BB=D0=BD=D0=B0=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lectures/1/horse/CMakeLists.txt | 5 +-- lectures/1/horse/horse_tests.hpp | 26 +++++++++------- lectures/1/horse/queue_horsewalker.cpp | 42 ++++++++++++++++++++++++++ lectures/1/horse/queue_horsewalker.hpp | 22 ++++++++++++++ 4 files changed, 82 insertions(+), 13 deletions(-) create mode 100644 lectures/1/horse/queue_horsewalker.cpp create mode 100644 lectures/1/horse/queue_horsewalker.hpp diff --git a/lectures/1/horse/CMakeLists.txt b/lectures/1/horse/CMakeLists.txt index 93deb76..97a461a 100644 --- a/lectures/1/horse/CMakeLists.txt +++ b/lectures/1/horse/CMakeLists.txt @@ -7,8 +7,9 @@ enable_testing() add_executable(horse main.cpp horsewalker.cpp recursive_horsewalker.cpp - stack_horsewalker.cpp) -include_directories(../common ../stack) + stack_horsewalker.cpp + queue_horsewalker.cpp) +include_directories(../common ../stack ../queue) set(CPACK_PROJECT_NAME ${PROJECT_NAME}) set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) diff --git a/lectures/1/horse/horse_tests.hpp b/lectures/1/horse/horse_tests.hpp index a8cb1d2..9b3f36c 100644 --- a/lectures/1/horse/horse_tests.hpp +++ b/lectures/1/horse/horse_tests.hpp @@ -2,54 +2,58 @@ #include "doctest.h" #include "recursive_horsewalker.hpp" #include "stack_horsewalker.hpp" +#include "queue_horsewalker.hpp" + +#define ALL_HORSEWALKERS RecursiveHorseWalker, StackHorseWalker, QueueHorseWalker TYPE_TO_STRING(RecursiveHorseWalker); TYPE_TO_STRING(StackHorseWalker); +TYPE_TO_STRING(QueueHorseWalker); TEST_CASE_TEMPLATE("Никъде не можем да стигнем от невалидна стартова позиция", - AnyHorseWalker, RecursiveHorseWalker, StackHorseWalker) { + AnyHorseWalker, ALL_HORSEWALKERS) { AnyHorseWalker horseWalker(4); CHECK_FALSE(horseWalker.existsWalk({-1, 0}, {3, 3})); } TEST_CASE_TEMPLATE("Не можем да стигнем до невалидна крайна позиция", - AnyHorseWalker, RecursiveHorseWalker, StackHorseWalker) { + AnyHorseWalker, ALL_HORSEWALKERS) { AnyHorseWalker horseWalker(4); CHECK_FALSE(horseWalker.existsWalk({0, 0}, {3, 5})); } TEST_CASE_TEMPLATE("Началната и крайната позиция съвпадат", - AnyHorseWalker, RecursiveHorseWalker, StackHorseWalker) { + AnyHorseWalker, ALL_HORSEWALKERS) { AnyHorseWalker horseWalker(4); CHECK(horseWalker.existsWalk({0, 0}, {0, 0})); } TEST_CASE_TEMPLATE("На дъска 4x4 можем да стигнем от (0,0) до (3,3)", - AnyHorseWalker, RecursiveHorseWalker, StackHorseWalker) { + AnyHorseWalker, ALL_HORSEWALKERS) { AnyHorseWalker horseWalker(4); CHECK(horseWalker.existsWalk({0, 0}, {3, 3})); } TEST_CASE_TEMPLATE("На дъска 4x4 можем да стигнем от (0,0) до (2,2)", - AnyHorseWalker, RecursiveHorseWalker, StackHorseWalker) { + AnyHorseWalker, ALL_HORSEWALKERS) { AnyHorseWalker horseWalker(4); CHECK(horseWalker.existsWalk({0, 0}, {2, 2})); } TEST_CASE_TEMPLATE("На дъска 4x4 можем да стигнем от (0,0) до (0,1)", - AnyHorseWalker, RecursiveHorseWalker, StackHorseWalker) { + AnyHorseWalker, ALL_HORSEWALKERS) { AnyHorseWalker horseWalker(4); CHECK(horseWalker.existsWalk({0, 0}, {0, 1})); } TEST_CASE_TEMPLATE("На дъска 3x3 не можем да стигнем от (0,0) до (1,1)", - AnyHorseWalker, RecursiveHorseWalker, StackHorseWalker) { + AnyHorseWalker, ALL_HORSEWALKERS) { AnyHorseWalker horseWalker(3); CHECK_FALSE(horseWalker.existsWalk({0, 0}, {1, 1})); } TEST_CASE_TEMPLATE("На дъска 4x4 всички позиции да достижими от (0,0)", - AnyHorseWalker, RecursiveHorseWalker, StackHorseWalker) { + AnyHorseWalker, ALL_HORSEWALKERS) { size_t SIZE = 4; for(int i = 0; i < SIZE; i++) for(int j = 0; j < SIZE; j++) { @@ -96,21 +100,21 @@ bool isValidWalk(HorseWalk const& walk, size_t boardSize, } TEST_CASE_TEMPLATE("На дъска 4x4 намираме правилна разходка от (0,0) до (3,3)", - AnyHorseWalker, RecursiveHorseWalker, StackHorseWalker) { + AnyHorseWalker, ALL_HORSEWALKERS) { AnyHorseWalker horseWalker(4); Position from{0, 0}, to{3, 3}; CHECK(isValidWalk(horseWalker.findWalk(from, to), 4, from, to)); } TEST_CASE_TEMPLATE("На дъска 4x4 намираме правилна разходка от (0,0) до (2,2)", - AnyHorseWalker, RecursiveHorseWalker, StackHorseWalker) { + AnyHorseWalker, ALL_HORSEWALKERS) { AnyHorseWalker horseWalker(4); Position from{0, 0}, to{2, 2}; CHECK(isValidWalk(horseWalker.findWalk(from, to), 4, from, to)); } TEST_CASE_TEMPLATE("На дъска 4x4 за всички позиции намираме правилна разходка от (0,0)", - AnyHorseWalker, RecursiveHorseWalker, StackHorseWalker) { + AnyHorseWalker, ALL_HORSEWALKERS) { size_t SIZE = 4; for(int i = 0; i < SIZE; i++) for(int j = 0; j < SIZE; j++) { diff --git a/lectures/1/horse/queue_horsewalker.cpp b/lectures/1/horse/queue_horsewalker.cpp new file mode 100644 index 0000000..57d70af --- /dev/null +++ b/lectures/1/horse/queue_horsewalker.cpp @@ -0,0 +1,42 @@ +#include "queue_horsewalker.hpp" + +HorseWalk const& QueueHorseWalker::findWalk(Position const& start, Position const& end) { + if (!insideBoard(end)) + return walk; + horseWave.enqueue(start); + while (!horseWave.empty()) { + Position current = horseWave.dequeue(); + if (current == end) { + // успех + LinkedStack reversedWalk; + + while (!steps.empty()) { + Step step = steps.pop(); + if (step.second == current) { + reversedWalk.push(current); + current = step.first; + } + } + reversedWalk.push(start); + while (!reversedWalk.empty()) + walk.push_back(reversedWalk.pop()); + return walk; + } + + if (insideBoard(current) && !board[current.first][current.second]) { + // стъпваме на тази позиция + board[current.first][current.second] = true; + // добавяме всички следващи стъпки + for(int dx = -2; dx <= 2; dx++) + if (dx != 0) + for (int sign : {-1, 1}) { + int dy = sign * (3 - std::abs(dx)); + Position newPosition{current.first + dx, current.second + dy}; + horseWave.enqueue(newPosition); + steps.push({current, newPosition}); + } + } + } + // не успяхме да стигнем до края + return walk; +} diff --git a/lectures/1/horse/queue_horsewalker.hpp b/lectures/1/horse/queue_horsewalker.hpp new file mode 100644 index 0000000..d06569f --- /dev/null +++ b/lectures/1/horse/queue_horsewalker.hpp @@ -0,0 +1,22 @@ +#ifndef __QUEUE_HORSEWALKER_HPP +#define __QUEUE_HORSEWALKER_HPP + +#include "horsewalker.hpp" +#include "lqueue.hpp" +#include "lstack.hpp" + +using Step = std::pair; + +class QueueHorseWalker : public HorseWalker { + LinkedQueue horseWave; + HorseWalk walk; + LinkedStack steps; +public: + QueueHorseWalker(size_t size) : HorseWalker(size) {} + + // намира разходка на коня от start до end + // връща празна разходка, ако не съществува + virtual HorseWalk const& findWalk(Position const& start, Position const& end); +}; + +#endif \ No newline at end of file