Compare commits
2 Commits
a367b26f87
...
995a00cbbd
Author | SHA1 | Date | |
---|---|---|---|
995a00cbbd | |||
6ed9c48a94 |
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <exception>
|
||||
|
||||
static const std::array<uint8_t, 42> defaultCardsCounter{
|
||||
const std::array<uint8_t, 42> defaultCardsCounter{
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
|
||||
@@ -48,7 +48,7 @@ void Controller::fillSolveableTable() {
|
||||
auto next_ptr = positions.begin(); // инициализируем указатель на позицию, куда будет вставляться следующий камень
|
||||
|
||||
while (!positions.empty()) {
|
||||
int id = genRandId();
|
||||
auto id = genRandId();
|
||||
|
||||
emplace_table(id, *next_ptr, positions); // вставляем id в next_ptr
|
||||
not_end--; // уменьшаем счётчик оставшихся для вставки камней
|
||||
@@ -60,10 +60,10 @@ void Controller::fillSolveableTable() {
|
||||
else
|
||||
id = getFreeSingularId(id);
|
||||
|
||||
emplace_table(id, *next_ptr, positions);
|
||||
not_end--;
|
||||
emplace_table(id, *next_ptr, positions); // вставляем id в next_ptr
|
||||
not_end--; // уменьшаем счётчик оставшихся для вставки камней
|
||||
|
||||
next_rand(positions, next_ptr, true, not_end);
|
||||
next_rand(positions, next_ptr, true, not_end); // Находим случайную новую позицию
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,26 +124,28 @@ void Controller::next_rand(PosSet& positions,
|
||||
|
||||
const auto rand_ptr = ptr; // сохраняем предыдущее положение итератора
|
||||
|
||||
while (!canOverlap && ptr != positions.end() && wouldOverlap(prev, *ptr)) // Пока не найдём тот, что не будет закрывать только что вставленную позицию, если не canBeUp или дошли до конца набора
|
||||
ptr++; // наращиваем итератор
|
||||
|
||||
if (ptr == positions.end()) { // если ни одна из позиций начиная с rand_ptr не подошла (нельзя выбирать накрывающую предыдущий камень и все позиции накрывают)
|
||||
ptr = positions.begin(); // начинаем с начала
|
||||
|
||||
while (!canOverlap && ptr != rand_ptr && wouldOverlap(prev, *ptr)) // Пока не найдём тот, что не будет закрывать только что вставленную позицию, если не canBeUp и не дошли до rand_ptr
|
||||
if (!canOverlap) {
|
||||
while (ptr != positions.end() && wouldOverlap(prev, *ptr)) // Пока не найдём тот, что не будет закрывать только что вставленную позицию, если не canBeUp или дошли до конца набора
|
||||
ptr++; // наращиваем итератор
|
||||
}
|
||||
|
||||
if (ptr == rand_ptr && !canOverlap && wouldOverlap(prev, *ptr)) { // если итератор совпадает с rand_ptr и при этом ptr перекрывает prev,
|
||||
if (not_end == positions.size()) // если уже все позиции добавлены в набор
|
||||
ptr = positions.begin(); // просто выбираем первую из них
|
||||
else { // иначе
|
||||
auto res = positions.insert(getRandLowest()); // пытаемся вставить вставляем случайную позицию в нижней плоскости
|
||||
if (ptr == positions.end()) { // если ни одна из позиций начиная с rand_ptr не подошла (нельзя выбирать накрывающую предыдущий камень и все позиции накрывают)
|
||||
ptr = positions.begin(); // начинаем с начала
|
||||
|
||||
while (!res.second) // пока не произошла вставка позиции в набор
|
||||
res = positions.insert(getRandLowest()); // пытаемся вставить случайную позицию в нижней плоскости
|
||||
while (ptr != rand_ptr && wouldOverlap(prev, *ptr)) // Пока не найдём тот, что не будет закрывать только что вставленную позицию, если не canBeUp и не дошли до rand_ptr
|
||||
ptr++; // наращиваем итератор
|
||||
}
|
||||
|
||||
ptr = res.first; // получаем итератор на только что вставленную позицию
|
||||
if (ptr == rand_ptr && wouldOverlap(prev, *ptr)) { // если итератор совпадает с rand_ptr и при этом ptr перекрывает prev,
|
||||
if (not_end == positions.size()) // если уже все позиции добавлены в набор
|
||||
ptr = positions.begin(); // просто выбираем первую из них
|
||||
else { // иначе
|
||||
auto res = positions.insert(getRandLowest()); // пытаемся вставить вставляем случайную позицию в нижней плоскости
|
||||
|
||||
while (!res.second) // пока не произошла вставка позиции в набор
|
||||
res = positions.insert(getRandLowest()); // пытаемся вставить случайную позицию в нижней плоскости
|
||||
|
||||
ptr = res.first; // получаем итератор на только что вставленную позицию
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -318,7 +320,7 @@ CardT Controller::getFreeSingularId(CardT prev) {
|
||||
* It also changes point to top right coordinate of card
|
||||
*/
|
||||
CardT* Controller::getCardByPosition(ThreePoint& point) {
|
||||
int8_t topIndex = -1; // начинаем с -1, чтобы если не нашёлся ни один камень, получить невалидную позицию
|
||||
int topIndex = -1; // начинаем с -1, чтобы если не нашёлся ни один камень, получить невалидную позицию
|
||||
CardT* res = nullptr; // указатель на элемент массива
|
||||
|
||||
ThreePoint realPos(point); // сохраняем копию позиции, чтобы при смещении не ломать позицию, для которой ищем
|
||||
|
@@ -3,7 +3,7 @@
|
||||
#include <wx/filename.h>
|
||||
#include <wx/stdpaths.h>
|
||||
|
||||
static const char* tileImageNames[TILE_IMAGES_N] = {
|
||||
const char* tileImageNames[TILE_IMAGES_N] = {
|
||||
// clang-format off
|
||||
"Pin1", "Pin2", "Pin3", "Pin4", "Pin5", "Pin6", "Pin7", "Pin8", "Pin9",
|
||||
"Sou1", "Sou2", "Sou3", "Sou4", "Sou5", "Sou6", "Sou7", "Sou8", "Sou9",
|
||||
@@ -37,8 +37,8 @@ void Drawer::drawTable(wxDC& dc) const {
|
||||
}
|
||||
}
|
||||
|
||||
static const wxColor lGreen{0x07, 0x55, 0x2b};
|
||||
static const wxColor dGreen{0x01, 0x2d, 0x16};
|
||||
const wxColor lGreen{0x07, 0x55, 0x2b};
|
||||
const wxColor dGreen{0x01, 0x2d, 0x16};
|
||||
|
||||
void Drawer::composeBG() {
|
||||
bgBitmap = wxBitmap(resolution); // создаём битмап размером со всю панейль
|
||||
|
2
Drawer.h
@@ -30,8 +30,6 @@ public:
|
||||
|
||||
wxSize composeMinSize(const Dimensions& gridSize) const;
|
||||
|
||||
wxSize tableSize;
|
||||
|
||||
wxSize tilePixelSize; // кратно 3x4, по умолчанию 600x800
|
||||
wxSize resolution;
|
||||
wxRect boardPixelRect;
|
||||
|
@@ -47,13 +47,13 @@ MainFrame::MainFrame()
|
||||
void MainFrame::initMenu() {
|
||||
wxMenu* menuGame = new wxMenu; // Создаём подменю
|
||||
menuGame->Append(IDM_New_Game, _("Начать сначала\tCTRL+N")); // Создаем пункт меню с id обработчика IDM_New_Game, далее аналогично
|
||||
menuGame->Append(IDM_Open, _("Открыть карту"));
|
||||
menuGame->Append(IDM_Open, _("Открыть карту\tCTRL+O"));
|
||||
menuGame->AppendCheckItem(IDM_Solveable, _("Генерировать решаемую карту"));
|
||||
menuGame->AppendSeparator(); // Добавляем горизонтальный разделитель в меню
|
||||
menuGame->Append(IDM_Undo, _("Отменить ход"));
|
||||
menuGame->Append(IDM_Reshuffle, _("Перемешать поле"));
|
||||
menuGame->AppendSeparator();
|
||||
menuGame->Append(IDM_Exit, _("Выход"));
|
||||
menuGame->Append(IDM_Exit, _("Выход\tCTRL+Q"));
|
||||
|
||||
wxMenu* menuHelp = new wxMenu;
|
||||
menuHelp->Append(IDM_Help, _("Инструкция"));
|
||||
|
@@ -20,13 +20,13 @@ TextDlg::TextDlg(wxWindow* parent, wxWindowID id, const wxString& title, const w
|
||||
wxDefaultSize, wxSP_WRAP);
|
||||
|
||||
const wxClientDC dc(text); // создаём dc, используя для него настройки статического текста
|
||||
const wxSize lineSize = dc.GetTextExtent(wxString('W', 40U)); // получаем из dc размеры строчки из 40 символов 'W' (так как текст удобнее всего читать, если в нём около 40-60 символов в строке)
|
||||
const wxSize& lineSize = dc.GetTextExtent(wxString('W', 40U)); // получаем из dc размеры строчки из 40 символов 'W' (так как текст удобнее всего читать, если в нём около 40-60 символов в строке)
|
||||
|
||||
scrollableWnd->SetScrollbars(lineSize.x, lineSize.y, 0, 0); // устанавливаем скорость скролла (количество пикселей, прокручиваемых при одинарном прокручивании колеса мыши, или нажатие кнопки)
|
||||
|
||||
text->Wrap(lineSize.x); // Делаем перенос строк для того, чтобы вместить текст в ширину строки
|
||||
|
||||
auto textSize = text->GetClientSize(); // получаем размер статического текста
|
||||
const wxSize& textSize = text->GetClientSize(); // получаем размер статического текста
|
||||
|
||||
scrollableWnd->SetVirtualSize(textSize.x, textSize.y); // устанавливаем виртуальный размер окна прокрутки равным размерам статического текста
|
||||
|
||||
@@ -34,4 +34,4 @@ TextDlg::TextDlg(wxWindow* parent, wxWindowID id, const wxString& title, const w
|
||||
textSize.x + 10 + wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y), // по ширине: ширина текста
|
||||
mmin(textSize.y, lineSize.y * 30) + 10); // по высоте: минимум из реальной высоты текста, или 30 строк
|
||||
// + отступы по 5 пикселей с обеих сторон
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ bool XmlLayout::openFile(const wxString& openPath) {
|
||||
}
|
||||
|
||||
Dimensions XmlLayout::getDimensions() {
|
||||
auto root = layoutDoc.GetRoot(); // сохраняем в ссылке указатель на корневой элемент XML-документа
|
||||
auto root = layoutDoc.GetRoot(); // сохраняем указатель на корневой элемент XML-документа
|
||||
|
||||
lx = wxAtoi(root->GetAttribute("lx")); // считываем минимальный x
|
||||
ly = wxAtoi(root->GetAttribute("ly")); // считываем минимальный y
|
||||
|
BIN
report/ClassDiagram.png
Executable file
After Width: | Height: | Size: 338 KiB |
BIN
report/DmitriyShishkov_1181_coursework.back.docx
Normal file
BIN
report/DmitriyShishkov_1181_coursework.docx
Normal file
BIN
report/DmitriyShishkov_1181_coursework.pdf
Normal file
BIN
report/click.png
Normal file
After Width: | Height: | Size: 31 KiB |
4
report/click.svg
Normal file
After Width: | Height: | Size: 13 KiB |
1
report/diagram
Normal file
@@ -0,0 +1 @@
|
||||
<mxfile host="app.diagrams.net" modified="2022-05-31T04:32:01.280Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36" etag="gU-0oV9X5qtG5Er4burL" version="18.1.3" type="device"><diagram id="q2XTSsZ33zmQU2bzPoKI" name="Page-1">zVjbctowEP0az7QPyUg2NvCIDaTtJNOkNG3yqGBhuzUWI0S4fH1la23LGIhDksKLWK1Wtz1Hu2sMy5uurjiZhTfMp7FhIn9lWH3DNDGybPmTatZKY3eRUgQ88sGoVIyiDc1ngnYR+XReMRSMxSKaVZVjliR0LCo6wjlbVs0mLK7uOiMB7IhKxWhMYloz+x35IlTajtku9V9oFIT5ztjpqpEnMv4bcLZIYL+EJVSNTEm+DGw5D4nPlprKGhiWxxkTSpquPBqnbs09puYN94wWR+Y0EU0mRAvXZJu7i5/B8J7e+1+jO7y6gFWeSbwAVxh9ZHSHaesOstY1+tjoeJnc1vSZpYuyUSXbFXt1abHOfZx5iaaHwYblLsNI0NGMjNPRpWSV1IViGsNw/XL5SSkXdKWp4LJXlE2p4GtpAhzEFjh+WSKKczBCDU0HdARIFBRLld6UAjj0Fc7ND7Dt3XbuOdkOM28hzZedTO5Ufay8m3naLCYWSlSTO5mMa3D1Mr1VA4f68j1Al3ERsoAlJB6UWrcKX2lzzdgMlH+oEGt43GQhWBVSuorEg5TRpQ29x7QHcn+ld9Z5J5E4POidx3KFtFtOy3r5vL30mbMFH9NDmEH0ITyg4oAdRIbUbwfJCFRFl6hjwdqcxkREz9XQs4t8sNoti+QtShM2mczl2bbZWWzaiLDu5vrRwuFkfn/xffbDu/m1+fZjRzSYqb3PhS34A9myBeXH0sd+gS3YcdpnxJZDd92Obp4WdFoQbip5wYmlZ9wnLqUglbR4169mExXOZNvS8ktXC22ovtqnISdTmYPlRuiWJDT+XKdvHMvCgr6chaosfktOglELQUrIcxRqmKMK5bsnqdZuFPta5nE0hLz9GSmfAt2eZulp+PX31Af/Iagc/67zovSld201TAuNX/XbChCzBm4gH8dIXkNIP54yrL++BMB6UMeNQvoxSNunQjqb2uOcrDWDLP/Od4R3CCgtZFYCiok7W6xRK75rmVBnlSBPMcTc4gPvbIqGpiVmWSc0Z9i7FA1NKdc+ZSyxj8z2qPaBg7O2nbZdrCX8InOoTGNpE/VPmAFUAWDsakpLm94D+XySv+1Uk795+uTfPh5UZaDAa/LZqcDQGaDD6eYMOD+0PgId2S3/+FFhufxjzRr8Aw==</diagram></mxfile>
|
BIN
report/paint.png
Normal file
After Width: | Height: | Size: 11 KiB |
4
report/paint.svg
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
report/reshuffle.png
Normal file
After Width: | Height: | Size: 31 KiB |
4
report/reshuffle.svg
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
report/resize.png
Normal file
After Width: | Height: | Size: 30 KiB |
4
report/resize.svg
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
report/start.png
Normal file
After Width: | Height: | Size: 45 KiB |
4
report/start.svg
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
report/timer.png
Normal file
After Width: | Height: | Size: 12 KiB |
4
report/timer.svg
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
report/undo.png
Normal file
After Width: | Height: | Size: 30 KiB |
4
report/undo.svg
Normal file
After Width: | Height: | Size: 10 KiB |
1
report/usecase
Normal file
@@ -0,0 +1 @@
|
||||
<mxfile host="app.diagrams.net" modified="2022-06-04T18:41:02.776Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36" etag="CHoYnxxKfn1GPYucbaki" version="19.0.0" type="device"><diagram id="q2XTSsZ33zmQU2bzPoKI" name="Page-1">7VtZj+MoEP41eeyR7+Mx5440PdKsWqvtfnQSknjHMREhk2R+/WIDNtg4pxM6o3RLERRgcFV9VUWBO3Z/ufsLRavFdzgFSccypruOPehYlme75Dcj7Ckh9ANKmKN4SklmSXiLfwNGNBh1E0/BWuqIIUxwvJKJE5imYIIlWoQQ3MrdZjCRZ11FczajURLeJlECat3+jad4QamB5Zf0ryCeL/jMphfSlnE0+TlHcJOy+VKYAtqyjPhj2JTrRTSFW4FkDzt2H0GIaWm564Mk4yrnGB03amgtloxAik8Z4KW+//5t9pb8/eHtY2B/ff3He3HZ4n5FyYbxgq0W7zlz8tcD2VOMjt3bLmIM3lbRJGvdEm0gtAVeJqRmkuIsTpI+TCDKx9ozN/sn9DVG8CcQWrz8LxsBUyzQ6R+hs4UBhMGu8ZXNgpFENQFcAoz2pAvXS4+9HlPLF17flkJ2HEZbCAL2ODFiijUvnl1ymBQYk89guHec32BKdJNVIcILOIdplAxLak+WSNnnFcIVk8N/AOM9A1q0wVCWEp0zm+gwZ8m64AZNwIEX4nCN0BzgQ5qmlhQCSYTjX/I6Wue6Wec6YV04yn57w/y31yGcCfp52Rfoec+ekbfSsiv1r0qPwHyVFTfLpDvBmVb3Mh2OibF5jcYg+QHXMY5hSrqMIcZwKXToJvE8a8Cwgiq4wUmcEvhw82e0AxDHlQFi1vFhq+BxK3QEfxo63BPR4etEh6tGx1DQ+W5epijocTrVfyPvMOIdSDngAClA5AnAGQh93Lp4k4Q4fXDc0VQxs4yn01z8LcDCteo4MC0FEIJbAcE8wS8/FhL8E5EQ6kSCr0aCxfWeqKwpKLqhQkJXaBI72Jfregsq7etX6QYnPOC2IeeUBiUnHET7dzY+r3xklS8urw52YuNgL/nfVsARXucmmIxfjC9+EDKbejJg8sd1EYr2QocVjFO8Fmb7kRGEyDqoBA5eZfNxpL9jVPSJLqAymK8GzmZrwpeqBhYcuFwpeZx/Z43bxfhdKAv6RmqlumWVvah7j6GltqXThjvmU6Tti7TBu9xJpA0RqsNc7dNpHJKd2QDH0msEl7iMe5rpUC1/ZahFNcLgm/emwK3YiRCpjGoahBZwOd6s7xuacV+qPVSzQ72QKlH0IYHo5pAyrVMx5ei0h3yZV+1TRjXw2HkTKZi1/NdIgI0jDKQ5gpBv6UnZre2DyG9fwBvNAig07Oqdf8QIEyJ3gNoBZ1gBJ49c9YHTUaSQn86QArIVbxj6fniJQzx3D2UatU3R4U1UbcCLc3hAcGV/rsT6t2kNAcDnyR2YD6D5WlNrfJmNMVzFTQTcj7jcxZidkCzOS8g79saIlOZZibsq6raEELDMQQdCa193tBearoQxW3EmaaoOXW7mUCxFNKEBSm1C4tStUZOs7gSJBqt2YhhXRHIDodVX9VRipifDjB7I2LVwsDgOFecSQ8Ph5ZFcC3Cqbp6UcLprfGY1HCLojM8eMzlVXAVqI6bzLC0xHT9KfMZ0NekGWgO2B1Dray8FNBzFOGoNLR5B18VGlXK/9ojoGBLOOSJqSwd5nHX+viK/yyOrVi390JioQGAd/47G+fMy5WKsJA93ex13cMgzshuQbHBHuNBYKuIBuB3MAru2bFnMSyxm3cKF0lMr429oXxrOm7kf/mRZXyfQHbg4ihsKz9jk4IHYPQ5DG1BlOUpz2bYVVySpPlc8U7l5cCM/0WBLxCtyfdUdt0raPc+Plxsopw64O26ditS2PoujN2en0XpYeq1HE4hubj2O3RP6Q82HIsM2KO6fu0KKx5VNCaEHx07whkI254r7tG0alM9zkN2Qi2nrtjLhFZbZKH/nkn8OJH8Uw0inbxZUcpNtYAuiO+VLmVAhOft8yZFq+dETRVj5TZk9/B8=</diagram></mxfile>
|
BIN
report/usecase.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
report/Схема программы.png
Normal file
After Width: | Height: | Size: 61 KiB |
4
report/Схема программы.svg
Normal file
After Width: | Height: | Size: 16 KiB |
2
utils.h
@@ -16,7 +16,7 @@ wxString PRemaining(uint8_t remaining);
|
||||
#define mmin(a, b) (a + b - abs(a - b)) / 2 // среднее арифметическое минус половина разницы
|
||||
#define mmax(a, b) (a + b + abs(a - b)) / 2 // среднее арифметическое плюс половина разницы
|
||||
|
||||
using CardT = int16_t;
|
||||
using CardT = int8_t;
|
||||
|
||||
struct Dimensions : wxSize { // используется там, где необходимо задать размеры в трёх координатах
|
||||
Dimensions(int _z, int _x, int _y) : z(_z), wxSize(_x, _y){};
|
||||
|