move.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #include "move.h"
  2. #include "utils.h"
  3. uint8_t coord_from(uint8_t x, uint8_t y) {
  4. return (y * SIZE_X) + x;
  5. }
  6. //-----------------------------------------------------------------------------
  7. uint8_t coord_x(uint8_t coord) {
  8. return coord % SIZE_X;
  9. }
  10. //-----------------------------------------------------------------------------
  11. uint8_t coord_y(uint8_t coord) {
  12. return coord / SIZE_X;
  13. }
  14. //-----------------------------------------------------------------------------
  15. uint8_t movable_dir(MovabilityTab* mv, uint8_t currentMovable) {
  16. return (currentMovable != MOVABLE_NOT_FOUND) ?
  17. (*mv)[coord_y(currentMovable)][coord_x(currentMovable)] :
  18. MOVABLE_NOT;
  19. }
  20. //-----------------------------------------------------------------------------
  21. void map_movability(PlayGround* pg, PlayGround* mv) {
  22. uint8_t tile, x, y, movable;
  23. for(y = 0; y < SIZE_Y; y++) {
  24. for(x = 0; x < SIZE_X; x++) {
  25. movable = MOVABLE_NOT;
  26. tile = (*pg)[y][x];
  27. if(is_block(tile)) {
  28. if(x > 0 && ((*pg)[y][x - 1] == EMPTY_TILE)) movable += MOVABLE_LEFT;
  29. if((x < (SIZE_X - 1)) && ((*pg)[y][x + 1] == EMPTY_TILE)) movable += MOVABLE_RIGHT;
  30. }
  31. (*mv)[y][x] = movable;
  32. }
  33. }
  34. }
  35. //-----------------------------------------------------------------------------
  36. uint8_t find_movable(PlayGround* mv) {
  37. uint8_t x, y;
  38. for(y = 0; y < SIZE_Y; y++) {
  39. for(x = 0; x < SIZE_X; x++) {
  40. if((*mv)[y][x] != MOVABLE_NOT) return coord_from(x, y);
  41. }
  42. }
  43. return MOVABLE_NOT_FOUND;
  44. }
  45. //-----------------------------------------------------------------------------
  46. uint8_t find_movable_rev(PlayGround* mv) {
  47. uint8_t x, y;
  48. for(y = SIZE_Y - 1; y > 0; y--) {
  49. for(x = SIZE_X - 1; x > 0; x--) {
  50. if((*mv)[y][x] != MOVABLE_NOT) return coord_from(x, y);
  51. }
  52. }
  53. return MOVABLE_NOT_FOUND;
  54. }
  55. //-----------------------------------------------------------------------------
  56. void find_movable_left(PlayGround* mv, uint8_t* currentMovable) {
  57. const uint8_t sx = (*currentMovable != MOVABLE_NOT_FOUND) ? coord_x(*currentMovable) :
  58. SIZE_X / 2;
  59. const uint8_t sy = (*currentMovable != MOVABLE_NOT_FOUND) ? coord_y(*currentMovable) : 0;
  60. uint8_t px = sx;
  61. // to the left, same line
  62. while(px > 0) {
  63. px--;
  64. if((*mv)[sy][px] != MOVABLE_NOT) {
  65. *currentMovable = coord_from(px, sy);
  66. return;
  67. }
  68. }
  69. uint8_t x, y;
  70. for(y = sy - 1; y > 0; y--) {
  71. for(x = SIZE_X - 1; x > 0; x--) {
  72. if((*mv)[y][x] != MOVABLE_NOT) {
  73. *currentMovable = coord_from(x, y);
  74. return;
  75. }
  76. }
  77. }
  78. uint8_t last = find_movable_rev(mv);
  79. if(last != MOVABLE_NOT_FOUND) {
  80. *currentMovable = last;
  81. }
  82. }
  83. //-----------------------------------------------------------------------------
  84. void find_movable_right(PlayGround* mv, uint8_t* currentMovable) {
  85. const uint8_t sx = (*currentMovable != MOVABLE_NOT_FOUND) ? coord_x(*currentMovable) :
  86. SIZE_X / 2;
  87. const uint8_t sy = (*currentMovable != MOVABLE_NOT_FOUND) ? coord_y(*currentMovable) : 0;
  88. uint8_t px = sx;
  89. uint8_t py = sy;
  90. // search right
  91. while(px < SIZE_X - 1) {
  92. px++;
  93. if((*mv)[sy][px] != MOVABLE_NOT) {
  94. *currentMovable = coord_from(px, sy);
  95. return;
  96. }
  97. }
  98. uint8_t x, y;
  99. for(y = py + 1; y < SIZE_Y; y++) {
  100. for(x = 0; x < SIZE_X; x++) {
  101. if((*mv)[y][x] != MOVABLE_NOT) {
  102. *currentMovable = coord_from(x, y);
  103. return;
  104. }
  105. }
  106. }
  107. uint8_t first = find_movable(mv);
  108. if(first != MOVABLE_NOT_FOUND) {
  109. *currentMovable = first;
  110. }
  111. }
  112. //-----------------------------------------------------------------------------
  113. void find_movable_down(PlayGround* mv, uint8_t* currentMovable) {
  114. uint8_t sx = (*currentMovable != MOVABLE_NOT_FOUND) ? coord_x(*currentMovable) : SIZE_X / 2;
  115. uint8_t sy = (*currentMovable != MOVABLE_NOT_FOUND) ? coord_y(*currentMovable) : 0;
  116. uint8_t py = sy;
  117. uint8_t delta, px_l, px_r;
  118. while(py < SIZE_Y - 1) {
  119. py++;
  120. if((*mv)[py][sx] != MOVABLE_NOT) {
  121. *currentMovable = coord_from(sx, py);
  122. return;
  123. }
  124. }
  125. py = sy;
  126. while(py < SIZE_Y - 1) {
  127. py++;
  128. delta = 0;
  129. while(delta < SIZE_X) {
  130. delta++;
  131. px_r = MIN(sx + delta, SIZE_X - 1);
  132. if((*mv)[py][px_r] != MOVABLE_NOT) {
  133. *currentMovable = coord_from(px_r, py);
  134. return;
  135. }
  136. px_l = MAX(sx - delta, 0);
  137. if((*mv)[py][px_l] != MOVABLE_NOT) {
  138. *currentMovable = coord_from(px_l, py);
  139. return;
  140. }
  141. }
  142. }
  143. }
  144. //-----------------------------------------------------------------------------
  145. void find_movable_up(PlayGround* mv, uint8_t* currentMovable) {
  146. uint8_t sx = (*currentMovable != MOVABLE_NOT_FOUND) ? coord_x(*currentMovable) : SIZE_X / 2;
  147. uint8_t sy = (*currentMovable != MOVABLE_NOT_FOUND) ? coord_y(*currentMovable) : 0;
  148. uint8_t py = sy;
  149. uint8_t delta, px_l, px_r;
  150. while(py > 0) {
  151. py--;
  152. if((*mv)[py][sx] != MOVABLE_NOT) {
  153. *currentMovable = coord_from(sx, py);
  154. return;
  155. }
  156. }
  157. py = sy;
  158. while(py > 0) {
  159. py--;
  160. delta = 0;
  161. while(delta < SIZE_X) {
  162. delta++;
  163. px_r = MIN(sx + delta, SIZE_X - 1);
  164. if((*mv)[py][px_r] != MOVABLE_NOT) {
  165. *currentMovable = coord_from(px_r, py);
  166. return;
  167. }
  168. px_l = MAX(sx - delta, 0);
  169. if((*mv)[py][px_l] != MOVABLE_NOT) {
  170. *currentMovable = coord_from(px_l, py);
  171. return;
  172. }
  173. }
  174. }
  175. }