back to scratko.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md43
-rw-r--r--image_converter/converter.c4
-rw-r--r--img_handler.cpp27
-rw-r--r--img_handler.hpp9
-rw-r--r--main.cpp18
-rw-r--r--puzzle.hpp12
-rw-r--r--puzzle.pngbin0 -> 114081 bytes
-rw-r--r--solution_algorithm.cpp1
-rw-r--r--solution_algorithm.hpp4
9 files changed, 96 insertions, 22 deletions
diff --git a/README.md b/README.md
index 0edea60..1e87112 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,43 @@
-<a href="https://scratko.xyz/games/puzzle.zip" target="_blank">Download Windows
+# Picture puzzle
+
+<img src="puzzle.png" />
+
+A desktop game similar to the standard widget in windows 7. The game is written
+in C++ (including C++17 standard). FLTK was used as a graphics library. This
+library is not as heavy as Qt, and allows to quickly create an application with
+graphical widgets.
+
+The essence of the game should be clear: to collect the image in its original
+form, moving one puzzle per move.
+
+The application has the following features:
+
+- *upload your image in any format and resolution. The program itself will
+ resize, cut into puzzles, create the appropriate directory and save them in
+ it.*
+
+- *showing the complete solution of the puzzle using the optimization algorithm
+ A\*.*
+
+- *the game is distributed in a single executable file by embedding the original
+ standard image (toucan image) in the executable file. The image data is stored
+ in an array in an object file (resources.o)*
+
+- *support for \*unix and Windows platforms*
+
+## Building
+
+For \*nix platform, you need to install FLTK library and then do the following:
+
+```
+git clone https://git.scratko.xyz/picture-puzzle
+cd picture-puzzle
+make
+./main
+```
+
+## For Windows platform
+
+The built executable file (under x86_64) is available at the link: <a
+href="https://scratko.xyz/games/puzzle.exe" target="_blank">Download Windows
version</a>
diff --git a/image_converter/converter.c b/image_converter/converter.c
index 4252e71..cccb9ad 100644
--- a/image_converter/converter.c
+++ b/image_converter/converter.c
@@ -1,3 +1,7 @@
+/*
+ * Embedding standard image data into a file resources.cpp
+ */
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
diff --git a/img_handler.cpp b/img_handler.cpp
index 921f639..6c62728 100644
--- a/img_handler.cpp
+++ b/img_handler.cpp
@@ -1,3 +1,8 @@
+/*
+ * Processing of images uploaded by the user
+ * (resizing, cropping, saving)
+ */
+
#include "img_handler.hpp"
#include "puzzle.hpp"
@@ -14,7 +19,7 @@
#include <iostream>
#include <string>
-ImageHandler::ImageHandler(const char *p) : path_to_file(p) {
+ImageHandler::ImageHandler(const char *p) : source_path(p) {
img_data = nullptr;
resized_data = nullptr;
/*
@@ -25,24 +30,24 @@ ImageHandler::ImageHandler(const char *p) : path_to_file(p) {
std::filesystem::create_directory(res_path);
#if defined(_WIN32)
- auto it = path_to_file.find_last_of('\\');
+ auto it = source_path.find_last_of('\\');
#else
- auto it = path_to_file.find_last_of('/');
+ auto it = source_path.find_last_of('/');
#endif
- std::string file_name = path_to_file.substr(it + 1);
+ std::string file_name = source_path.substr(it + 1);
std::string fn_withot_ext =
file_name.substr(0, file_name.find_first_of('.'));
#if defined(_WIN32)
- path_to_save = "resources\\" + fn_withot_ext + "\\";
+ destination_directory = "resources\\" + fn_withot_ext + "\\";
#else
- path_to_save = "resources/" + fn_withot_ext + '/';
+ destination_directory = "resources/" + fn_withot_ext + '/';
#endif
- std::filesystem::create_directory(path_to_save);
+ std::filesystem::create_directory(destination_directory);
}
void ImageHandler::load_img()
{
- img_data = stbi_load(path_to_file.c_str(), &in_width, &in_height,
+ img_data = stbi_load(source_path.c_str(), &in_width, &in_height,
&channel, 0);
}
@@ -62,11 +67,11 @@ void ImageHandler::save_img()
for(j = 0; j < puzzles_per_side; ++j, ++k) {
x = i * puzzle_size;
y = j * puzzle_size;
- std::string tmp_name =
- path_to_save +
+ std::string tmp_path =
+ destination_directory +
std::to_string(k / puzzles_per_side) +
std::to_string(k % puzzles_per_side) + ".png";
- stbi_write_png(tmp_name.c_str(), puzzle_size, puzzle_size, channel,
+ stbi_write_png(tmp_path.c_str(), puzzle_size, puzzle_size, channel,
resized_data + channel * (x + y * width),
width * channel);
}
diff --git a/img_handler.hpp b/img_handler.hpp
index 8c5754a..cb53807 100644
--- a/img_handler.hpp
+++ b/img_handler.hpp
@@ -1,3 +1,8 @@
+/*
+ * Processing of images uploaded by the user
+ * (resizing, cropping, saving)
+ */
+
#ifndef IMG_HANDLER_HPP_SENTRY
#define IMG_HANDLER_HPP_SENTRY
@@ -12,8 +17,8 @@ class ImageHandler {
int channel;
int in_width;
int in_height;
- std::string path_to_file;
- std::string path_to_save;
+ std::string source_path;
+ std::string destination_directory;
unsigned char *img_data;
unsigned char *resized_data;
public:
diff --git a/main.cpp b/main.cpp
index d1646e1..539130d 100644
--- a/main.cpp
+++ b/main.cpp
@@ -9,10 +9,26 @@
#include "gameplay.hpp"
#include "menu_callbacks.hpp"
+class MainWindow : public Fl_Window {
+public:
+ MainWindow(int w, int h, const char *title) : Fl_Window(w, h, title) {}
+ /*
+ * Ending program by esc key while the computer is solving a puzzle
+ */
+ int handle(int event) {
+ if(event == FL_KEYDOWN && Fl::event_length() != 0 &&
+ Fl::event_key() == FL_Escape)
+ {
+ exit(0);
+ }
+ return Fl_Window::handle(event);
+ }
+};
+
int main()
{
srand(time(nullptr));
- Fl_Window *win = new Fl_Window(320, 355, "Picture puzzle");
+ MainWindow *win = new MainWindow(320, 355, "Picture puzzle");
GameParams *params = GameParams::SetUpParams(win);
Fl_Sys_Menu_Bar *sys_bar = new Fl_Sys_Menu_Bar(0, 0, 355, 20, nullptr);
sys_bar->add("&File/&New game", nullptr, new_game_callback, params);
diff --git a/puzzle.hpp b/puzzle.hpp
index 11c5fae..09660c8 100644
--- a/puzzle.hpp
+++ b/puzzle.hpp
@@ -43,6 +43,9 @@ private:
coordinates empty_box;
std::vector<std::unique_ptr<Puzzle>> puzzles;
Fl_Window *win;
+ /*
+ * selecting the current directory where the user image is stored
+ */
std::string cur_directory;
GameParams(Fl_Window *a_win = nullptr)
@@ -55,11 +58,6 @@ private:
void CreateNewPuzzles();
void SelectRandomPicture();
Fl_PNG_Image *LoadPictureParts(std::unique_ptr<Puzzle>& tmp_puzzle);
-
- friend class PuzzleGame;
- friend class ASearch;
- friend void press_button_callback(Fl_Widget*, void*);
- friend void solve_problem_callback(Fl_Widget*, void*);
public:
void SetXYEmptyBox(int x, int y) { empty_box.x = x; empty_box. y = y; }
coordinates GetXYEmptyBox() { return empty_box; }
@@ -70,6 +68,10 @@ public:
gi->CalculateStandardPuzzlePos();
return gi;
}
+ friend class PuzzleGame;
+ friend class ASearch;
+ friend void press_button_callback(Fl_Widget*, void*);
+ friend void solve_problem_callback(Fl_Widget*, void*);
};
#endif
diff --git a/puzzle.png b/puzzle.png
new file mode 100644
index 0000000..30dd62b
--- /dev/null
+++ b/puzzle.png
Binary files differ
diff --git a/solution_algorithm.cpp b/solution_algorithm.cpp
index f0b7861..d96374b 100644
--- a/solution_algorithm.cpp
+++ b/solution_algorithm.cpp
@@ -178,6 +178,7 @@ void ASearch::ShowSolution(Node *goal)
(*puzzle_pos)->position(goal->state[i].x, goal->state[i].y);
gp->win->redraw();
Fl::flush();
+ Fl::check();
usleep(40000);
}
}
diff --git a/solution_algorithm.hpp b/solution_algorithm.hpp
index 440264b..f182aa8 100644
--- a/solution_algorithm.hpp
+++ b/solution_algorithm.hpp
@@ -16,8 +16,6 @@ private:
Node *parent_p;
int depth;
int evaluation;
- friend struct std::hash<std::shared_ptr<Node>>;
- friend class ASearch;
public:
Node(std::vector<GameParams::coordinates>& s, Node *p = nullptr,
int d = 0, int e = 0)
@@ -30,6 +28,8 @@ public:
return first->evaluation > second->evaluation;
}
};
+ friend struct std::hash<std::shared_ptr<Node>>;
+ friend class ASearch;
};
template<>