Upgraded layout structure, added filling methods, fixed tileset, added tile selection verification
295
Controller.cpp
@ -1,52 +1,30 @@
|
||||
#include "Controller.h"
|
||||
#include "utils.h"
|
||||
#include <wx/xml/xml.h>
|
||||
|
||||
Controller::Controller(Drawer& drawer): drawer(drawer) {};
|
||||
|
||||
void Controller::resize(const wxSize& tableSize) {
|
||||
wxSize& resolution = drawer.resolution;
|
||||
wxSize& gridSize = drawer.gridSize;
|
||||
Dimensions& gridSize = drawer.gridSize;
|
||||
wxRect& tablePixelRect = drawer.tablePixelRect;
|
||||
|
||||
resolution = tableSize;
|
||||
|
||||
int gridPoint = min(resolution.x / (gridSize.x * TILE_WIDTH),
|
||||
resolution.y / (gridSize.y * TILE_HEIGHT));
|
||||
|
||||
if (gridPoint > 2) {
|
||||
tablePixelRect.SetSize({gridPoint * TILE_WIDTH * gridSize.x, gridPoint * TILE_HEIGHT * gridSize.y});
|
||||
if (stopwatch >= 0) {
|
||||
int gridPoint = min(resolution.x / (gridSize.x * TILE_WIDTH),
|
||||
resolution.y / (gridSize.y * TILE_HEIGHT));
|
||||
|
||||
if (gridPoint > 2) {
|
||||
tablePixelRect.SetSize({gridPoint * TILE_WIDTH * gridSize.x, gridPoint * TILE_HEIGHT * gridSize.y});
|
||||
|
||||
drawer.tilePixelSize.Set(gridPoint * TILE_WIDTH, gridPoint * TILE_HEIGHT);
|
||||
drawer.tilePixelSize.Set(gridPoint * TILE_WIDTH, gridPoint * TILE_HEIGHT);
|
||||
}
|
||||
|
||||
tablePixelRect.SetPosition({(resolution.x - tablePixelRect.width) / 2,
|
||||
(resolution.y - tablePixelRect.height) / 2});
|
||||
}
|
||||
|
||||
tablePixelRect.SetPosition({(resolution.x - tablePixelRect.width) / 2,
|
||||
(resolution.y - tablePixelRect.height) / 2});
|
||||
|
||||
drawer.setBG(tableSize);
|
||||
drawer.initScreen(tableSize, table);
|
||||
}
|
||||
|
||||
wxPoint Controller::toGrid(const wxPoint& point) {
|
||||
wxPoint out(-1, -1);
|
||||
|
||||
wxRect& tablePixelRect = drawer.tablePixelRect;
|
||||
|
||||
if (point.x >= tablePixelRect.x &&
|
||||
point.x <= tablePixelRect.x + tablePixelRect.width &&
|
||||
point.y >= tablePixelRect.y &&
|
||||
point.y <= tablePixelRect.y + tablePixelRect.height)
|
||||
{
|
||||
out.x = (point.x - tablePixelRect.x) / drawer.tilePixelSize.x;
|
||||
out.y = (point.y - tablePixelRect.y) / drawer.tilePixelSize.y;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
wxPoint Controller::fromGrid(const wxPoint& point) {
|
||||
return { drawer.tablePixelRect.x + point.x * drawer.tilePixelSize.x,
|
||||
drawer.tablePixelRect.y + point.y * drawer.tilePixelSize.y };
|
||||
drawer.initScreen(table);
|
||||
}
|
||||
|
||||
void Controller::loadLayout(const wxString& path) {
|
||||
@ -54,72 +32,241 @@ void Controller::loadLayout(const wxString& path) {
|
||||
|
||||
drawer.gridSize = layout.getDimensions();
|
||||
|
||||
table = TLVec(drawer.gridSize.x, wxVector<wxVector<TLSquare>>(drawer.gridSize.y, wxVector<TLSquare>()));
|
||||
table = TLVec(drawer.gridSize.z, vector<vector<CardT>>(drawer.gridSize.x, vector<CardT>(drawer.gridSize.y, -2)));
|
||||
|
||||
layout.readLayout(table);
|
||||
|
||||
remaining = layout.getTilesNumber();
|
||||
|
||||
if (remaining == 144) {
|
||||
for (int i = 0; i < 34; i++)
|
||||
cardsCounter[i] = 4;
|
||||
for (int i = 34; i < TILE_IMAGES_N; i++)
|
||||
cardsCounter[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
TLVec* Controller::getTable() {
|
||||
return &table;
|
||||
TLVec& Controller::getTable() {
|
||||
return table;
|
||||
}
|
||||
|
||||
TLSquare* Controller::getCardByPosition(const wxPoint& point) {
|
||||
void Controller::fillSolveableTable() {
|
||||
time_t start_time = time(NULL);
|
||||
|
||||
auto& gridSize = drawer.gridSize;
|
||||
|
||||
std::list<ThreePoint> positions;
|
||||
|
||||
int overall = gridSize.z * gridSize.x * gridSize.y;
|
||||
int pos = rand() % overall;
|
||||
int z, x, y;
|
||||
|
||||
do {
|
||||
z = pos / (gridSize.x * gridSize.y);
|
||||
x = (pos / gridSize.y) % gridSize.x;
|
||||
y = pos % gridSize.y;
|
||||
} while (table[z][x][y] != -1);
|
||||
|
||||
positions.push_back({z, x, y});
|
||||
|
||||
int past_pos = 0;
|
||||
auto past_ptr = positions.begin();
|
||||
|
||||
while (!positions.empty()) {
|
||||
int id = genRandId();
|
||||
|
||||
if (id < 34) {
|
||||
past_pos = emplace_rand(id, positions, past_pos, past_ptr);
|
||||
past_pos = emplace_rand(id, positions, past_pos, past_ptr);
|
||||
|
||||
cardsCounter[id]--;
|
||||
} else
|
||||
emplace_rand(id, positions, past_pos, past_ptr);
|
||||
}
|
||||
|
||||
wxLogInfo(wxString::Format("Filling took %i seconds", start_time - time(NULL)));
|
||||
}
|
||||
|
||||
int Controller::emplace_rand(int id, std::list<ThreePoint> positions, int past_pos, std::list<ThreePoint>::iterator past_ptr) {
|
||||
int d = rand() % positions.size() - past_pos;
|
||||
|
||||
if (d > 0)
|
||||
for (int i = 0; i < d; i++)
|
||||
past_ptr++;
|
||||
else
|
||||
for (int i = 0; i > d; i--)
|
||||
past_ptr--;
|
||||
|
||||
past_pos += d;
|
||||
|
||||
table[past_ptr->z][past_ptr->x][past_ptr->y] = id;
|
||||
|
||||
// if ()
|
||||
// positions.push_back({})
|
||||
|
||||
/**
|
||||
* TODO: random move and positions adding
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Controller::fillRandom() {
|
||||
srand(time(NULL));
|
||||
int not_end = remaining;
|
||||
|
||||
for (int z = 0; z < drawer.gridSize.z && not_end; z++)
|
||||
for (int x = 0; x < drawer.gridSize.x && not_end; x++)
|
||||
for (int y = 0; y < drawer.gridSize.y && not_end; y++)
|
||||
if (table[z][x][y] == -1) {
|
||||
table[z][x][y] = genRandId();
|
||||
not_end--;
|
||||
}
|
||||
}
|
||||
|
||||
int Controller::genRandId() {
|
||||
int id;
|
||||
|
||||
int w = 0;
|
||||
|
||||
do {
|
||||
id = rand() % TILE_IMAGES_N;
|
||||
w++;
|
||||
} while (cardsCounter[id] == 0);
|
||||
|
||||
cardsCounter[id]--;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* It also changes point to top right coordinate of card
|
||||
*/
|
||||
CardT* Controller::getCardByPosition(ThreePoint& point) {
|
||||
int8_t topIndex = -1;
|
||||
auto res = table[0][0].rend();
|
||||
CardT* res = nullptr;
|
||||
|
||||
for (auto el = table[point.x][point.y].rbegin(); el != table[point.x][point.y].rend(); ++el)
|
||||
if (el->second != (uint8_t)-1) {
|
||||
auto d = el->first;
|
||||
if (d > topIndex) {
|
||||
topIndex = d;
|
||||
res = el;
|
||||
ThreePoint realPos = point;
|
||||
|
||||
for (int z = table.size() - 1; z >= 0; z--)
|
||||
if (table[z][point.x][point.y] >= 0) {
|
||||
if (z > topIndex) {
|
||||
topIndex = z;
|
||||
res = &table[z][point.x][point.y];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (point.x > 0)
|
||||
for (auto el = table[point.x-1][point.y].rbegin(); el != table[point.x-1][point.y].rend(); ++el)
|
||||
if (el->second != (uint8_t)-1) {
|
||||
auto d = el->first;
|
||||
if (d > topIndex) {
|
||||
topIndex = d;
|
||||
res = el;
|
||||
for (int z = table.size() - 1; z >= 0; z--)
|
||||
if (table[z][point.x-1][point.y] >= 0) {
|
||||
if (z > topIndex) {
|
||||
topIndex = z;
|
||||
res = &table[z][point.x-1][point.y];
|
||||
|
||||
realPos.x = point.x - 1;
|
||||
realPos.y = point.y;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (point.y > 0)
|
||||
for (auto el = table[point.x][point.y-1].rbegin(); el != table[point.x][point.y-1].rend(); ++el)
|
||||
if (el->second != (uint8_t)-1) {
|
||||
auto d = el->first;
|
||||
if (d > topIndex) {
|
||||
topIndex = d;
|
||||
res = el;
|
||||
for (int z = table.size() - 1; z >= 0; z--)
|
||||
if (table[z][point.x][point.y-1] >= 0) {
|
||||
if (z > topIndex) {
|
||||
topIndex = z;
|
||||
res = &table[z][point.x][point.y-1];
|
||||
|
||||
realPos.x = point.x;
|
||||
realPos.y = point.y - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (point.x > 0 && point.y > 0)
|
||||
for (auto el = table[point.x-1][point.y-1].rbegin(); el != table[point.x-1][point.y-1].rend(); ++el)
|
||||
if (el->second != (uint8_t)-1) {
|
||||
auto d = el->first;
|
||||
if (d > topIndex) {
|
||||
topIndex = d;
|
||||
res = el;
|
||||
for (int z = table.size() - 1; z >= 0; z--)
|
||||
if (table[z][point.x-1][point.y-1] >= 0) {
|
||||
if (z > topIndex) {
|
||||
topIndex = z;
|
||||
res = &table[z][point.x-1][point.y-1];
|
||||
|
||||
realPos.x = point.x - 1;
|
||||
realPos.y = point.y - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return &(*res);
|
||||
point.x = realPos.x;
|
||||
point.y = realPos.y;
|
||||
point.z = topIndex;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void Controller::select(TLSquare* card) {
|
||||
if (selected != nullptr && selected->second == card->second && selected != card) {
|
||||
selected->second = -1;
|
||||
card->second = -1;
|
||||
selected = nullptr;
|
||||
|
||||
drawer.initScreen(drawer.tableSize, table);
|
||||
} else
|
||||
selected = card;
|
||||
bool Controller::available(const ThreePoint& point) {
|
||||
return upFree(point) && sideFree(point);
|
||||
}
|
||||
|
||||
bool Controller::upFree(const ThreePoint& point) {
|
||||
|
||||
if (point.z == table.size() - 1)
|
||||
return true;
|
||||
|
||||
return !(
|
||||
(table[point.z + 1][point.x][point.y] >= 0) ||
|
||||
(point.x > 0 && table[point.z + 1][point.x - 1][point.y] >= 0) ||
|
||||
(point.y > 0 && table[point.z + 1][point.x][point.y - 1] >= 0) ||
|
||||
(point.x > 0 && point.y > 0 && table[point.z + 1][point.x - 1][point.y - 1] >= 0) ||
|
||||
(point.x < table[point.z].size() - 1 && table[point.z + 1][point.x + 1][point.y] >= 0) ||
|
||||
(point.y < table[point.z][point.x].size() - 1 && table[point.z + 1][point.x][point.y + 1] >= 0) ||
|
||||
(point.x < table[point.z].size() - 1 && point.y < table[point.z][point.x].size() - 1 && table[point.z + 1][point.x + 1][point.y + 1] >= 0) ||
|
||||
(point.x > 0 && point.y < table[point.z][point.x].size() - 1 && table[point.z + 1][point.x - 1][point.y + 1] >= 0) ||
|
||||
(point.x < table[point.z].size() - 1 && point.y > 0 && table[point.z + 1][point.x + 1][point.y - 1] >= 0)
|
||||
);
|
||||
}
|
||||
|
||||
bool Controller::sideFree(const ThreePoint& point) {
|
||||
bool lfree = true;
|
||||
bool rfree = true;
|
||||
|
||||
if (point.x > 1)
|
||||
lfree = !(
|
||||
(point.y > 0 && table[point.z][point.x-2][point.y-1] >= 0) ||
|
||||
(table[point.z][point.x-2][point.y] >= 0) ||
|
||||
(point.y < table[point.z][point.x].size() - 1 && table[point.z][point.x-2][point.y+1] >= 0)
|
||||
);
|
||||
|
||||
if (point.x < table[point.z].size() - 2)
|
||||
rfree = !(
|
||||
(point.y > 0 && table[point.z][point.x+2][point.y-1] >= 0) ||
|
||||
(table[point.z][point.x+2][point.y] >= 0) ||
|
||||
(point.y < table[point.z][point.x].size() - 1 && table[point.z][point.x+2][point.y+1] >= 0)
|
||||
);
|
||||
|
||||
return lfree || rfree;
|
||||
}
|
||||
|
||||
void Controller::select(CardT* card) {
|
||||
wxLogDebug(wxString::Format("%i %p", *card, card));
|
||||
|
||||
if (selected != nullptr && sameValues(*card, *selected) && selected != card) {
|
||||
*selected = -3;
|
||||
*card = -3;
|
||||
selected = nullptr;
|
||||
|
||||
drawer.marked = {-1, -1, -1};
|
||||
} else
|
||||
selected = card;
|
||||
|
||||
drawer.initScreen(table);
|
||||
}
|
||||
|
||||
bool Controller::sameValues(CardT a, CardT b) {
|
||||
if (a == b) return true;
|
||||
else if (a >= 38 && b >= 38)
|
||||
return true;
|
||||
else if (a >= 34 && a <= 37 && b >= 34 && b <= 37)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
31
Controller.h
@ -1,6 +1,9 @@
|
||||
#ifndef CONTROLLER_H
|
||||
#define CONTROLLER_H
|
||||
|
||||
#include <array>
|
||||
#include <list>
|
||||
|
||||
#include "wxw.h"
|
||||
|
||||
#include "Drawer.h"
|
||||
@ -10,27 +13,41 @@ class Controller {
|
||||
public:
|
||||
Controller(Drawer& drawer);
|
||||
|
||||
int stopwatch = 0;
|
||||
int stopwatch = -1;
|
||||
|
||||
void resize(const wxSize& tableSize);
|
||||
|
||||
void loadLayout(const wxString& path);
|
||||
|
||||
wxPoint toGrid(const wxPoint& point);
|
||||
wxPoint fromGrid(const wxPoint& point);
|
||||
bool available(const ThreePoint& point);
|
||||
bool upFree(const ThreePoint& point);
|
||||
bool sideFree(const ThreePoint& point);
|
||||
|
||||
void select(TLSquare* card);
|
||||
void select(CardT* card);
|
||||
|
||||
TLVec* getTable();
|
||||
TLVec& getTable();
|
||||
|
||||
TLSquare* getCardByPosition(const wxPoint& point);
|
||||
void fillSolveableTable();
|
||||
void fillRandom();
|
||||
|
||||
CardT* getCardByPosition(ThreePoint& point);
|
||||
|
||||
std::array<uint8_t, TILE_IMAGES_N>cardsCounter;
|
||||
|
||||
uint8_t remaining;
|
||||
private:
|
||||
Drawer& drawer;
|
||||
XmlLayout layout;
|
||||
|
||||
TLVec table;
|
||||
|
||||
TLSquare* selected = nullptr;
|
||||
CardT* selected = nullptr;
|
||||
|
||||
int emplace_rand(int id, std::list<ThreePoint> positions, int past_pos, std::list<ThreePoint>::iterator past_ptr);
|
||||
|
||||
int genRandId();
|
||||
|
||||
bool sameValues(CardT a, CardT b);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
95
Drawer.cpp
@ -1,11 +1,16 @@
|
||||
#include "Drawer.h"
|
||||
|
||||
#define TILE_IMAGES_N 37
|
||||
static const char* tileImageNames[] = { "Back", "Blank", "Chun", "Front", "Haku", "Hatsu", "Man1", "Man2", "Man3", "Man4", "Man5", "Man6", "Man7", "Man8", "Man9", "Nan", "Pei", "Pin1", "Pin2", "Pin3", "Pin4", "Pin5", "Pin6", "Pin7", "Pin8", "Pin9", "Shaa", "Sou1", "Sou2", "Sou3", "Sou4", "Sou5", "Sou6", "Sou7", "Sou8", "Sou9", "Ton" };
|
||||
static const char* tileImageNames[] = { "Pin1", "Pin2", "Pin3", "Pin4", "Pin5", "Pin6", "Pin7", "Pin8", "Pin9", "Sou1", "Sou2", "Sou3", "Sou4", "Sou5", "Sou6", "Sou7", "Sou8", "Sou9", "Man1", "Man2", "Man3", "Man4", "Man5", "Man6", "Man7", "Man8", "Man9", "Chun", "Haku", "Hatsu", "Nan", "Pei", "Shaa", "Ton", "Flower1", "Flower2", "Flower3", "Flower4", "Season1", "Season2", "Season3", "Season4" };
|
||||
|
||||
Drawer::Drawer() {
|
||||
for (int i = 0; i < 37; i++)
|
||||
tileImages[i].LoadFile(_("./resources/tiles/") + _(tileImageNames[i]) + _(".png"), wxBITMAP_TYPE_PNG);
|
||||
/**
|
||||
* TODO: fix not loading last two tiles icons
|
||||
*/
|
||||
|
||||
Drawer::Drawer(): marked{-1, -1, -1} {
|
||||
for (int i = 0; i < TILE_IMAGES_N; i++) {
|
||||
if (!tileImages[i].LoadFile(_("./resources/tiles/") + _(tileImageNames[i]) + _(".png"), wxBITMAP_TYPE_PNG))
|
||||
wxLogDebug(_("./resources/tiles/") + _(tileImageNames[i]) + _(".png ") + wxString::Format(wxT("%i"), i));
|
||||
}
|
||||
}
|
||||
|
||||
void Drawer::drawTable(wxDC& dc) {
|
||||
@ -28,33 +33,46 @@ void Drawer::setBG(const wxSize& tableSize) {
|
||||
isBgReady = true;
|
||||
}
|
||||
|
||||
void Drawer::initScreen(const wxSize& tableSize, const TLVec& layout) {
|
||||
wxPoint Drawer::toGrid(const wxPoint& point) {
|
||||
wxPoint out(-1, -1);
|
||||
|
||||
if (point.x >= tablePixelRect.x &&
|
||||
point.x <= tablePixelRect.x + tablePixelRect.width &&
|
||||
point.y >= tablePixelRect.y &&
|
||||
point.y <= tablePixelRect.y + tablePixelRect.height)
|
||||
{
|
||||
out.x = (point.x - tablePixelRect.x) / tilePixelSize.x;
|
||||
out.y = (point.y - tablePixelRect.y) / tilePixelSize.y;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
wxPoint Drawer::fromGrid(int x, int y) {
|
||||
return { tablePixelRect.x + x * tilePixelSize.x,
|
||||
tablePixelRect.y + y * tilePixelSize.y };
|
||||
}
|
||||
|
||||
wxPoint Drawer::fromGrid(const wxPoint& point) {
|
||||
return fromGrid(point.x, point.y);
|
||||
}
|
||||
|
||||
void Drawer::initScreen(const TLVec& layout) {
|
||||
if (isBgReady) {
|
||||
screenBitmap = copyBitmap(bgBitmap);
|
||||
|
||||
wxLogDebug(_("Reinit"));
|
||||
|
||||
wxMemoryDC dc;
|
||||
dc.SelectObject(screenBitmap);
|
||||
|
||||
int cards_set = -1;
|
||||
uint8_t layer = -1;
|
||||
|
||||
while (cards_set) {
|
||||
layer++;
|
||||
cards_set = 0;
|
||||
|
||||
for (int i = 0; i < layout.size(); i++)
|
||||
for (int j = 0; j < layout[i].size(); j++) {
|
||||
int k = layout[i][j].size() - 1;
|
||||
while (k > -1 && layout[i][j][k].second == (uint8_t)-1)
|
||||
k--;
|
||||
|
||||
if (k > -1)
|
||||
if (layout[i][j][k].first == layer || layer == 0) {
|
||||
drawTile(dc, layout[i][j][k].second, {tablePixelRect.x + tilePixelSize.x*i, tablePixelRect.y + tilePixelSize.y*j}, layer);
|
||||
cards_set++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int z = 0; z < gridSize.z; z++)
|
||||
for (int x = 0; x < gridSize.x; x++)
|
||||
for (int y = 0; y < gridSize.y; y++) {
|
||||
CardT c = layout[z][x][y];
|
||||
if (c >= 0)
|
||||
drawTile(dc, c, fromGrid(x, y), z);
|
||||
}
|
||||
|
||||
isScreenReady = true;
|
||||
}
|
||||
@ -62,16 +80,29 @@ void Drawer::initScreen(const wxSize& tableSize, const TLVec& layout) {
|
||||
|
||||
void Drawer::drawTile(wxDC& dc, int8_t index, const wxPoint& position, uint8_t zIndex) {
|
||||
wxBrush _bgColor = dc.GetBrush();
|
||||
dc.SetBrush(wxColor(200, 200, 200));
|
||||
|
||||
wxBrush front = wxColor(255, 255, 255);
|
||||
wxBrush back = wxColor(200, 200, 200);
|
||||
|
||||
if (position == fromGrid({marked.x, marked.y}) && marked.z == zIndex) {
|
||||
front = wxColor(200, 255, 200);
|
||||
back = wxColor(190, 220, 190);
|
||||
}
|
||||
|
||||
dc.SetBrush(back);
|
||||
|
||||
dc.DrawRoundedRectangle(position.x + (tilePixelSize.GetWidth()/10 + 3) - (tilePixelSize.GetWidth()/10 + 3)*zIndex, position.y + (tilePixelSize.GetHeight()/10 + 3) - (tilePixelSize.GetHeight()/10 + 3)*zIndex, tilePixelSize.GetWidth() * 2, tilePixelSize.GetHeight() * 2, 10);
|
||||
|
||||
dc.SetBrush(_bgColor);
|
||||
dc.SetBrush(front);
|
||||
|
||||
dc.DrawRoundedRectangle(position.x - (tilePixelSize.GetWidth()/10 + 3)*zIndex, position.y - (tilePixelSize.GetHeight()/10 + 3)*zIndex, tilePixelSize.GetWidth() * 2, tilePixelSize.GetHeight() * 2, 10);
|
||||
|
||||
if (tileImages[index].GetWidth() != tilePixelSize.x * 2)
|
||||
dc.DrawBitmap(tileImages[index].Scale(tilePixelSize.x * 2 - 20, tilePixelSize.y * 2 - 20), {position.x + 10 - (tilePixelSize.GetWidth()/10 + 3)*zIndex, position.y + 10 - (tilePixelSize.GetHeight()/10 + 3)*zIndex});
|
||||
else
|
||||
dc.DrawBitmap(tileImages[index], {position.x + 10 - (tilePixelSize.GetWidth()/10 + 3)*zIndex, position.y + 10 - (tilePixelSize.GetHeight()/10 + 3)*zIndex});
|
||||
dc.SetBrush(_bgColor);
|
||||
|
||||
if (tileImages[index].IsOk()) {
|
||||
if (tileImages[index].GetWidth() != tilePixelSize.x * 2)
|
||||
dc.DrawBitmap(tileImages[index].Scale(tilePixelSize.x * 2 - 20, tilePixelSize.y * 2 - 20), {position.x + 10 - (tilePixelSize.GetWidth()/10 + 3)*zIndex, position.y + 10 - (tilePixelSize.GetHeight()/10 + 3)*zIndex});
|
||||
else
|
||||
dc.DrawBitmap(tileImages[index], {position.x + 10 - (tilePixelSize.GetWidth()/10 + 3)*zIndex, position.y + 10 - (tilePixelSize.GetHeight()/10 + 3)*zIndex});
|
||||
}
|
||||
}
|
||||
|
12
Drawer.h
@ -8,6 +8,8 @@
|
||||
#define TILE_HEIGHT 8
|
||||
#define TILE_WIDTH 6
|
||||
|
||||
#define TILE_IMAGES_N 42
|
||||
|
||||
class Drawer {
|
||||
public:
|
||||
Drawer();
|
||||
@ -18,11 +20,17 @@ public:
|
||||
|
||||
wxSize tilePixelSize; // 600x800
|
||||
wxSize resolution;
|
||||
wxSize gridSize;
|
||||
Dimensions gridSize;
|
||||
wxRect tablePixelRect;
|
||||
|
||||
void setBG(const wxSize& tableSize);
|
||||
void initScreen(const wxSize& tableSize, const TLVec& layout);
|
||||
void initScreen(const TLVec& layout);
|
||||
|
||||
wxPoint toGrid(const wxPoint& point);
|
||||
wxPoint fromGrid(int x, int y);
|
||||
wxPoint fromGrid(const wxPoint& point);
|
||||
|
||||
ThreePoint marked;
|
||||
|
||||
private:
|
||||
void drawScreen(wxDC& dc);
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
GamePanel::GamePanel(wxFrame* parent) : wxPanel(parent), controller(drawer), sb(parent->GetStatusBar()) {
|
||||
GamePanel::GamePanel(wxFrame* parent) : wxPanel(parent), controller(drawer) {
|
||||
SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||
|
||||
Bind(wxEVT_PAINT, &GamePanel::OnPaint, this);
|
||||
@ -12,21 +12,25 @@ GamePanel::GamePanel(wxFrame* parent) : wxPanel(parent), controller(drawer), sb(
|
||||
this->controller.resize(evt.GetSize());
|
||||
});
|
||||
|
||||
timer = new wxTimer(this);
|
||||
timer = new wxTimer(this, 1);
|
||||
Bind(wxEVT_TIMER, &GamePanel::OnTimer, this, timer->GetId());
|
||||
|
||||
Bind(wxEVT_LEFT_DOWN, &GamePanel::OnClick, this);
|
||||
}
|
||||
|
||||
void GamePanel::Start(const wxString& path) {
|
||||
void GamePanel::Start(const wxString& path, bool solveable) {
|
||||
controller.stopwatch = 0;
|
||||
controller.loadLayout(path);
|
||||
if (solveable)
|
||||
controller.fillSolveableTable();
|
||||
else
|
||||
controller.fillRandom();
|
||||
|
||||
timer->Start(1000, wxTIMER_CONTINUOUS);
|
||||
|
||||
if (sb == nullptr)
|
||||
sb = ((wxFrame*)this->GetParent())->GetStatusBar();
|
||||
sb->SetStatusText(LTimeToStr(controller.stopwatch));
|
||||
|
||||
|
||||
drawer.initScreen(drawer.tableSize, *controller.getTable());
|
||||
}
|
||||
|
||||
void GamePanel::OnPaint(wxPaintEvent& _) {
|
||||
@ -41,13 +45,17 @@ void GamePanel::OnTimer(wxTimerEvent& _) {
|
||||
}
|
||||
|
||||
void GamePanel::OnClick(wxMouseEvent& _) {
|
||||
wxPoint res = controller.toGrid(ScreenToClient(wxGetMousePosition()));
|
||||
wxPoint posPlain = drawer.toGrid(ScreenToClient(wxGetMousePosition()));
|
||||
|
||||
if (res.x > -1) {
|
||||
auto card = controller.getCardByPosition(res);
|
||||
if (card != nullptr) {
|
||||
ThreePoint pos = {-1, posPlain.x, posPlain.y};
|
||||
|
||||
if (pos.x > -1) {
|
||||
auto card = controller.getCardByPosition(pos);
|
||||
|
||||
drawer.marked = pos;
|
||||
|
||||
if (pos.z >= 0 && controller.available(pos))
|
||||
controller.select(card);
|
||||
}
|
||||
}
|
||||
|
||||
Refresh();
|
||||
|
@ -12,7 +12,7 @@ class GamePanel : public wxPanel {
|
||||
public:
|
||||
GamePanel(wxFrame* parent);
|
||||
|
||||
void Start(const wxString& path);
|
||||
void Start(const wxString& path, bool solveable);
|
||||
|
||||
private:
|
||||
Drawer drawer;
|
||||
|
@ -23,6 +23,7 @@ void MainFrame::initMenu() {
|
||||
wxMenu *menuGame = new wxMenu;
|
||||
menuGame->Append(IDM_New_Game, _("Начать сначала"));
|
||||
menuGame->Append(IDM_Open, _("Открыть карту"));
|
||||
menuGame->AppendCheckItem(IDM_Solveable, _("Генерировать решаемую карту"));
|
||||
menuGame->AppendSeparator();
|
||||
menuGame->Append(IDM_Exit, _("Выход"));
|
||||
|
||||
@ -63,10 +64,14 @@ void MainFrame::bindMenu() {
|
||||
if (layoutPath.IsEmpty())
|
||||
openLayout();
|
||||
else
|
||||
panel->Start(layoutPath);
|
||||
panel->Start(layoutPath, solveable);
|
||||
|
||||
Refresh();
|
||||
}, IDM_New_Game);
|
||||
|
||||
Bind(wxEVT_MENU, [this](wxCommandEvent& _) -> void {
|
||||
solveable = _.IsChecked();
|
||||
}, IDM_Solveable);
|
||||
}
|
||||
|
||||
void MainFrame::openLayout() {
|
||||
@ -77,5 +82,5 @@ void MainFrame::openLayout() {
|
||||
|
||||
layoutPath = openFileDlg.GetPath();
|
||||
|
||||
panel->Start(layoutPath);
|
||||
panel->Start(layoutPath, solveable);
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ private:
|
||||
|
||||
const wxString dataDirPath;
|
||||
wxString layoutPath;
|
||||
|
||||
bool solveable = false;
|
||||
};
|
||||
|
||||
enum
|
||||
@ -33,7 +35,8 @@ enum
|
||||
IDM_Help = wxID_HELP,
|
||||
IDM_About = wxID_ABOUT,
|
||||
IDM_Rules = wxID_HIGHEST + 1,
|
||||
IDM_New_Game
|
||||
IDM_New_Game,
|
||||
IDM_Solveable
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -15,8 +15,9 @@ bool XmlLayout::openFile(const wxString& openPath) {
|
||||
return true;
|
||||
}
|
||||
|
||||
wxSize XmlLayout::getDimensions() {
|
||||
return { wxAtoi(layoutDoc.GetRoot()->GetAttribute("ux")) + 2,
|
||||
Dimensions XmlLayout::getDimensions() {
|
||||
return { wxAtoi(layoutDoc.GetRoot()->GetAttribute("layers")),
|
||||
wxAtoi(layoutDoc.GetRoot()->GetAttribute("ux")) + 2,
|
||||
wxAtoi(layoutDoc.GetRoot()->GetAttribute("uy")) + 2 };
|
||||
}
|
||||
|
||||
@ -29,13 +30,15 @@ void XmlLayout::readLayout(TLVec& table) {
|
||||
if (tilePtr->GetName().IsSameAs("tile")) {
|
||||
x = wxAtoi(tilePtr->GetAttribute("x"));
|
||||
y = wxAtoi(tilePtr->GetAttribute("y"));
|
||||
l = wxAtoi(tilePtr->GetAttribute("layer"));
|
||||
l = wxAtoi(tilePtr->GetAttribute("layer")) - 1;
|
||||
|
||||
table[x][y].push_back(std::make_pair(l - 1, (uint8_t)-1));
|
||||
|
||||
table[x][y].at(table[x][y].size() -1).second = (random()) % 37;
|
||||
table[l][x][y] = -1;
|
||||
}
|
||||
|
||||
tilePtr = tilePtr->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t XmlLayout::getTilesNumber() {
|
||||
return wxAtoi(layoutDoc.GetRoot()->GetAttribute("tiles"));
|
||||
}
|
@ -12,8 +12,9 @@ public:
|
||||
XmlLayout();
|
||||
|
||||
bool openFile(const wxString& path);
|
||||
wxSize getDimensions();
|
||||
Dimensions getDimensions();
|
||||
void readLayout(TLVec& table);
|
||||
uint8_t getTilesNumber();
|
||||
|
||||
private:
|
||||
wxString path;
|
||||
|
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 18 KiB |
BIN
resources/tiles/Flower1.png
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
resources/tiles/Flower2.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
resources/tiles/Flower3.png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
resources/tiles/Flower4.png
Normal file
After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 240 B |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 83 KiB |
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 79 KiB |
BIN
resources/tiles/Season1.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
resources/tiles/Season2.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
resources/tiles/Season3.png
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
resources/tiles/Season4.png
Normal file
After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 25 KiB |
25
utils.h
@ -3,6 +3,10 @@
|
||||
|
||||
#include "wxw.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
using std::vector;
|
||||
|
||||
wxString LTimeToStr(int time);
|
||||
int upDiv(int a, int b);
|
||||
wxString itowxS(int a);
|
||||
@ -10,7 +14,24 @@ wxString itowxS(int a);
|
||||
#define min(a, b) (a + b - abs(a - b)) / 2
|
||||
#define max(a, b) (a + b + abs(a - b)) / 2
|
||||
|
||||
using TLSquare = std::pair<uint8_t, uint8_t>;
|
||||
using TLVec = wxVector<wxVector<wxVector<TLSquare>>>;
|
||||
using CardT = int16_t;
|
||||
|
||||
class Dimensions : public wxSize {
|
||||
public:
|
||||
Dimensions(int _z, int _x, int _y): wxSize(_x, _y), z(_z) {};
|
||||
Dimensions(): wxSize(), z(0) {};
|
||||
int z;
|
||||
};
|
||||
|
||||
class ThreePoint {
|
||||
public:
|
||||
ThreePoint(int _z, int _x, int _y): x(_x), y(_y), z(_z) {};
|
||||
ThreePoint(): x(0), y(0), z(0) {};
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
};
|
||||
|
||||
using TLVec = vector<vector<vector<CardT>>>;
|
||||
|
||||
#endif
|
||||
|