minesweeper_game_screen_i.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #ifndef MINESWEEPERGAMESCREEN_I_H
  2. #define MINESWEEPERGAMESCREEN_I_H
  3. #include "m-rbtree.h"
  4. #include "m-deque.h"
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif
  8. /** We can use this Point struct for the 2d position for the minesweeper game.
  9. * We define the necessary functions needed for this user defined type
  10. * so that we can make use of M*LIB's Red Black Tree and Double Ended
  11. * Queue for DFS and other algorithms for our MineSweeper game
  12. */
  13. typedef struct {
  14. uint8_t x, y;
  15. } Point;
  16. typedef struct {
  17. bool allocated;
  18. Point p;
  19. } Point_t[1];
  20. static inline void pointobj_init(Point_t dest) {
  21. dest->p = (Point){.x = 0, .y = 0};
  22. dest->allocated = true;
  23. }
  24. static inline void pointobj_clear(Point_t dest) {
  25. assert(dest->allocated);
  26. dest->allocated = false;
  27. }
  28. static inline void pointobj_init_set(Point_t dest, const Point_t source) {
  29. dest->p = source->p;
  30. dest->allocated = true;
  31. }
  32. static inline void pointobj_set(Point_t dest, const Point_t source) {
  33. if(dest != source) {
  34. pointobj_clear(dest);
  35. pointobj_init_set(dest, source);
  36. }
  37. }
  38. static inline void pointobj_set_point(Point_t dest, Point value) {
  39. dest->p = value;
  40. }
  41. static inline void pointobj_init_set_point(Point_t dest, Point val) {
  42. pointobj_init(dest);
  43. pointobj_set_point(dest, val);
  44. }
  45. static inline bool pointobj_equal_p(const Point_t a, const Point_t b) {
  46. return (a->p.x == b->p.x && a->p.y == b->p.y) ? true : false;
  47. }
  48. static inline int pointobj_cmp(const Point_t a, const Point_t b) {
  49. if(a->p.x != b->p.x) return (a->p.x < b->p.x) ? -1 : 1;
  50. if(a->p.y != b->p.y) return (a->p.y < b->p.y) ? -1 : 1;
  51. return 0;
  52. }
  53. // This is the oplist needed to define the rb tree and dequeue and uses the/
  54. // above functions.
  55. #define POINT_OPLIST \
  56. (TYPE(Point_t), \
  57. INIT(pointobj_init), \
  58. INIT_SET(pointobj_init_set), \
  59. SET(pointobj_set), \
  60. CLEAR(pointobj_clear), \
  61. EQUAL(pointobj_equal_p), \
  62. CMP(pointobj_cmp))
  63. // Use this to get rid of -Wunused-parameter errors for this macro only
  64. #pragma GCC diagnostic push
  65. #pragma GCC diagnostic ignored "-Wunused-parameter"
  66. // Example Macro defining the RBTREE for Point that will be used as an ordered set
  67. RBTREE_DEF(point_set, Point_t, POINT_OPLIST)
  68. #pragma GCC diagnostic pop
  69. // Example Macro defining the DEQ for Point that will be used as a double ended queue
  70. DEQUE_DEF(point_deq, Point_t, POINT_OPLIST)
  71. // Helper to convert the Point_t type to Point
  72. static inline Point pointobj_get_point(const Point_t z) {
  73. return z->p;
  74. }
  75. // Printing deq to debug
  76. static inline void print_deq_to_debug(point_deq_t* deq) {
  77. point_deq_it_t it;
  78. for(point_deq_it(it, *deq); !point_deq_end_p(it); point_deq_next(it)) {
  79. Point ref = pointobj_get_point(*point_deq_ref(it));
  80. FURI_LOG_D("DEQ DEBUG:", "(%hd,%hd), ", ref.x, ref.y);
  81. }
  82. }
  83. // Printing ordered set to debug
  84. static inline void print_ordered_set_to_debug(point_set_t* tree) {
  85. point_set_it_t it;
  86. for(point_set_it(it, *tree); !point_set_end_p(it); point_set_next(it)) {
  87. Point ref = pointobj_get_point(*point_set_ref(it));
  88. FURI_LOG_D("SET DEBUG:", "(%hd,%hd), ", ref.x, ref.y);
  89. }
  90. }
  91. #ifdef __cplusplus
  92. }
  93. #endif
  94. #endif