-
Notifications
You must be signed in to change notification settings - Fork 0
/
Field.cpp
138 lines (122 loc) · 4.05 KB
/
Field.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "Field.h"
Field::Field()
{
m_field.resize(100);
for (auto& e : m_field) {
e.resize(100);
}
}
void Field::draw(sf::RenderWindow& window)
{
for (unsigned int i = 0; i < m_field.size(); i++) {
for (unsigned int j = 0; j < m_field.at(i).size(); j++) {
m_field.at(i).at(j).draw(window, i, j);
m_field.at(i).at(j).m_row = i;
m_field.at(i).at(j).m_column = j;
}
}
}
void Field::prims_alg(sf::RenderWindow& window)
{
int rnd_row = rnd_number(m_field.size() - 1);
int rnd_column = rnd_number(m_field.front().size() - 1);
m_field.at(rnd_row).at(rnd_column).wall = false;
m_field.at(rnd_row).at(rnd_column).visited = true;
int start_row = m_field.at(rnd_row).at(rnd_column).m_row;
int start_column = m_field.at(rnd_row).at(rnd_column).m_column;
add_walls(start_row, start_column);
while (!w_list.empty()) {
int c_n = rnd_number(w_list.size() - 1);
point a_p = w_list.at(c_n);
int a_row = m_field.at(a_p.x).at(a_p.y).m_row;
int a_column = m_field.at(a_p.x).at(a_p.y).m_column;
if (auto u_c = is_wall_visited_w(a_row, a_column)) {
m_field.at(u_c->x).at(u_c->y).visited = true;
m_field.at(u_c->x).at(u_c->y).wall = false;
m_field.at(a_p.x).at(a_p.y).wall = false;
//add_walls(a_row, a_column);
add_walls(u_c->x, u_c->y);
}
if(auto u_c = is_wall_visited_s(a_row, a_column)) {
m_field.at(u_c->x).at(u_c->y).visited = true;
m_field.at(u_c->x).at(u_c->y).wall = false;
m_field.at(a_p.x).at(a_p.y).wall = false;
//add_walls(a_row, a_column);
add_walls(u_c->x, u_c->y);
}
w_list.erase(w_list.begin() + c_n);
m_field.at(a_p.x).at(a_p.y).visited = true;
update(window);
window.display();
}
}
void Field::update(sf::RenderWindow& window)
{
for (unsigned int i = 0; i < m_field.size(); i++) {
for (unsigned int j = 0; j < m_field.at(i).size(); j++) {
if (!m_field.at(i).at(j).wall) {
m_field.at(i).at(j).change_color(window, sf::Color::White);
}
else {
m_field.at(i).at(j).change_color(window, sf::Color::Black);
}
}
}
}
bool Field::in_bounds(int row, int column)
{
return row < m_field.size() && column < m_field.front().size()
&& row >= 0 && column >= 0;
}
std::optional<point> Field::is_wall_visited_w(int row, int column)
{
if (in_bounds(row + 1, column) && m_field.at(row + 1).at(column).visited &&
in_bounds(row - 1, column) && !m_field.at(row - 1).at(column).visited) {
return point(row - 1, column);
}
else if (in_bounds(row - 1, column) && m_field.at(row - 1).at(column).visited &&
in_bounds(row + 1, column) && !m_field.at(row + 1).at(column).visited) {
return point(row + 1, column);
}
return {};
}
std::optional<point> Field::is_wall_visited_s(int row, int column)
{
if (in_bounds(row, column + 1) && m_field.at(row).at(column + 1).visited &&
in_bounds(row, column -1) && !m_field.at(row).at(column - 1).visited) {
return point(row, column - 1);
}
else if (in_bounds(row, column - 1) && m_field.at(row).at(column - 1).visited &&
in_bounds(row, column + 1) && !m_field.at(row).at(column + 1).visited) {
return point(row, column + 1);
}
return {};
}
void Field::add_walls(int row, int column)
{
if (in_bounds(row + 1, column) && m_field.at(row + 1).at(column).wall) {
//m_field.at(row + 1).at(column).visited = true;
w_list.push_back(point(row +1 , column));
}
if (in_bounds(row - 1, column) && m_field.at(row - 1).at(column).wall) {
//m_field.at(row - 1).at(column).visited = true;
w_list.push_back(point(row - 1, column));
}
if (in_bounds(row, column + 1) && m_field.at(row).at(column + 1).wall) {
//m_field.at(row).at(column + 1).visited = true;
w_list.push_back(point(row, column + 1));
}
if (in_bounds(row, column - 1) && m_field.at(row).at(column - 1).wall) {
//m_field.at(row).at(column - 1).visited = true;
w_list.push_back(point(row, column - 1));
}
}
int Field::rnd_number(int s)
{
int n = 0;
std::random_device dev;
std::mt19937 genr(dev());
std::uniform_int_distribution<int> dis(0, s);
n = dis(dev);
return n;
}