diff --git a/build/Makefile b/build/Makefile index d005c46..7170d3f 100644 --- a/build/Makefile +++ b/build/Makefile @@ -23,8 +23,8 @@ all: $(TARGETLIBS) libkeyboard.so libcheck.so libmap_operation.so libutility.so: lib%.so: %.o $(CC) -shared -o $@ $< -libpuzzle.so: puzzle.o libutility.so libcheck.so libmap_operation.so libsolve.so libmain.so - $(CC) -shared $(LIBSEARCH) -o libpuzzle.so puzzle.o -lutility -lcheck -lmap_operation -lsolve -lmain -lpthread +libpuzzle.so: puzzle.o libutility.so libcheck.so libmap_operation.so libsolve.so libmain.so libanalyze.so + $(CC) -shared $(LIBSEARCH) -o libpuzzle.so puzzle.o -lutility -lcheck -lmap_operation -lsolve -lanalyze -lmain -lpthread libbuildin: make -C ../buildin @@ -32,6 +32,9 @@ libbuildin: libdefdata.so: defdata.o libbuildin $(CC) -shared $(LIBSEARCH) -o libdefdata.so defdata.o $(DEFDATADEPEND) +libanalyze.so: analyze.o libcheck.so + $(CC) -shared $(LIBSEARCH) -o libanalyze.so analyze.o -lcheck + libmain.so libsolve.so: lib%.so: %.o libutility.so libkeyboard.so libcheck.so $(CC) -shared $(LIBSEARCH) -o $@ $< -lkeyboard -lcheck -lutility diff --git a/build/analyze.cpp b/build/analyze.cpp new file mode 100644 index 0000000..c56628f --- /dev/null +++ b/build/analyze.cpp @@ -0,0 +1,50 @@ +#include"analyze.h" +#include"check.h" + +namespace game +{ + static void analyze_point_pos( + const point& __pre, const point& __now, + vector& __trace + ) + { + const long __d_x = static_cast(__now.x-__pre.x); + const long __d_y = static_cast(__now.y-__pre.y); + if(__d_x == 0) + { + if(__d_y == 1) + { __trace.push_back(keyboard::keyboard_mapping::right_arrow);} + if(__d_y == -1) + { __trace.push_back(keyboard::keyboard_mapping::left_arrow);} + } + if(__d_y == 0) + { + if(__d_x == 1) + { __trace.push_back(keyboard::keyboard_mapping::down_arrow);} + if(__d_x == -1) + { __trace.push_back(keyboard::keyboard_mapping::up_arrow);} + } + } + + void analyze_point_trace( + const matrix& __map, + const std::map& __mapping, + const vector& __po, + vector& __trace + ) + { + typedef vector::const_iterator __iterator; + __iterator __i = __po.begin(); + __iterator __j = __i; + ++__i; + for(; __i != __po.end(); ++__i, ++__j) + { + if(check_is_transport(__map.at(__j->x, __j->y))) + { analyze_point_pos(__mapping.find(*__j)->second, *__i, __trace);} + else + { analyze_point_pos(*__j, *__i, __trace);} + } + return; + } + +} diff --git a/build/analyze.h b/build/analyze.h new file mode 100644 index 0000000..3cde996 --- /dev/null +++ b/build/analyze.h @@ -0,0 +1,21 @@ + +#ifndef __PUZZ_ANALYZE__ +#define __PUZZ_ANALYZE__ + +#include"constant.hpp" +#include"matrix.hpp" +#include"structs.hpp" +#include"keyboard.h" +#include + +namespace game +{ + void analyze_point_trace( + const matrix& __map, + const std::map& __mapping, + const vector& __po, + vector& __trace + ); +} + +#endif // ! __PUZZ_ANALYZE__ diff --git a/build/check.cpp b/build/check.cpp index 515b6aa..08b2b54 100644 --- a/build/check.cpp +++ b/build/check.cpp @@ -25,6 +25,9 @@ namespace game __col > 0 && __col < __map.col(); } + bool check_is_dest(base_type __step) noexcept + { return __step == puzz_dest;} + bool check_is_transport(base_type __step) noexcept { return __step == puzz_tran;} diff --git a/build/check.h b/build/check.h index 4607b88..45c8426 100644 --- a/build/check.h +++ b/build/check.h @@ -10,18 +10,16 @@ namespace game { bool check_block_vaild(base_type __step) noexcept; - bool check_is_passage(base_type __step) noexcept; + bool check_is_dest(base_type __step) noexcept; + bool check_is_write_ligatures(base_type __step) noexcept; + bool check_is_transport(base_type __step) noexcept; bool check_not_out( unsigned long __row, unsigned long __col, const matrix& __map ) noexcept; - bool check_is_transport(base_type __step) noexcept; - - bool check_is_write_ligatures(base_type __step) noexcept; - bool check_map_base(const matrix& __map) noexcept; bool check_map_wall(const matrix& __map) noexcept; bool check_is_mapped_vaild(const matrix& __map) noexcept; diff --git a/build/main.cpp b/build/main.cpp index 39eed83..f814303 100644 --- a/build/main.cpp +++ b/build/main.cpp @@ -45,7 +45,7 @@ namespace game namespace game { - static void init_position( + void init_position( const matrix& __map, game_postion& __pos ) noexcept { @@ -106,15 +106,6 @@ namespace game return; } - void init_position( - const matrix& __map, - point_mutex& __now - ) noexcept - { - init_position(__map, __now.__pos); - return; - } - static void readapt_postion( const matrix& __map, game_postion& __pos, const bool __row, const bool __col @@ -325,9 +316,45 @@ namespace game std::lock_guard __guard(__map.__mutex); std::lock_guard __now_guard(__now.__mutex); - return __map.__data.at(__now.__pos.x, __now.__pos.y) == puzz_dest; + return check_is_dest(__map.__data.at(__now.__pos.x, __now.__pos.y)); + } + + void _game_playing( + countdown_mutex* __timer, mutex_puzz* __map, + const std::map* __mapping, + point_mutex* __now, + const bool __row, const bool __col + ) + { + keyboard::keyboard_mapping __dir; + while(true) + { + if(check_record()) + { return;} + __dir = keyboard::keyboard_one_step(); + if(check_record()) + { return;} + move_one_step(*__map, *__now, __row, __col, *__mapping, __dir); + if(check_record()) + { return;} + if(check_is_at_dest(*__map, *__now)) + { + test_out(); + draw_play_matrix(*__map, *__now); + printf("You finished the game.\n\n"); + return; + } + draw_play_matrix(*__map, *__now, *__timer); + if(check_record()) + { return;} + } } +} + +namespace game +{ + void _time_opreator( countdown_mutex* __timer, mutex_puzz* __map, point_mutex* __now @@ -358,35 +385,57 @@ namespace game exit(EXIT_SUCCESS); } - void _game_playing( - countdown_mutex* __timer, mutex_puzz* __map, - const std::map* __mapping, - point_mutex* __now, - const bool __row, const bool __col - ) +} + +namespace game +{ + static void delay(std::clock_t times) noexcept { - keyboard::keyboard_mapping __dir; - while(true) + using std::clock_t; + using std::clock; + for(clock_t __now = clock(); clock() - __now < times;) + { } + } + void show_puzzle_trace( + matrix& __map, game_postion& __pos, + const std::map& __mapping, + const vector& __po + ) noexcept + { + using std::time_t; + using std::time; + + init_position(__map, __pos); + + auto __use = [&__map, &__pos]()->void{ + reflush_screen(); + char __tmp = __map.at(__pos.x, __pos.y); + __map.at(__pos.x, __pos.y) = puzz_now; + draw_matrix( + __map, __pos.__up, __pos.__down, __pos.__left, __pos.__right + ); + __map.at(__pos.x, __pos.y) = __tmp; + +#ifndef NDEBUG + printf("\nNow position:(%4lu, %4lu)\n", __pos.x, __pos.y); + printf("\nNow draw position:\n"); + printf("UP:\t%4lu\n", __pos.__up); + printf("DOWN:\t%4lu\n", __pos.__down); + printf("LEFT:\t%4lu\n", __pos.__left); + printf("RIGHT:\t%4lu\n", __pos.__right); +#endif // ! NDEBUG + + delay(CLOCKS_PER_SEC / 10 * 3); + return; + }; + + __use(); + const bool __row = __pos.__up != 0 || __pos.__down != __map.row(); + const bool __col = __pos.__left != 0 || __pos.__right != __map.col(); + for(const keyboard::keyboard_mapping& __dir: __po) { - if(check_record()) - { return;} - __dir = keyboard::keyboard_one_step(); - if(check_record()) - { return;} - move_one_step(*__map, *__now, __row, __col, *__mapping, __dir); - if(check_record()) - { return;} - if(check_is_at_dest(*__map, *__now)) - { - test_out(); - draw_play_matrix(*__map, *__now); - printf("You finished the game.\n\n"); - return; - } - draw_play_matrix(*__map, *__now, *__timer); - if(check_record()) - { return;} + move_one_step(__map, __pos, __row, __col, __mapping, __dir); + __use(); } } - } diff --git a/build/main.h b/build/main.h index f569f83..096c44e 100644 --- a/build/main.h +++ b/build/main.h @@ -63,7 +63,7 @@ namespace game void init_record() noexcept; void init_position( const matrix& __map, - point_mutex& __now + game_postion& __now ) noexcept; void draw_play_matrix( @@ -88,6 +88,11 @@ namespace game point_mutex* __now ); + void show_puzzle_trace( + matrix& __map, game_postion& __pos, + const std::map& __mapping, + const vector& __po + ) noexcept; } #endif // ! __PUZZLE_MAIN_PROCESS__ diff --git a/build/puzzle.cpp b/build/puzzle.cpp index 00a33b2..c292685 100644 --- a/build/puzzle.cpp +++ b/build/puzzle.cpp @@ -4,6 +4,8 @@ #include"map_operation.h" #include"solve.h" #include"main.h" +#include"analyze.h" +#include"keyboard.h" #include #include #include @@ -16,7 +18,7 @@ namespace game puzzle::~puzzle() { } - bool puzzle::load_data(const char* __str) + bool puzzle::load_file(const char* __str) { using std::FILE; using std::fopen; @@ -26,7 +28,7 @@ namespace game FILE* __file = fopen(__str, "r"); if(__file == nullptr) { - fprintf(stderr, "Error when open the file:%s", __str); + fprintf(stderr, "Error when opening the file:%s", __str); return false; } unsigned long __r, __c; @@ -146,7 +148,7 @@ namespace game namespace game { - void puzzle::game_play() + void puzzle::game_play() const { using std::printf; @@ -166,7 +168,7 @@ namespace game __st_po, this->__select, __now.__pos.x, __now.__pos.y ); - init_position(__map.__data, __now); + init_position(__map.__data, __now.__pos); reflush_screen(); draw_play_matrix(__map, __now, __clock); @@ -189,15 +191,10 @@ namespace game { __thread2.join();} } - void puzzle::game_solve() + void puzzle::game_solve() const { using std::printf; - reflush_screen(); - printf("This is the map:\n"); - draw_matrix(this->__data); - printf("\n"); - bool __res = find_all_shortest_path(this->__data, this->__mapping); if(!__res) { @@ -205,15 +202,10 @@ namespace game return; } } - void puzzle::game_solve_all() + void puzzle::game_solve_all() const { using std::printf; - reflush_screen(); - printf("This is the map:\n"); - draw_matrix(this->__data); - printf("\n"); - bool __res = find_all_path(this->__data, this->__mapping); if(!__res) { @@ -222,6 +214,42 @@ namespace game } } + void puzzle::game_show(const char* __fname) + { + using std::printf; + using std::fopen; + using std::fclose; + using std::fscanf; + using std::fprintf; + + FILE* __file = fopen(__fname, "r"); + if(__file == nullptr) + { + fprintf(stderr, "Error when opening the file:%s", __fname); + return; + } + unsigned long __num; + unsigned long __x, __y; + vector __po; + game_postion __now; + fscanf(__file, "%lu", &__num); + for(unsigned long __i = 0; __i != __num; ++__i) + { + if(fscanf(__file, "%lu%lu", &__x, &__y) != 2) + { + fprintf(stderr, "Error when reading the file:%s", __fname); + return; + } + __po.push_back(point{__x, __y}); + } + + __now.x = __po.front().x; + __now.y = __po.front().y; + vector __rec; + analyze_point_trace(this->__data, this->__mapping, __po, __rec); + show_puzzle_trace(this->__data, __now, this->__mapping, __rec); + } + const puzzle::data_type& puzzle::map_data() const noexcept { return this->__data;} const puzzle::time_type& puzzle::time_data() const noexcept diff --git a/build/puzzle.h b/build/puzzle.h index 0af383c..e65fcd5 100644 --- a/build/puzzle.h +++ b/build/puzzle.h @@ -32,7 +32,7 @@ namespace game ~puzzle(); public: - bool load_data(const char* __str); + bool load_file(const char* __str); bool load_data(const data_type& __file_data); bool load_data(data_type&& __file_data); bool load_mapping(const std::map& __file_data); @@ -44,9 +44,10 @@ namespace game bool load_select(long long __at) noexcept; public: - void game_play(); - void game_solve(); - void game_solve_all(); + void game_play() const; + void game_solve() const; + void game_solve_all() const; + void game_show(const char* __fname); public: const data_type& map_data() const noexcept; diff --git a/build/solve.cpp b/build/solve.cpp index 9f94abb..7aaad89 100644 --- a/build/solve.cpp +++ b/build/solve.cpp @@ -1,29 +1,31 @@ #include"solve.h" -#include"utility.h" #include"keyboard.h" +#include"utility.h" #include"check.h" #include namespace game { - static void draw_solve_path( - const matrix& __map, const vector& __rec - ) + static void draw_solve_path(const vector& __rec) { - matrix __use(__map); - for(const auto& __tmp : __rec) - { __use.at(__tmp.x, __tmp.y) = puzz_write;} - __use.at(__rec.front().x, __rec.front().y) = puzz_start; - __use.at(__rec.back().x, __rec.back().y) = puzz_dest; - draw_matrix(__use); - printf("\n"); + printf("%lu\n", __rec.size()); + unsigned long __use = 0; + for(const point& __tmp : __rec) + { + printf("%lu %lu ", __tmp.x, __tmp.y); + ++__use; + if((__use & 0x7U) == 0) + { printf("\n");} + } + printf("\n\n"); } namespace __detail { static void __fill_map( const matrix& __map, matrix& __filled, + const std::map& __mapping, unsigned long __r, unsigned long __c ) { @@ -43,21 +45,31 @@ namespace game for(unsigned long __i = 0; __i != 4; ++__i) { - const unsigned long __trow = static_cast(__now.__x)+x_dic[__i]; - const unsigned long __tcol = static_cast(__now.__y)+y_dic[__i]; - if(check_not_out(__trow, __tcol, __map) && - check_is_passage(__map.at(__trow, __tcol))) + const unsigned long __tx = static_cast(__now.__x)+x_dic[__i]; + const unsigned long __ty = static_cast(__now.__y)+y_dic[__i]; + if(check_not_out(__tx, __ty, __map) && + check_is_passage(__map.at(__tx, __ty))) { - if(check_is_transport(__map.at(__trow, __tcol))) + if((__filled.at(__tx, __ty) == -1 || + __filled.at(__tx, __ty) > __now.__step+1)) { - ; + if(check_is_transport(__map.at(__tx, __ty))) + { + __filled.at(__tx, __ty) = __now.__step+1; + point __tmp = __mapping.find(point{__tx, __ty})->second; + if(__filled.at(__tmp.x, __tmp.y) == -1 || + __filled.at(__tmp.x, __tmp.y) > __now.__step+1) + { + __filled.at(__tmp.x, __tmp.y) = __now.__step+1; + __queue.push(__point{__tmp.x, __tmp.y, __now.__step+1}); + } + } + else + { + __filled.at(__tx, __ty) = __now.__step+1; + __queue.push(__point{__tx, __ty, __now.__step+1}); + } } - // if((__filled.at(__trow, __tcol) == -1 || - // __filled.at(__trow, __tcol) > __now.__step+1)) - // { - // __queue.push(__point{__trow, __tcol, __now.__step+1}); - // __filled.at(__trow, __tcol) = __now.__step+1; - // } } } @@ -66,6 +78,7 @@ namespace game static void __find_all( const matrix& __map, + const std::map& __mapping, const unsigned long __res, const matrix& __filled, vector& __porec, unsigned long __r, unsigned long __c @@ -75,11 +88,10 @@ namespace game if(__map.at(__r, __c) == puzz_dest) { - reflush_screen(); - draw_solve_path(__map, __porec); - keyboard::keyboard_one_step(); + draw_solve_path(__porec); return; } + if(__porec.size() == __res) { return;} @@ -87,15 +99,28 @@ namespace game for(unsigned long __i = 0; __i != 4; ++__i) { - const unsigned long __trow = static_cast(__r)+x_dic[__i]; - const unsigned long __tcol = static_cast(__c)+y_dic[__i]; + const unsigned long __tx = static_cast(__r)+x_dic[__i]; + const unsigned long __ty = static_cast(__c)+y_dic[__i]; - if(check_not_out(__trow, __tcol, __map) && - __filled.at(__r, __c) + 1 == __filled.at(__trow, __tcol) + if(check_not_out(__tx, __ty, __map) && + __filled.at(__r, __c) + 1 == __filled.at(__tx, __ty) ) { - __porec.push_back(point{__trow, __tcol}); - __find_all(__map, __res, __filled, __porec, __trow, __tcol); + __porec.push_back(point{__tx, __ty}); + if(check_is_transport(__map.at(__tx, __ty))) + { + const point __tmp = + __mapping.find(point{__tx, __ty})->second; + __find_all( + __map, __mapping, __res, __filled, __porec, __tmp.x, __tmp.y + ); + } + else + { + __find_all( + __map, __mapping, __res, __filled, __porec, __tx, __ty + ); + } __porec.pop_back(); } } @@ -137,7 +162,7 @@ namespace game unsigned long __res; matrix __record(__map.row(), __map.col()); __record.init(-1); - __detail::__fill_map(__map, __record, __po.x, __po.y); + __detail::__fill_map(__map, __record, __mapping, __po.x, __po.y); __res = __detail::__find_min_dest(__map, __record); if(__res == 0) @@ -147,7 +172,7 @@ namespace game vector __porec; __porec.push_back(point{__po.x, __po.y}); __detail::__find_all( - __map, 0xffffffffUL,__record, __porec, __po.x, __po.y + __map, __mapping, 0xffffffffUL, __record, __porec, __po.x, __po.y ); } @@ -169,8 +194,15 @@ namespace game unsigned long __res; matrix __record(__map.row(), __map.col()); __record.init(-1); - __detail::__fill_map(__map, __record, __po.x, __po.y); - + __detail::__fill_map(__map, __record, __mapping, __po.x, __po.y); +#ifndef NDEBUG + for(unsigned long __i = 0; __i != __record.row(); ++__i) + { + for(unsigned long __j = 0; __j != __record.col(); ++__j) + { printf("%3ld ", __record.at(__i, __j));} + printf("\n"); + } +#endif // ! NDEBUG __res = __detail::__find_min_dest(__map, __record); if(__res == 0) { continue;} @@ -179,7 +211,7 @@ namespace game vector __porec; __porec.push_back(point{__po.x, __po.y}); __detail::__find_all( - __map, __res+1, __record, __porec, __po.x, __po.y + __map, __mapping, __res+1, __record, __porec, __po.x, __po.y ); } return __sum; diff --git a/build/solve.h b/build/solve.h index 4242b6a..d6bff43 100644 --- a/build/solve.h +++ b/build/solve.h @@ -5,6 +5,7 @@ #include"constant.hpp" #include"matrix.hpp" #include"structs.hpp" +#include"keyboard.h" #include namespace game diff --git a/build/utility.cpp b/build/utility.cpp index e3f288c..4f81c09 100644 --- a/build/utility.cpp +++ b/build/utility.cpp @@ -1,6 +1,7 @@ #include"utility.h" #include #include +#include namespace game { @@ -11,42 +12,7 @@ namespace game } void draw_matrix(const matrix& __map) noexcept - { - using std::printf; - for(unsigned long __i = 0; __i != __map.row(); ++__i) - { - for(unsigned long __j = 0; __j != __map.col(); ++__j) - { - switch(__map.at(__i, __j)) - { - case puzz_trap_wall: - case puzz_wall: - printf(" #"); - break; - case puzz_now: - printf(" \e[1;36m@\e[0m"); - break; - case puzz_start: - printf(" \e[1;31m0\e[0m"); - break; - case puzz_dest: - printf(" \e[1;31m1\e[0m"); - break; - case puzz_trap_pass: - case puzz_pass: - printf(" \e[1;30m-\e[0m"); - break; - case puzz_write: - printf(" \e[1;33mx\e[0m"); - break; - case puzz_tran: - printf(" \e[1;35m+\e[0m"); - break; - } - } - printf("\n"); - } - } + { draw_matrix(__map, 0, __map.row(), 0, __map.col());} void draw_matrix( const matrix& __map, @@ -125,6 +91,7 @@ namespace game unsigned long& __x, unsigned long& __y ) noexcept { + srand(time(nullptr)); unsigned long long __where = 0; if(__at < 0) { __where = rand();} diff --git a/puzzle.gen.cpp b/puzzle.gen.cpp index ddd1a72..7ad34b3 100644 --- a/puzzle.gen.cpp +++ b/puzzle.gen.cpp @@ -143,7 +143,7 @@ int main(int argc, char* argv[]) unsigned long __in = 0; game::puzzle puzz; - if(puzz.load_data(argv[1])) + if(puzz.load_file(argv[1])) { print_header(__in); print_map_data_header(__in); diff --git a/puzzle.main.cpp b/puzzle.main.cpp index 450090b..3847ced 100644 --- a/puzzle.main.cpp +++ b/puzzle.main.cpp @@ -10,6 +10,7 @@ // #include"./build/map_operation.h" // #include"./build/puzzle.h" // #include"./build/solve.h" +// #include"./build/analyze.h" // #include"./build/utility.h" // #include"./buildin/map_0.h" // #include"./buildin/map_1.h" @@ -21,6 +22,7 @@ // #include"./build/map_operation.cpp" // #include"./build/puzzle.cpp" // #include"./build/solve.cpp" +// #include"./build/analyze.cpp" // #include"./build/utility.cpp" // #include"./buildin/map_0.cpp" // #include"./buildin/map_1.cpp" @@ -131,22 +133,22 @@ int main(int argc, char* argv[]) // goto help_error; // } - std::vector __po; - game::matrix __map; - std::map __mapping; - game::build_in_data(__map, 1); - game::build_in_mapping(__mapping, 1); - game::countdown __time = game::build_in_time(1); + // std::vector __po; + // game::matrix __map; + // std::map __mapping; + // game::build_in_data(__map, 0); + // game::build_in_mapping(__mapping, 0); + // game::countdown __time = game::build_in_time(0); game::puzzle puzz; if( - puzz.load_data(std::move(__map)) && - puzz.load_time(__time) && - puzz.load_mapping(std::move(__mapping)) && - puzz.load_select(-1) - // puzz.load_data("/home/inochi/codes/vscode/Cpp/game-puzzle/output.map") + // puzz.load_data(std::move(__map)) && + // puzz.load_time(__time) && + // puzz.load_mapping(std::move(__mapping)) && + // puzz.load_select(-1) + puzz.load_file("/home/inochi/codes/vscode/Cpp/game-puzzle/output.map") ) - { puzz.game_play();} + { puzz.game_show("/home/inochi/codes/vscode/Cpp/game-puzzle/output");} return 0; }