-
Notifications
You must be signed in to change notification settings - Fork 0
Task 10 #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Task 10 #2
Changes from all commits
c3058b9
ab9df4e
cf76b89
dced4f1
ab80e5f
6a71180
5a49c52
26cb0ff
a442304
b3a3245
3bd31b1
2af4347
59db137
df3698f
ec25868
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| *.exe | ||
| *.vcxproj.user | ||
| *.obj | ||
| *.log | ||
| *.pdb | ||
| *.idb | ||
| *.tlog | ||
| *.lastbuildstate | ||
| *.ilk | ||
| *.exe.recipe | ||
| *.vcxproj | ||
| *.sln | ||
| *.vcxproj.filters |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| #pragma once | ||
|
|
||
| class MCell { | ||
| public: | ||
| bool down() const { return m_down; } | ||
| bool right() const { return m_right; } | ||
| friend class Maze; | ||
| private: | ||
| MCell() = default; | ||
| bool m_down = false; | ||
| bool m_right = false; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| #include <algorithm> | ||
| #include <iostream> | ||
| #include <queue> | ||
| #include "MTreeNode.h" | ||
| using namespace std; | ||
|
|
||
| MTreeNode* MTreeNode::beginTree(int i, int j) { | ||
| MTreeNode* node = new MTreeNode(nullptr); | ||
This comment was marked as resolved.
Sorry, something went wrong.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тут утечка, верно? Кстати говоря, я вызывал delete для корня дерева в practise_18.11.20.cpp в случае построения второго лабиринта (про третий благополучно забыл). Но я догадываюсь, что это не есть хорошо. Можете намекнуть на пример корректного поведения для beginTree? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Извиняюсь, запутался... Всё норм. |
||
| node->m_i = i; | ||
| node->m_j = j; | ||
| return node; | ||
| } | ||
|
|
||
| MTreeNode::MTreeNode(MTreeNode* parent) { | ||
| m_parent = parent; | ||
| if (parent) m_distance = parent->m_distance + 1; | ||
| } | ||
|
|
||
| MTreeNode::~MTreeNode() { | ||
| for (auto ptr : m_children) | ||
| delete ptr; | ||
This comment was marked as resolved.
Sorry, something went wrong.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Речь о том, что я мог просто вызвать delete[] ? Или я оставляю в памяти висеть детей того родителя, у которого вызывается деструктор? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Сорян, всё норм. Я уже обревьювился в конец... |
||
| } | ||
|
|
||
| bool MTreeNode::addChild(int i, int j) { | ||
| if (abs(i - m_i + j - m_j) != 1) | ||
| return false; | ||
|
|
||
| for (auto &child : m_children) | ||
| if (child->m_i == i && child->m_j == j) | ||
| return false; | ||
| m_children.push_back(new MTreeNode(this)); | ||
This comment was marked as resolved.
Sorry, something went wrong. |
||
| m_children.back()->m_i = i; | ||
| m_children.back()->m_j = j; | ||
| return true; | ||
| } | ||
|
|
||
| MTreeNode* MTreeNode::hasChild(int i, int j) const{ | ||
| for (auto child : m_children){ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Разумно не делать копии, то есть auto& |
||
| if (child->m_i == i && child->m_j == j) | ||
| return child; | ||
| } | ||
| return nullptr; | ||
| } | ||
|
|
||
| //�����, ����������� ����� ���� � ������ ������� �� ����� | ||
| const MTreeNode* MTreeNode::searchNode(const int i, const int j) const{ | ||
| queue<MTreeNode*> nodes; | ||
| auto node = searchRoot(this); | ||
| while (true) | ||
| { | ||
| if (node->m_i == i && node->m_j == j) return node; | ||
| for (const auto child : node->m_children) { | ||
| if (child->i() == i && child->j() == j) | ||
| return child; | ||
| nodes.push(child); | ||
| } | ||
| if (nodes.size() == 0) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Это можно вынести в while, так то!
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Я могу заблуждаться, но ведь есть ситуация при которой мы достанем новый узел из очереди и она опустеет, однако этот узел будет иметь детей, которых потом также потребуется обойти. Мы прервем цикл до их обхода. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ошибаетесь, подумайте... |
||
| break; | ||
| node = nodes.front(); | ||
| nodes.pop(); | ||
| } | ||
| } | ||
|
|
||
| //����� ������ ����� � ����� | ||
| const MTreeNode* MTreeNode::searchRoot(const MTreeNode* node) const{ | ||
| queue<MTreeNode*> nodes; | ||
| MTreeNode* parent = node->m_parent; | ||
| if (!parent) | ||
| return node; | ||
| else { | ||
| while (true) { | ||
| MTreeNode* temp = parent->m_parent; | ||
| if (!temp) break; | ||
| parent = temp; | ||
| } | ||
| return parent; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| #pragma once | ||
| #include <vector> | ||
|
|
||
| class MTreeNode | ||
| { | ||
| public: | ||
| ~MTreeNode(); | ||
| int i() const { return m_i; } | ||
| int j() const { return m_j; } | ||
| int distance() const { return m_distance; } | ||
| int childCount() const { return m_children.size(); } | ||
| bool addChild(int i, int j); | ||
| const MTreeNode* parent() const { return m_parent; } | ||
| MTreeNode* hasChild(int i, int j) const; | ||
| const MTreeNode* child(int i) const { return m_children[i]; } | ||
| static MTreeNode* beginTree(int i, int j); | ||
| const MTreeNode* searchNode(const int i, const int j) const; | ||
| const MTreeNode* searchRoot(const MTreeNode* node) const; | ||
| private: | ||
| int m_i, m_j = 0; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Что-то тут копипастой запахло.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Вы сказали, что бы я исправил былое безобразие. Вы мне вариантом предложили сделать отдельный метод для поиска корня, если я хочу не зависеть от передаваемого узла. Я так и поступил. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Дык не про то речь... Ну и ладно... |
||
| int m_distance = 0; | ||
| MTreeNode* m_parent = nullptr; | ||
| std::vector<MTreeNode*> m_children; | ||
| MTreeNode(MTreeNode* parent); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| #include <algorithm> | ||
| #include <iostream> | ||
| #include <map> | ||
| #include "Maze.h" | ||
| #include <cassert> | ||
| using namespace std; | ||
|
|
||
| enum MazeElem { | ||
| Up = 1 << 0, | ||
| Left = 1 << 1, | ||
| Down = 1 << 2, | ||
| Right = 1 << 3, | ||
| UpLeft = Up + Left, | ||
| UpDown = Up + Down, | ||
| UpRight = Up + Right, | ||
| LeftDown = Left + Down, | ||
| LeftRight = Left + Right, | ||
| RightDown = Right + Down, | ||
| UpLeftDown = Up + Left + Down, | ||
| UpLeftRight = Up + Left + Right, | ||
| UpDownRight = Up + Down + Right, | ||
| LeftDownRight = Left + Down + Right, | ||
| AllDirection = Up + Left + Down + Right, | ||
| }; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Наркота то какая.... Наркотаааааа....." |
||
| static map<int, char> m_dict = { {AllDirection, char(197)}, {UpLeftDown, char(180)}, {UpLeftRight, char(193)}, | ||
| {UpDownRight, char(195)}, {LeftDownRight, char(194)}, {UpLeft, char(217)}, | ||
| {UpDown, char(179)}, {UpRight, char(192)}, {LeftDown, char(191)}, | ||
| {LeftRight, char(196)}, {RightDown, char(218)}, {Up, '0'}, {Down, '0'}, {Left, '0'}, {Right, '0'}, {0, '0'} | ||
| }; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Молодца! статик! |
||
|
|
||
| Maze::Maze(int n, int m) { | ||
| m_width = m; | ||
| m_height = n; | ||
| m_field = new MCell[m * n]; | ||
| } | ||
|
|
||
| Maze::~Maze() { delete[] m_field; } | ||
|
|
||
| const MCell& Maze::cell(int i, int j) const { | ||
| assert(i >= 0 && i < m_height && j >= 0 && j < m_width); | ||
| return m_field[i * m_width + j]; | ||
| } | ||
|
|
||
| bool Maze::checkConnection(int i1, int j1, int i2, int j2) const { | ||
| assert(i1 == i2 || j1 == j2); | ||
| if ((abs(i1 - i2) + abs(j1 - j2) != 1)) | ||
| return false; | ||
| if (j2 < 0 || j2 >= m_width || i2 < 0 || i2 >= m_height) | ||
| return false; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Может вынести эти штучки отдельно. А то дублирование получается. Ниже то же самое написано... |
||
| } | ||
|
|
||
| bool Maze::hasConnection(int i1, int j1, int i2, int j2) const { | ||
| if (!checkConnection(i1, j1, i2, j2)) | ||
| return false; | ||
| const int ind1 = min(i1, i2); | ||
| const int ind2 = min(j1, j2); | ||
| if (i1 == i2) { | ||
| return m_field[ind1 * m_width + ind2].right(); | ||
| } | ||
| else if (j2 == j1) { | ||
| return m_field[ind1 * m_width + ind2].down(); | ||
| } | ||
| } | ||
|
|
||
| bool Maze::makeConnection(int i1, int j1, int i2, int j2) { | ||
| if (!checkConnection(i1, j1, i2, j2)) | ||
| return false; | ||
| const int ind1 = min(i1, i2); | ||
| const int ind2 = min(j1, j2); | ||
| if (i1 == i2) { | ||
| m_field[ind1 * m_width + ind2].m_right = true; | ||
| return true; | ||
| } | ||
| else if (j1 == j2) { | ||
| m_field[ind1 * m_width + ind2].m_down = true; | ||
| return true; | ||
| } | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тут при неправильных индексах надо бы ассерт сделать. Хотя и не обязательно. |
||
|
|
||
| bool Maze::removeConnection(int i1, int j1, int i2, int j2) { | ||
| if (!checkConnection(i1, j1, i2, j2)) | ||
| return false; | ||
| int ind1 = min(i1, i2); | ||
| int ind2 = min(j1, j2); | ||
| if (i1 == i2) { | ||
| bool res = m_field[ind1 * m_width + ind2].m_right; | ||
| m_field[ind1 * m_width + ind2].m_right = false; | ||
| return res; | ||
| } | ||
| else if (j2 == j1) { | ||
| bool res = m_field[ind1 * m_width + ind2].m_down; | ||
| m_field[ind1 * m_width + ind2].m_down = false; | ||
| return res; | ||
| } | ||
| } | ||
|
|
||
| void Maze::printMaze() const { | ||
| for (int n = 0; n < m_width * m_height; ++n) { | ||
| int i = n / m_width; | ||
| int j = n % m_width; | ||
| int res = m_field[n].down() << 2 | m_field[n].right() << 3; | ||
| if (i - 1 >= 0) | ||
| res += m_field[(i - 1) * m_width + j].down() << 0; | ||
| if (j - 1 >= 0) | ||
| res += m_field[i * m_width + j - 1].right() << 1; | ||
|
|
||
| assert(typeid(m_dict.find(res)->second) == typeid(char)); | ||
| cout << m_dict.find(res)->second; | ||
|
|
||
| if (j + 1 == m_width) | ||
| cout << endl; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| #pragma once | ||
| #include "MCell.h" | ||
|
|
||
| class Maze { | ||
| public: | ||
| Maze(int n, int m); | ||
| ~Maze(); | ||
| const MCell& cell(int i, int j) const; | ||
| bool checkConnection(int i1, int j1, int i2, int j2) const; | ||
| bool hasConnection(int i1, int j1, int i2, int j2) const; | ||
| bool makeConnection(int i1, int j1, int i2, int j2); | ||
| bool removeConnection(int i1, int j1, int i2, int j2); | ||
| void printMaze() const; | ||
| private: | ||
| MCell* m_field = nullptr; | ||
| int m_width = 0; | ||
| int m_height = 0; | ||
| }; |
This comment was marked as resolved.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.