pepper2.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #include <curses.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <malloc_np.h>
  5. #include <string.h>
  6. #include <time.h>
  7. /* cc pepper2.c -lncurses -o p2 -O2 */
  8. typedef struct {
  9. size_t len;
  10. char *items[10];
  11. } truc_array;
  12. enum dirs {
  13. R, /* right */
  14. L, /* left */
  15. U, /* up */
  16. D /* down */
  17. };
  18. static WINDOW * winR;
  19. static void worm(WINDOW *win, int x, int y, char c0, char repl)
  20. {
  21. static int ax, ay;
  22. static char ac = '*';
  23. wattron(win, A_REVERSE | A_BOLD);
  24. mvwprintw(win, y + 1, x + 1, "%c", c0);
  25. wattroff(win, A_REVERSE | A_BOLD);
  26. if (ac != '*')
  27. mvwprintw(win, ay + 1, ax + 1, "%c", ac);
  28. wrefresh(win);
  29. ax = x;
  30. ay = y;
  31. ac = repl;
  32. usleep(150 * 1000);
  33. }
  34. static __attribute((malloc)) __attribute__((nonnull)) char *get_it(truc_array const *src)
  35. {
  36. char *r = mallocx(src->len, MALLOCX_ZERO);
  37. size_t n = 0;
  38. enum dirs dir = R;
  39. int x = 0, y = 0;
  40. char c0 = '<';
  41. WINDOW * win = newwin(14, 18, 1, 40);
  42. curs_set(0);
  43. box(win, 0, 0);
  44. while (src->len && (n < src->len)) {
  45. char c;
  46. while((c = src->items[y][x]) != ' ') {
  47. /* store */
  48. if (c != '*') {
  49. r[n++] = c;
  50. worm(win, x, y, c0, c);
  51. mvwprintw(winR, 1, 1, "%s", r);
  52. wrefresh(winR);
  53. } else
  54. worm(win, x, y, c0, '.');
  55. if (n == src->len) {
  56. break;
  57. }
  58. /* test next one */
  59. int tx = x;
  60. int ty = y;
  61. switch (dir) {
  62. case R:
  63. tx++;
  64. break;
  65. case L:
  66. tx--;
  67. break;
  68. case U:
  69. ty--;
  70. break;
  71. case D:
  72. ty++;
  73. break;
  74. default:
  75. fprintf(stderr, "Bug!\n");
  76. break;
  77. }
  78. /* ouch */
  79. if (tx > 14 || tx < 0 || ty <0 || ty > 9)
  80. break;
  81. if ((c = src->items[ty][tx]) == ' ')
  82. break;
  83. /* valid next */
  84. x = tx;
  85. y = ty;
  86. }
  87. switch (dir) {
  88. char c_up, c_down, c_left, c_right;
  89. case R:
  90. case L:
  91. /* cover up and down */
  92. c_up = ' ';
  93. c_down = ' ';
  94. if (y > 1)
  95. c_up = src->items[y - 1][x];
  96. if (y < 9)
  97. c_down = src->items[y + 1][x];
  98. if (c_up != ' ') {
  99. y = y - 1;
  100. dir = U;
  101. c0 = '^';
  102. }
  103. else if (c_down != ' ') {
  104. y = y + 1;
  105. dir = D;
  106. c0 = ';';
  107. }
  108. else
  109. goto end;
  110. break;
  111. case U:
  112. case D:
  113. /* cover left and right */
  114. c_left = ' ';
  115. c_right = ' ';
  116. if (x > 1)
  117. c_left = src->items[y][x - 1];
  118. if (y < 14)
  119. c_right = src->items[y][x + 1];
  120. if (c_left != ' ') {
  121. x = x - 1;
  122. dir = L;
  123. c0 = '>';
  124. }
  125. else if (c_right != ' ') {
  126. x = x + 1;
  127. dir = R;
  128. c0 = '<';
  129. } else
  130. goto end;
  131. break;
  132. }
  133. }
  134. end:
  135. worm(win, x , y , ' ', ' ');
  136. delwin(win);
  137. return r;
  138. }
  139. static void print_it(truc_array src)
  140. {
  141. WINDOW * win = newwin(14, 18, 1, 1);
  142. box(win, 0, 0);
  143. for (size_t j= 0; j < 10; ++j) {
  144. mvwprintw(win, j + 1, 1, "%s", src.items[j]);
  145. }
  146. wrefresh(win);
  147. delwin(win);
  148. }
  149. int main(int argc, char *argv[])
  150. {
  151. truc_array a= {60, };
  152. char *r = NULL;
  153. /* 012345789ABCDEF */
  154. a.items[0] = "*01** $";
  155. a.items[1] = "edcBA ";
  156. a.items[2] = "* * X ";
  157. a.items[3] = "* ! * ";
  158. a.items[4] = "****F** ";
  159. a.items[5] = " * *H* ";
  160. a.items[6] = " *G** * ";
  161. a.items[7] = " X I ";
  162. a.items[8] = " X **J**** ";
  163. a.items[9] = "X Z $";
  164. initscr();
  165. nonl();
  166. noecho();
  167. winR = newwin(3, 65, 20, 1);
  168. box(winR, 0, 0);
  169. wrefresh(winR);
  170. print_it(a);
  171. r = get_it(&a);
  172. dallocx(r, 0);
  173. delwin(winR);
  174. endwin();
  175. }