Finished generation of solveable map (rev 1)
This commit is contained in:
parent
827f3ccdf6
commit
f80c95e75e
166
Controller.cpp
166
Controller.cpp
@ -35,65 +35,147 @@ void Controller::fill(bool solveable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Controller::fillSolveableTable() {
|
void Controller::fillSolveableTable() {
|
||||||
time_t start_time = time(NULL);
|
srand(time(NULL));
|
||||||
|
|
||||||
std::list<ThreePoint> positions;
|
auto not_end = remaining;
|
||||||
|
|
||||||
int overall = gridSize.z * gridSize.x * gridSize.y;
|
std::set<ThreePoint> positions;
|
||||||
int pos = rand() % overall;
|
|
||||||
int z, x, y;
|
|
||||||
|
|
||||||
do {
|
positions.insert(getRandLowest());
|
||||||
z = pos / (gridSize.x * gridSize.y);
|
|
||||||
x = (pos / gridSize.y) % gridSize.x;
|
|
||||||
y = pos % gridSize.y;
|
|
||||||
} while (table[z][x][y] != FREE);
|
|
||||||
|
|
||||||
positions.push_back({z, x, y});
|
auto next_ptr = positions.begin();
|
||||||
|
|
||||||
int past_pos = 0;
|
while (!positions.empty() || (not_end && !(positions.insert(getRandLowest()), positions.empty()))) {
|
||||||
auto past_ptr = positions.begin();
|
|
||||||
|
|
||||||
while (!positions.empty()) {
|
|
||||||
int id = genRandId();
|
int id = genRandId();
|
||||||
|
|
||||||
if (id < 34) {
|
if (id < 34) {
|
||||||
past_pos = emplace_rand(id, positions, past_pos, past_ptr);
|
emplace_rand(id, positions, next_ptr, true);
|
||||||
past_pos = emplace_rand(id, positions, past_pos, past_ptr);
|
emplace_rand(id, positions, next_ptr, false);
|
||||||
|
|
||||||
cardsCounter[id]--;
|
cardsCounter[id]--;
|
||||||
} else
|
not_end -= 2;
|
||||||
emplace_rand(id, positions, past_pos, past_ptr);
|
} else {
|
||||||
|
emplace_rand(id, positions, next_ptr, true);
|
||||||
|
not_end--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxLogInfo(
|
|
||||||
wxString::Format("Filling took %i seconds", start_time - time(NULL)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Controller::emplace_rand(int id, std::list<ThreePoint> positions,
|
wxPoint Controller::getRandLowest() {
|
||||||
int past_pos,
|
int overall = gridSize.x * gridSize.y;
|
||||||
std::list<ThreePoint>::iterator past_ptr) {
|
int x, y;
|
||||||
int d = rand() % positions.size() - past_pos;
|
|
||||||
|
|
||||||
if (d > 0)
|
do {
|
||||||
for (int i = 0; i < d; i++)
|
int pos = rand() % overall;
|
||||||
past_ptr++;
|
x = (pos / gridSize.y) % gridSize.x;
|
||||||
else
|
y = pos % gridSize.y;
|
||||||
for (int i = 0; i > d; i--)
|
} while (table[0][x][y] != FREE);
|
||||||
past_ptr--;
|
|
||||||
|
|
||||||
past_pos += d;
|
return {x, y};
|
||||||
|
}
|
||||||
|
|
||||||
table[past_ptr->z][past_ptr->x][past_ptr->y] = id;
|
#include <wx/file.h>
|
||||||
|
|
||||||
// if ()
|
void print_list(const std::set<ThreePoint>& positions) {
|
||||||
// positions.push_back({})
|
wxFile f("tmp.txt", wxFile::write_append);
|
||||||
|
|
||||||
|
for (const auto& el : positions)
|
||||||
|
f.Write(itowxS(el.z) + " " + itowxS(el.x) + " " + itowxS(el.y) + "\n");
|
||||||
|
|
||||||
|
f.Write("_ size: " + itowxS(positions.size()) + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
void Controller::emplace_rand(int id, std::set<ThreePoint>& positions,
|
||||||
* TODO: random move and positions adding
|
std::set<ThreePoint>::iterator& next_ptr,
|
||||||
*/
|
bool canBeUp) {
|
||||||
|
print_list(positions);
|
||||||
|
|
||||||
return 0;
|
table[next_ptr->z][next_ptr->x][next_ptr->y] = id;
|
||||||
|
|
||||||
|
push_available(positions, *next_ptr);
|
||||||
|
|
||||||
|
auto prev_ptr = next_ptr;
|
||||||
|
auto prev = *next_ptr;
|
||||||
|
|
||||||
|
do {
|
||||||
|
next_ptr++;
|
||||||
|
|
||||||
|
if (next_ptr == positions.end())
|
||||||
|
next_ptr = positions.begin();
|
||||||
|
} while (!canBeUp && !wouldBeUpFree(prev, *next_ptr));
|
||||||
|
|
||||||
|
positions.erase(prev_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller::wouldBeUpFree(const ThreePoint& prev, const ThreePoint& next) {
|
||||||
|
table[next.z][next.x][next.y] = 1;
|
||||||
|
|
||||||
|
bool res = upFree(prev);
|
||||||
|
|
||||||
|
table[next.z][next.x][next.y] = FREE;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::push_available(std::set<ThreePoint>& positions,
|
||||||
|
const ThreePoint& pos) {
|
||||||
|
int z = pos.z, x = pos.x, y = pos.y;
|
||||||
|
|
||||||
|
if (x >= 2 && table[z][x-2][y] == FREE) // left
|
||||||
|
positions.emplace(z, x-2, y);
|
||||||
|
if (x + 2 < gridSize.x && table[z][x+2][y] == FREE) // right
|
||||||
|
positions.emplace(z, x+2, y);
|
||||||
|
|
||||||
|
if (y >= 1 && (y < 2 || table[z][x][y-2] != FREE)) { // half bottom
|
||||||
|
if (x >= 2 && table[z][x-2][y-1] == FREE) // left
|
||||||
|
positions.emplace(z, x-2, y-1);
|
||||||
|
if (x + 2 < gridSize.x && table[z][x+2][y-1] == FREE) // right
|
||||||
|
positions.emplace(z, x+2, y-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y + 1 < gridSize.y && (y + 2 >= gridSize.y || table[z][x][y+2] != FREE)) { // half bottom
|
||||||
|
if (x >= 2 && table[z][x-2][y+1] == FREE) // left
|
||||||
|
positions.emplace(z, x-2, y+1);
|
||||||
|
if (x + 2 < gridSize.x && table[z][x+2][y+1] == FREE) // right
|
||||||
|
positions.emplace(z, x+2, y+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y >= 2 && table[z][x][y-2] == FREE) // up
|
||||||
|
positions.emplace(z, x, y-2);
|
||||||
|
if (y + 2 < gridSize.y && table[z][x][y+2] == FREE) // bottom
|
||||||
|
positions.emplace(z, x, y+2);
|
||||||
|
|
||||||
|
if (z + 1 < gridSize.z) { // higher
|
||||||
|
if (table[z+1][x][y] == FREE) // straight
|
||||||
|
positions.emplace(z+1, x, y);
|
||||||
|
|
||||||
|
if (y >= 1 && (y < 2 || table[z][x][y-2] != FREE) && table[z+1][x][y-1] == FREE) // half top
|
||||||
|
positions.emplace(z+1, x, y-1);
|
||||||
|
if (y + 1 < gridSize.y && (y + 2 >= gridSize.y || table[z][x][y+2] != FREE) && table[z+1][x][y+1] == FREE) // half bottom
|
||||||
|
positions.emplace(z+1, x, y+1);
|
||||||
|
|
||||||
|
if (x >= 1 && (x < 2 || table[z][x-2][y] != FREE)) {// half left
|
||||||
|
if (table[z+1][x-1][y] == FREE) // straight
|
||||||
|
positions.emplace(z+1, x-1, y);
|
||||||
|
|
||||||
|
if (y >= 1 && (x < 2 || table[z][x-2][y-1] != FREE) && table[z+1][x-1][y-1] == FREE) // half top
|
||||||
|
positions.emplace(z+1, x-1, y-1);
|
||||||
|
|
||||||
|
if (y + 1 < gridSize.y && (x < 2 || table[z][x-2][y+1] != FREE) && table[z+1][x-1][y+1] == FREE) //half bottom
|
||||||
|
positions.emplace(z+1, x-1, y+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x + 1 < gridSize.x && (x + 2 >= gridSize.x || table[z][x+2][y] != FREE)) { // half right
|
||||||
|
if (table[z+1][x+1][y] == FREE) // straight
|
||||||
|
positions.emplace(z+1, x+1, y);
|
||||||
|
|
||||||
|
if (y >= 1 && (x + 2 >= gridSize.x || table[z][x+2][y-1] != FREE) && table[z+1][x+1][y-1] == FREE) // half top
|
||||||
|
positions.emplace(z+1, x+1, y-1);
|
||||||
|
|
||||||
|
if (y + 1 < gridSize.y && (x + 2 >= gridSize.x || table[z][x+2][y+1] != FREE) && table[z+1][x+1][y+1] == FREE) //half bottom
|
||||||
|
positions.emplace(z+1, x+1, y+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::free_table() {
|
void Controller::free_table() {
|
||||||
@ -115,7 +197,7 @@ void Controller::free_table() {
|
|||||||
void Controller::fillRandom() {
|
void Controller::fillRandom() {
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
|
|
||||||
wxLogDebug(wxString::Format("%i", remaining));
|
wxLogDebug(itowxS(remaining));
|
||||||
|
|
||||||
auto not_end = remaining;
|
auto not_end = remaining;
|
||||||
|
|
||||||
@ -261,7 +343,7 @@ void Controller::handleClick(const wxPoint& point) {
|
|||||||
ThreePoint pos = {-1, posPlain.x, posPlain.y};
|
ThreePoint pos = {-1, posPlain.x, posPlain.y};
|
||||||
|
|
||||||
if (pos.x > -1) {
|
if (pos.x > -1) {
|
||||||
auto card = getCardByPosition(pos);
|
CardT* card = getCardByPosition(pos);
|
||||||
|
|
||||||
if (pos.z >= 0 && available(pos)) {
|
if (pos.z >= 0 && available(pos)) {
|
||||||
if (selected != nullptr && sameValues(*card, *selected) &&
|
if (selected != nullptr && sameValues(*card, *selected) &&
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define CONTROLLER_H
|
#define CONTROLLER_H
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <list>
|
#include <set>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
#include "wxw.h"
|
#include "wxw.h"
|
||||||
@ -43,8 +43,11 @@ private:
|
|||||||
CardT* selected = nullptr;
|
CardT* selected = nullptr;
|
||||||
|
|
||||||
void fillSolveableTable();
|
void fillSolveableTable();
|
||||||
int emplace_rand(int id, std::list<ThreePoint> positions, int past_pos,
|
wxPoint getRandLowest();
|
||||||
std::list<ThreePoint>::iterator past_ptr);
|
void emplace_rand(int id, std::set<ThreePoint>& positions,
|
||||||
|
std::set<ThreePoint>::iterator& next_ptr, bool canBeUp);
|
||||||
|
bool wouldBeUpFree(const ThreePoint& prev, const ThreePoint& next);
|
||||||
|
void push_available(std::set<ThreePoint>& positions, const ThreePoint& pos);
|
||||||
|
|
||||||
void fillRandom();
|
void fillRandom();
|
||||||
|
|
||||||
|
@ -49,8 +49,6 @@ void MainFrame::initMenu() {
|
|||||||
menuGame->Append(IDM_New_Game, _("Начать сначала"));
|
menuGame->Append(IDM_New_Game, _("Начать сначала"));
|
||||||
menuGame->Append(IDM_Open, _("Открыть карту"));
|
menuGame->Append(IDM_Open, _("Открыть карту"));
|
||||||
menuGame->AppendCheckItem(IDM_Solveable, _("Генерировать решаемую карту"));
|
menuGame->AppendCheckItem(IDM_Solveable, _("Генерировать решаемую карту"));
|
||||||
menuGame->Enable(IDM_Solveable,
|
|
||||||
false); // TODO: finish solveable table generation
|
|
||||||
menuGame->AppendSeparator();
|
menuGame->AppendSeparator();
|
||||||
menuGame->Append(IDM_Undo, _("Отменить ход"));
|
menuGame->Append(IDM_Undo, _("Отменить ход"));
|
||||||
menuGame->Append(IDM_Reshuffle, _("Перемешать поле"));
|
menuGame->Append(IDM_Reshuffle, _("Перемешать поле"));
|
||||||
|
12
utils.h
12
utils.h
@ -26,8 +26,18 @@ public:
|
|||||||
|
|
||||||
class ThreePoint {
|
class ThreePoint {
|
||||||
public:
|
public:
|
||||||
ThreePoint(int _z, int _x, int _y) : x(_x), y(_y), z(_z){};
|
constexpr ThreePoint(int _z, int _x, int _y) : x(_x), y(_y), z(_z){};
|
||||||
|
ThreePoint(const wxPoint& a) : x(a.x), y(a.y), z(0){};
|
||||||
ThreePoint() : x(0), y(0), z(0){};
|
ThreePoint() : x(0), y(0), z(0){};
|
||||||
|
|
||||||
|
bool operator<(const ThreePoint& b) const {
|
||||||
|
return z*144*144+x*144+y < b.z*144*144+b.x*144+b.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const ThreePoint& b) {
|
||||||
|
return z == b.z && x == b.x && y == b.y;
|
||||||
|
}
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
int z;
|
int z;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user