Game.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #include <iostream>
  2. #include <windows.h>
  3. #include <conio.h>
  4. #include "Const.h"
  5. //Устанавливаются начальные значения параметров игры.
  6. void init_game(Field& field, Snake& snake, Game& game, Food& food)//Устанавливаются начальные значения параметров игры.
  7. {
  8. food.score = 0;//количество сьеденной еды
  9. food.food_flag = false;//Признак, что еда установлена
  10. game.timeout = 100; //Таймаут задержки между шагами игры; > 100 (ms), 1000 - будет задерживать выполнение программы на 1 секунду
  11. game.game_on = 1;//Признак продолжения игры
  12. snake.direction = turn_right;
  13. srand(time(0));//установка начала последовательности, генерируемой функ­цией rand()
  14. system("cls");//полная очистка консоли
  15. create_field(field);//Cоздание двумерного динамического массива поля на основе пользовательских данных
  16. start_snake(field, snake);//устанавливается начальное положение головы змейки при старте игры в зависимости от размера поля (по центру)
  17. init_snake(snake);//Устанавливается пользовательский размер змейки, массив змейки заполняется стартовыми значениями
  18. init_field(field);//Инициализация поля (символы заполнения поля и границ)
  19. set_snake(field, snake);//Змейка устанавливается в игровом поле
  20. print_field(field, food.score);//печать поля
  21. std::cout << "Press any key" << std::endl;//5) Вывод приглашения к игре.
  22. }
  23. //устанавливается начальное положение головы змейки при старте игры в зависимости от размера поля (по центру)
  24. void start_snake(Field& field, Snake& snake)
  25. {
  26. //int step_x = rand() % L + 1; // разработать случайное начальное положение змейки
  27. //step = 13;
  28. //snake_x[0] = 13;
  29. snake.snake_x[0] = field.columns / 2;
  30. snake.snake_y[0] = field.rows / 2;
  31. }
  32. //Змейка устанавливается в игровом поле
  33. void set_snake(Field& field, Snake& snake)
  34. {
  35. field.field[snake.snake_y[0]][snake.snake_x[0]] = head_symbol;//установка головы
  36. // установка хвоста, если есть
  37. for (int i = 1; i < snake.snake_size; i++)
  38. {
  39. field.field[snake.snake_y[i]][snake.snake_x[i]] = tail_symbol;
  40. }
  41. }
  42. //Очищается позиция змейки на поле
  43. void clear_snake(Field& field, Snake& snake)
  44. {
  45. //чистим "хвост"
  46. field.field[snake.snake_y[snake.snake_size-1]][snake.snake_x[snake.snake_size-1]] = field_symbol;
  47. }
  48. // Генерируется хначение еды и устанавливается в игровом поле.
  49. void set_food(Field& field, Food& food)
  50. {
  51. if (!food.food_flag)//если нет еды и змейка не достигла максимального размера
  52. {
  53. do
  54. {
  55. generate_food(field, food);
  56. } while (field.field[food.food_y][food.food_x] != field_symbol);
  57. field.field[food.food_y][food.food_x] = food_symbol;
  58. food.food_flag = true;
  59. }
  60. }
  61. //Выполняется проверка того, что змейка съела еду (координаты головы совпадают с кооординатами еды)
  62. void check_eating(Snake& snake, Food& food)
  63. {
  64. if (snake.snake_y[0]== food.food_y && snake.snake_x[0] == food.food_x)//Координата еды совпадают с координатами головы
  65. {
  66. food.food_flag = false;//еды нет
  67. ++food.score;
  68. snake.snake_size++; //увеличение размера змейки
  69. }
  70. }
  71. //Выполняется проверка того, что змейка встретилась с границей поля
  72. void check_snake(Field& field, Snake& snake)
  73. {
  74. if (snake.snake_x[0] == 0)
  75. {
  76. snake.snake_x[0] = field.columns - 2;
  77. }
  78. if (snake.snake_x[0] == field.columns - 1)
  79. {
  80. snake.snake_x[0] = 1;
  81. }
  82. if (snake.snake_y[0] == 0)
  83. {
  84. snake.snake_y[0] = field.rows - 2;
  85. }
  86. if (snake.snake_y[0] == field.rows - 1)
  87. {
  88. snake.snake_y[0] = 1;
  89. }
  90. }
  91. //Проверка завершения игры.
  92. int check_game(Field& field, Snake& snake, Food& food)
  93. {
  94. int tmp_game_on = 1;
  95. if (!food.food_flag && snake.snake_size == L)//если нет еды и змейка максимального размера
  96. {
  97. tmp_game_on = 0;
  98. //придумать разные варианты выводимых сообщений в зависимости от ситуации
  99. }
  100. if (field.field[snake.snake_y[0]][snake.snake_x[0]] == tail_symbol) //проверка того, что змейка встретилась с хвостом
  101. {
  102. tmp_game_on = 0;
  103. }
  104. return tmp_game_on;
  105. }
  106. //Обработка пользовательского ввода, задание направления движения змейки
  107. void handle_cmd(Snake& snake, Game& game)
  108. {
  109. char key;// для ввода кода символа с клавиатуры
  110. char keep_direct;// для сохранения символа направления движения.
  111. DIRECTION tmp_direction;
  112. key = _getch();
  113. if (key == 0 || key == -32)
  114. {
  115. keep_direct = _getch();
  116. switch (keep_direct)
  117. {
  118. case up: {tmp_direction = turn_up; } break;
  119. case down: {tmp_direction = turn_down; } break;
  120. case left: {tmp_direction = turn_left; } break;
  121. case right: {tmp_direction = turn_right; } break;
  122. default: {tmp_direction = err; }
  123. }
  124. }
  125. else
  126. {
  127. switch (key = toupper(key))
  128. {
  129. case s_right: {tmp_direction = turn_right; } break;
  130. case s_left: {tmp_direction = turn_left; } break;
  131. case s_up: {tmp_direction = turn_up; } break;
  132. case s_down: {tmp_direction = turn_down; } break;
  133. case s_out: {game.game_on = 0; } return;//убрать (объединить)
  134. case esc: {game.game_on = 0; } return;
  135. break;
  136. default: {tmp_direction = err; }
  137. }
  138. }
  139. if (tmp_direction != err)
  140. {
  141. switch (snake.direction)
  142. {
  143. case turn_up://доработать, плохо читается, можно усовершенствовать
  144. {
  145. if (tmp_direction == turn_down) { snake.direction = turn_up; }
  146. else {snake.direction = tmp_direction; }
  147. } break;
  148. case turn_down:
  149. {
  150. if (tmp_direction == turn_up) { snake.direction = turn_down; }
  151. else { snake.direction = tmp_direction; }
  152. } break;
  153. case turn_left:
  154. {
  155. if (tmp_direction == turn_right) { snake.direction = turn_left; }
  156. else { snake.direction = tmp_direction; }
  157. } break;
  158. case turn_right:
  159. {
  160. if (tmp_direction == turn_left) { snake.direction = turn_right; }
  161. else { snake.direction = tmp_direction; }
  162. } break;
  163. default: { snake.direction = tmp_direction; } break;
  164. }
  165. }
  166. }
  167. // Вывод информации при окончание игры и очистка памяти
  168. void game_over(Field& field, Snake& snake, Food& food)
  169. {
  170. setCursorPosition(0, 0);
  171. if(snake.snake_size<L) field.field[snake.snake_y[0]][snake.snake_x[0]] = head_symbol;
  172. print_field(field, food.score);
  173. if (snake.snake_size == L) std::cout << "Max size! You win!" << std::endl;
  174. else std::cout << "You lose!" << std::endl;
  175. std::cout << "The end!" << std::endl;
  176. //чистим память
  177. for (int i = 0; i < field.rows; i++)
  178. {
  179. delete[] field.field[i];
  180. }
  181. delete[] field.field;
  182. }