#include "puzzle.hpp" #include "gameplay.hpp" #include #include #include #include #include #include #include #include GameParams* GameParams::instance = nullptr; void GameParams::CalculateStandardPuzzlePos() { coordinates tmp; int i, j, k = 0; for(i = 0; i < puzzles_per_side; ++i) for(j = 0; j < puzzles_per_side; ++j, ++k) { tmp.x = i * (puzzle_size + spacing) + spacing; tmp.y = j * (puzzle_size + spacing) + spacing + 30; standard_puzzle_coordinates[k] = tmp; } } void GameParams::ResetFreePuzzles() { for(int i = 0; i < puzzle_pieces; ++i) free_puzzles[i] = 1; } static void find_path_to_picture(std::string& path, const std::string& cur_directory, int number) { path = cur_directory + std::to_string(number / puzzles_per_side) + std::to_string(number % puzzles_per_side) + ".png"; } void GameParams::NextUntestedPuzzles() { int idx_random_puzzle; std::unique_ptr tmp_puzzle; /* * check if puzzles already were created */ if(puzzles.size() != 0) puzzles.clear(); /* * ======== creating puzzles =========== */ win->begin(); for(int i = 0; i < puzzle_pieces; ++i) { idx_random_puzzle = 0 + (int)((double)puzzle_pieces * rand()/(RAND_MAX + 1.0)); while(!free_puzzles[idx_random_puzzle]) idx_random_puzzle = 0 + (int)((double)puzzle_pieces * rand()/(RAND_MAX + 1.0)); free_puzzles[idx_random_puzzle] = 0; /* empty puzzle */ if(idx_random_puzzle == puzzle_pieces-1) { SetXYEmptyBox(standard_puzzle_coordinates[i].x, standard_puzzle_coordinates[i].y); continue; } /* common puzzle */ tmp_puzzle = std::unique_ptr(new Puzzle(standard_puzzle_coordinates[i].x, standard_puzzle_coordinates[i].y)); tmp_puzzle->sequence_number = idx_random_puzzle; find_path_to_picture(tmp_puzzle->path, cur_directory, tmp_puzzle->sequence_number); Fl_PNG_Image *img = new Fl_PNG_Image(tmp_puzzle->path.c_str()); // TODO check fails img->fail(); tmp_puzzle->image(img); tmp_puzzle->callback(press_button_callback, this); puzzles.push_back(std::move(tmp_puzzle)); } win->end(); ResetFreePuzzles(); } bool GameParams::IsSolvability() { int counter = 0; for(size_t i = 0; i < puzzles.size(); ++i) for(size_t j = i+1; j < puzzles.size(); ++j) if(puzzles[i]->sequence_number > puzzles[j]->sequence_number) ++counter; return counter % 2 == 0; } void GameParams::CreateNewPuzzles() { do { NextUntestedPuzzles(); } while(!IsSolvability()); } void GameParams::SelectRandomPicture() { std::vector choices; for (const auto& entry : std::filesystem::directory_iterator("resources")) { choices.emplace_back(entry.path().string()); } std::random_device rd; std::mt19937 g(rd()); std::shuffle(choices.begin(), choices.end(), g); cur_directory = choices[0]; #if defined(_WIN32) cur_directory.append("\\"); #else cur_directory.append("/"); #endif }