Как стать автором
Обновить

Комментарии 6

Я просто хотел разобраться как работать с make и gcc и для примера решил написать змейку в консоли ¯_(ツ)_/¯

Ну, ога. У тебя тут один файл. Зачем нужен make?

Планирую в дальнейшем уже сделать графическую змейку. Да и поупражняться в make будет не лишним

Буду рад конструктивной критике.

Нормально получилось, есть места, где читатель может сам додумать как и что написать, а не просто скопипастить код.

Другое дело, что рассказ о том как вы писали игру для платформы Windows (см. вызываются специфические функции Win32), но почему-то указан тег "makefile" и вообще упомянуты make и gcc (которые больше ассоциируются с unix`ами), тогда как о виндовом характере программы в статье ни слова (только хаб сверху указан).

Упоминание про make и gcc вообще спокойно можно убрать из статьи - хуже не будет, тем более вы ничего про него не поясняете.

Если хотите и дальше немного экспериментировать с играми в консоли, как вариант, можете обратить внимание на функцию toupper() из стандартной сишной библиотеки, чтобы вот такое не городить:

  case 'W':
  case 'w':
  {
    if (snakeLV == 'S' || snakeLV == 's') // защита от дурака

Благодарю за советы

В среднем выглядит неплохо, если оно работает. А так

 COORD *nSnake = (COORD *)realloc(Snake, snakeSize * sizeof(COORD));

учитывая, что действо происходит в терминале кажется достаточно выделить один буфер размером в терминал и больше не реаллоцировать змея. Заодно можно обойтись циклическим буфером - на одной итерации без еды и исчезает один хвост: держим массив с индексом координаты головы. На рендере змеи просто от координаты головы отсчитываем длину змея в обратную сторону.

[a b c _ _ _ _ _ _ _ _ _] len 3 head 2 # змейка на три клетки
[a b c d _ _ _ _ _ _ _ _] len 3 head 3 # змейка двинулась на клетку d
[a b c d e _ _ _ _ _ _ _] len 4 head 4 # змейка съела яблоко в клетке e
...
[a b c d e f g h a _ _ _] len 4 head 8 # голова в точке где когда-то был хвост
... 
[l b c d e f g h a i j k] len 4 head 0 # змейка в координатах lkji

В реальности буффер будет наверное размером в терминал, то бишь что-нибудь в районе 30х140 ~ 4k+ элементов, так что до края голова доберётся не скоро.

if (true) var = true это все же антипаттерн, мешающий читать код.

if (Snake[0].X == W || Snake[0].X == 0)
{
  isGameEnd = TRUE; // укусила боковые границы
}
if (Snake[0].Y == H || Snake[0].Y == 0) 
{
  isGameEnd = TRUE; // укусила нижнюю или верхнюю границы
}

У вас есть возможность сложить это в меньшее количество строк, просто переназначив значение через оператор |= . Ну и копипастить каждый раз тоже снижает читаемость: т.к. у вас в этом месте код не меняется обращение по индексу можно вынести в одну переменную.

const COORD* head = &Snake[0]; // чтобы не копипастить индекс каждый раз
isGameEnd |= head->X == W || head->X == 0; // укусила боковые границы
isGameEnd |= head->Y == H || head->Y == 0; // укусила нижнюю или верхнюю границы
for (int i = 1; i < snakeSize; i++) 
{
  // укусила себя
  isGameEnd |= head->X == Snake[i].X 
            && head->Y == Snake[i].Y;
}

Благодарю! Учту в будущем

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации