Форум программистов, компьютерный форум, киберфорум
Программирование игр
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.86/29: Рейтинг темы: голосов - 29, средняя оценка - 4.86
2 / 2 / 0
Регистрация: 08.06.2018
Сообщений: 66

Прошу критики игры "Змейка"

20.06.2018, 15:06. Показов 6428. Ответов 85
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет.
Недавно написал змейку.
Прошу оценить и покритиковать немного,мб какие-то предложения,поправки.
Вложения
Тип файла: rar Project.rar (12.87 Мб, 47 просмотров)
Тип файла: rar отдельно main.rar (1.3 Кб, 11 просмотров)
Тип файла: rar отдельно екзешник.rar (24.7 Кб, 25 просмотров)
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
20.06.2018, 15:06
Ответы с готовыми решениями:

Змейка, завершение игры
Нужно сделать чтобы змейка ела 5 яблок и игра заканчивалась, но не могу понять как это сделать( Вот сам код #include...

Прошу критики
Всем привет! Прошу старших коллег оценить код ниже. Любая критика приветствуется. Стоит задача спарсить страницы с объявлениями о...

Прошу вашей критики
Начинаю делать собственный проект www.geo-rus.ru. Жду вашей критики по всем фронтам. :) Главный вопрос: стоит ли он развития, или...

85
 Аватар для COKPOWEHEU
4090 / 2688 / 432
Регистрация: 09.09.2017
Сообщений: 11,965
06.07.2018, 18:29
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от 8Observer8 Посмотреть сообщение
COKPOWEHEU, я там выше Linux версию прикрепил, работает?
Работает, хотя как-то неадекватно реагирует на клавиши... странно, не помню чтобы устанавливал mono
Цитата Сообщение от anton3d Посмотреть сообщение
Не совсем удобно работать конечно
Имеете в виду каждый раз набирать километр ключей компилятору?
Или запускать виртуалку с Убунтой?
В первом случае можно написать простенький сборочный скрипт (который перерастет в makefile)
Во втором - найти нужные библиотеки под винду.
Цитата Сообщение от anton3d Посмотреть сообщение
вот еще не понял-почему ее нужно отдельно статически встраивать в программу??
Наверное, можно и динамически, но зачем? Она 600 кБ весит, не так уж много. Зато не будет проблем если захотите продемонстрировать на чужом компе, а там нужных dll'ок не окажется. Впрочем, повторюсь: для SDL так и так придется таскать SDL2.dll
Если поискать сборку ncurses, там есть несколько dll'ок, наверное можно подключить их.
Цитата Сообщение от anton3d Посмотреть сообщение
8Observer8, Не,ну правда-я уже наработался с движками
Справедливости ради, если цель не только разобраться, но и написать собственно игру, использовать движки все-таки лучше. Там уже решено много проблем, которые решать сложно и неинтересно.
Поэтому имеет смысл изобрести велосипед - кустарную поделку, во многом уступающую готовым аналогам. Зато станет понятно, где встречаются узкие или опасные места, смотреть как решали проблемы вы - и как сторонние разработчики.
Помимо прочего, полученные знания могут пригодиться в совершенно другой области.
1
9949 / 2949 / 497
Регистрация: 05.10.2013
Сообщений: 8,028
Записей в блоге: 242
06.07.2018, 21:13
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Работает, хотя как-то неадекватно реагирует на клавиши...
В смысле, если зажать вверх, то можно управлять влево и вправо, а если вниз то нельзя?

Это потому что управление сделано через if/else. Я сделаю просто через if потом, изменений побольше накопится.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    // Update is called once per frame
    void Update()
    {
        // Move in a new Direction?
        if (Input.GetKey(KeyCode.RightArrow))
        {
            dir = Vector3.right;
        }
        else if (Input.GetKey(KeyCode.DownArrow))
        {
            dir = Vector3.back;
        }
        else if (Input.GetKey(KeyCode.LeftArrow))
        {
            dir = -Vector3.right; // '-right' means 'left'
        }
        else if (Input.GetKey(KeyCode.UpArrow))
        {
            dir = Vector3.forward;
        }
    }
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Поэтому имеет смысл изобрести велосипед - кустарную поделку, во многом уступающую готовым аналогам. Зато станет понятно, где встречаются узкие или опасные места, смотреть как решали проблемы вы - и как сторонние разработчики.
Если вы захотите посмотреть, как решили ту или иную проблему разработчики движков Unreal Engine или CryEngine (у которых исходники открыты), но не так просто будет разобраться, начав изучать их исходники, потому что исходники этих движков огромные, ориентироваться в них очень сложно. С нуля да, полезно для саморазвития писать, так как если в движке что-то не реализовано, можно написать реализацию для движка, либо скриптами, либо плагином на C++, в Unity есть возможность писать плагины на C++. Я два месяца назад для самообучения переписывал код из туториала по арканойду с JS и Canvas API 2D breakout game using pure JavaScript на TypeScript. Переписал, залил на github, тут играть можно -> клик. Так вот я обратил внимание на текст в начале тутора:
Starting with pure JavaScript is the best way to get a solid knowledge of web game development. After that, you can pick any framework you like and use it for your projects. Frameworks are just tools built with the JavaScript language; so even if you plan on working with them, it's good to learn about the language itself first to know what exactly is going on under the hood. Frameworks speed up development time and help take care of boring parts of the game, but if something is not working as expected, you can always try to debug that or just write your own solutions in pure JavaScript.
Тут таже самая мысль, что нужно уметь написать, чего нет в выбранном фреймворке или движке, что написание с нуля даёт возможность понимать, как работает выбранный фреймворк под капотом (on under the hood)

Добавлено через 1 час 52 минуты
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Failed to initialize graphics.
Make sure you have DirectX 11 installed, have up to date
drivers for your graphics card and have not disabled
3D acceleration in display settings.
InitializeEngineGraphics failed
Есть предположение, что на эмуляторе не устновлен DX11. В требованиях пишут, как минимум DX10 должен быть. В начале игры можно выбрать низкое качество графики. Если будет возможность попробуйте поставить на самое низкое. Если DX10 не установлен, то работать не будет. Раньше на Unity 5 было требование DX9, а с выходом нового Unity 2018 требования повысились.
0
 Аватар для COKPOWEHEU
4090 / 2688 / 432
Регистрация: 09.09.2017
Сообщений: 11,965
07.07.2018, 09:42
Цитата Сообщение от 8Observer8 Посмотреть сообщение
В смысле, если зажать вверх, то можно управлять влево и вправо, а если вниз то нельзя?
просто с задержкой
Цитата Сообщение от 8Observer8 Посмотреть сообщение
Есть предположение, что на эмуляторе не устновлен DX11
Возможно. Проверил на более настроенном wine - заработало, хотя все равно ошибками плюется в лог.
P.S. не нашел на какую кнопку оно закрывается, поэтому убивал по alt+F4.
P.P.S. превращаться в тестера вашей игрушки особого желания нет.
1
9949 / 2949 / 497
Регистрация: 05.10.2013
Сообщений: 8,028
Записей в блоге: 242
08.07.2018, 10:23
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
не нашел на какую кнопку оно закрывается, поэтому убивал по alt+F4
Спасибо за замечание. Добавил в ТЗ, чтобы закрывалось по ESC.

Добавлено через 5 часов 48 минут
Цитата Сообщение от anton3d Посмотреть сообщение
у годот был открытый исходный код и никаких ограничений,но пока еще маленькое сообщество
Здесь нужно взвешивать, что перевесит. На одной чаще открытый исходный код, но я считаю, что важнее, какое сообщество, то есть насколько популярен и следовательно, сколько заказов. Не знаю, что в России популярнее, для меня ориентиром являются сайты Freelancer.com и Upwork.com. Я сейчас сравнил, по Unity на Upwork публикуют в среднем примерно 10 заказов в сутки, а по Godot - 1 заказ в месяц. Как правило, заказчика или контору не интересуют исходники. Я не беру в расчёт супер крутые конторы, которые может быть переписывают исходники Unreal Engine под себя, но с другой стороны такие конторы могу позволить себе купить исходники Unity. Я пока не видел таких заказов или контор, чтобы требовалось наличие и правка исходников. Я работал в конторе у нас в городе на Unity, там даже речи не шло о покупке и изменении исходников Unity. Просто люди пилят игрушки под мобильные платформы и ПК для продажи на Google Play, App Store, Steam и т.д. Удалённо немного поработал в зарубежной конторе, там тоже об исходниках Unity речи не шло. Я пока даже не забумываюсь об этом. Потом может быть через много лет, когда мои скилы до этого дорастут, может когда будет под 40. По моему, по вакансиям, заказам и популярности, на данный момент, Godot уступает Unity в десятки раз. Я не сторонник прыгать с технологии на технологию, так как и так мало времени на самообразование. Если только эти технологии не дополняют друг друга - тогда другое дело. Лучше сосредоточиться в одном направлении с дополняющими технологиями и пахать, иначе можно закапаться в сложностях, потерять мотивацию в движении к графическим приложениям и/или к геймдеву и в итоге не найти источников заработка. Если в онлайн в книжном магазине Packtpub вы поищите сколько книг вышло по Godot, то вы увидите, что их всего одна штука, а по Unity вышло уже около сотни книг и огромное число платных видео курсов на английском, которые несложно найти в инете.

Добавлено через 15 часов 5 минут
Цитата Сообщение от anton3d Посмотреть сообщение
Я не понимаю как это все работает,я лучше фундаментально пойму как все работает.
Тогда вам не уйти от низкоуровневого графического API. Придётся выбирать: OpenGL, DirectX, Vulkan и т.д. Если OpenGL, то нужно будет решить, либо, например, год или несколько лет потратите, чтобы изучить старый нешейдерный OpenGL 1.5, либо сразу перейдёте с шейдерному OpenGL 3+. Тут тоже мнения разделяются. Я несколько месяцев поизучал старый по переводу на русский книги "Суперкнига", 3-е издание. Прочитал три или четыре главы. Потом перешёл на изучение шейдерного OpenGL, начал с этой книги. В ней простым языком объясняется работа шейдеров. Переводил примеры с WebGL на C#/OpenGL 3+. Правда, перевёл только половину: ссылка на github

Если хочется изучать основы 2D и 3D графики без привязки к графическому API, то есть такие книги. Я, правда, только некоторые читаю небольшими кусками.

В общем об основах 2D/3D графики:
  • 2011 - 02 - 3D Graphics for Game Programming - JungHyun Han
  • 2014 - Introduction to Computer Graphics A Practical Learning Approach - Fabio Ganovelli, Massimiliano Corsini, Sumanta Pattanaik, Marco Di Benedetto
  • 2013 - 06 - Computer Graphics Principles and Practice - 3rd Edition - John F. Hughes

Книги по математике (об основах графики) и физике:
  • 2011 - 06 - Mathematics for 3D Game Programming and Computer Graphics - 3-rd edition - Eric Lengyel -> description
  • 2011 - 11 - 3D Math Primer for Graphics and Game Development - Dunn F., Parberry I -> description
  • 2013 - 04 - Physics for Game Developers - 2nd Edition - David M. Bourg, Bryan Bywalec -> description -> source code

В общем о создании движков:
0
2 / 2 / 0
Регистрация: 08.06.2018
Сообщений: 66
08.07.2018, 15:17  [ТС]
8Observer8,спасибо за книги,будет очень полезно))
0
 Аватар для COKPOWEHEU
4090 / 2688 / 432
Регистрация: 09.09.2017
Сообщений: 11,965
08.07.2018, 16:15
Цитата Сообщение от 8Observer8 Посмотреть сообщение
Если OpenGL, то нужно будет решить, либо, например, год или несколько лет потратите, чтобы изучить старый нешейдерный OpenGL 1.5
Преимущество нешейдерного OpenGL 1 в том, что это самая простая и интуитивная графическая библиотека. Выучить glBegin, glEnd, glVertex и glColor не так сложно.
0
9949 / 2949 / 497
Регистрация: 05.10.2013
Сообщений: 8,028
Записей в блоге: 242
08.07.2018, 16:53
Такой тутор есть по нешейдерному OpenGL: C++ 2D Pong Game. В нём показано, как просто текст выводить с помощью средств GLUT. Если хотите, можете его выполнить и потом змейку переписать, может там немного нужно будет переписывать, а может всё, но это опять же практика. Я выполнял этот тутор, он короткий и английский там простой. Мерцать экран не будет, скорость змейки можно сделать нормальной, а не так как у вас: вверх она с одной скорость движется, а вниз с другой.
0
2 / 2 / 0
Регистрация: 08.06.2018
Сообщений: 66
08.07.2018, 18:58  [ТС]
8Observer8,
Цитата Сообщение от 8Observer8 Посмотреть сообщение
вверх она с одной скорость движется, а вниз с другой.
этот косяк связан с тем,что форма всех символов прямоугольная
окей я гляну,посмотрим что можно будет сделать

Добавлено через 5 минут
COKPOWEHEU, я наконец-то прокомментировал тот код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <signal.h>//библиотеки какие-то
#include <stdlib.h>
#include <curses.h>
 
int main(int argc, char ** argv){//кстати обычно не пишу никаких входных данных,но так как мы запускам программу через коммандную строку,передаем ей параметры запуска,вроде -I ./mingw_include/ncursesw(это же для этого,правда??)
  MEVENT event;//не понятноо,обьяснения не нашел
  
  //инициализация
  initscr();//инициализируем curses,создаем окно по умолчанию,чистим экран и устанавливаем курсор в 0.0
  noecho();//выключаем ввод символов с клавиатуры
  curs_set(0);//делаем курсор невидимым
  start_color();//точного обьяснения не нашел,но знаю точно что эту функцию нужно вызывать перед созданием палитры цветов
  timeout(100);//установка задержки (аналог sleep????)
  set_escdelay(0);//не нашел
  keypad(stdscr, TRUE);//включаем перевод клавиатуры(не понимаю что это)
  mousemask(ALL_MOUSE_EVENTS, NULL);//подключения событий мыши??(тоже не понятно)
  cbreak();//устанавливает режим ввода для текущего терминала в режим cbreak (что за режим-хрен его знает)
  leaveok(stdscr,false);//закрепляем позицию курсора в зависимости от операций обновления(тоже не понимаю)
  nonl();//выключаем переход на новую строку
  
  printw("Press any key");//выводим на экран 
 
  int key;//создаем переменную 
  while(1){//бесконечный цикл в с-стиле в с++ обычно юзается true 
    key = getch(//записываем в переменную key считанный символ с клавиатуры
    if(key == 27)break;//если код считанного символаравняется 27 то прерываем цикл
      else if(key == KEY_MOUSE){//если клоцнули мышкой
        getmouse(&event);//что то делаем,видимо для этого мы подключали события мыши(в общем тоже не понимаю)
      }else if(key != -1){//если код не равняется-1
        move(1,1);//передвигаем курсор в координаты 1.1
        printw(" %i  ", key);//и выводим что-то перед переменной key
        mvaddch(2,2,key);//переводчик говорит что-то  про однобайтовый символ и перенос курсора
      }
  }
  
  endwin();//останавливаем действия curses(получется обратная функция к initscr)
}
много чего не понятно в самом curses
а еще почему-то 90% всей информации находится на порталах посвященных linux и другим unix-подобным системам
0
 Аватар для COKPOWEHEU
4090 / 2688 / 432
Регистрация: 09.09.2017
Сообщений: 11,965
09.07.2018, 10:46
Цитата Сообщение от anton3d Посмотреть сообщение
так как мы запускам программу через коммандную строку,передаем ей параметры запуска,вроде -I ./mingw_include/ncursesw(это же для этого,правда??)
Нет, эти параметры нужно передавать компилятору gcc.
А входные аргументы я написал по другим причинам.
1. Так правильно. В смысле, объявление void main() это скорее синтаксический сахар (причем с void - еще и незаконный, то есть выдает ошибку). На самом деле, можно писать и без параметров.
2. Особенность SDL, к которому мы, надеюсь, придем. Вот для него объявление main с правильными параметрами и правильным возвращаемым значением является обязательным. Иначе просто не соберется.
Цитата Сообщение от anton3d Посмотреть сообщение
MEVENT event;//не понятноо,обьяснения не нашел
Одна из вещей, которые я собирался объяснить. Обработчик внешних событий - перемещение мыши, изменение размеров окна, все что угодно.
Цитата Сообщение от anton3d Посмотреть сообщение
noecho();//выключаем ввод символов с клавиатуры
Надеюсь, это просто неудачная формулировка.
По умолчанию при нажатии клавиши, ее символ отображается на экране - так называемое эхо. Так вот, командой noecho мы это отображение отключаем. Сам ввод, естественно, сохраняется.
Цитата Сообщение от anton3d Посмотреть сообщение
timeout(100);//установка задержки (аналог sleep????)
Нет.
При обычном вводе (scanf, gets, getch и т.п.) программа будет ждать ввода хотя бы одного символа. А для игры это неприемлемо, поэтому timeout задает максимальное время ожидания, после которого функции ввода будут возвращать "буфер пуст". Для нас это вполне штатная ситуация.
Цитата Сообщение от anton3d Посмотреть сообщение
set_escdelay(0);//не нашел
Тоже, честно говоря, плохо помню что это такое. Вроде бы отключает задержку при нажатии ESC.
Цитата Сообщение от anton3d Посмотреть сообщение
keypad(stdscr, TRUE);//включаем перевод клавиатуры(не понимаю что это)
разрешение использовать спецклавиши вроде стрелок, home и т.п.
Цитата Сообщение от anton3d Посмотреть сообщение
mousemask(ALL_MOUSE_EVENTS, NULL);//подключения событий мыши??(тоже не понятно)
А что непонятно? Да, подключение мыши. Здесь она не используется пока, но ведь и хуже от нее не будет
Цитата Сообщение от anton3d Посмотреть сообщение
cbreak();//устанавливает режим ввода для текущего терминала в режим cbreak (что за режим-хрен его знает)
По умолчанию ввод с терминала передается только после нажатия Enter или заполнении буфера. Данная функция буферизацию отключает, то есть можно отлавливать клавиши сразу при нажатии.
Цитата Сообщение от anton3d Посмотреть сообщение
leaveok(stdscr,false);//закрепляем позицию курсора в зависимости от операций обновления(тоже не понимаю)
Опять-таки точно не помню, но вроде бы разрешает программное управление курсором
Цитата Сообщение от anton3d Посмотреть сообщение
nonl();//выключаем переход на новую строку
По умолчанию нажатие Enter интерпретируется как перевод строки или передачу буфера символов. Этой функцией мы это отключаем. Теперь Enter - такая же клавиша, как остальные
Цитата Сообщение от anton3d Посмотреть сообщение
int key;//создаем переменную
Ну это вообще не комментарий. В комментарии пишется "зачем" а не "как"
Цитата Сообщение от anton3d Посмотреть сообщение
if(key == 27)break;//если код считанного символаравняется 27 то прерываем цикл
Не слишком содержательно. 27 - код символа ESC. Вообще-то неплохо было бы добавить тут константу или макроконстанту, ну да ладно
Цитата Сообщение от anton3d Посмотреть сообщение
}else if(key != -1){//если код не равняется-1
А если равняется -1 то что это значит для программы? Почему игнорируем именно этот код?
Цитата Сообщение от anton3d Посмотреть сообщение
printw(" %i ", key);//и выводим что-то перед переменной key
Эм... что?
Цитата Сообщение от anton3d Посмотреть сообщение
mvaddch(2,2,key);//переводчик говорит что-то про однобайтовый символ и перенос курсора
move - add - char. Переместить курсор и вывести ASCII символ с кодом key.
Цитата Сообщение от anton3d Посмотреть сообщение
а еще почему-то 90% всей информации находится на порталах посвященных linux и другим unix-подобным системам
Возможно, дело в том, что там консоль гораздо популярнее. Все базовые утилиты именно консольные, все управление системой может осуществляться (и частенько так и делают, поскольку оконные приложения не обеспечивают 100% контроля) через консоль. А в windows или там macos старательно эту консоль прячут, вот и не получили популярность подобные библиотеки.
.
У вас проблемы с форматным выводом? Комбинация printw(" %i ", key); достаточно стандартная, ваш комментарий меня удивил. Возможно, вы просто не сталкивались с Си-шным вводом-выводом, предпочитая плюсовый? Не уверен что ncurses умеет работать с std::cin, std::cout. Конечно, для простейшей змейки это не критично.
Но все равно разобраться с обычными, не связанными с ncurses, функциями ввода-вывода в Си - printf, scanf - лишним не будет.
.
Я думаю, что по этому шаблону уже можете начать переносить свою змейку на ncurses. Лично для меня интереснее писать свои программы, чем комментировать чужие, поэтому не буду навязываться пока со своим кодом - пишите как считаете нужным. Впрочем, если хотите помощи с какой-то конкретной областью - обращайтесь.
Напоминаю, что стоит добавить константы для клавиш, для символов самой змейки и прочего.
Только вот еще что. Как я говорил в начале, стоит "завернуть" близкие по смыслу переменные в одну структуру или класс. Я бы предложил начать с самой змейки:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
struct Point{
  int x;
  int y;
};
 
class Snake{
public: //со временем оформим в "нормальный" класс с приватными полями и прочим, но пока не будем усложнять
  Point pos[100]; //выделять позицию "головы" не стоит, пусть остается как pos[0]
  //остальные поля добавьте по вкусу. Поле pos я написал только для примера как "завернуть" позиции всех сегментов в один массив
  char dir;
  void move();
  //точно так же, не буду слишком навязывать свое понимание
};
 
void Snake::move(){
  //код перемещения змейки. Здесь - только пример реализации метода. (возвращаемое значение) (Название класса) (двоеточие-двоеточие) (имя метода с параметрами)
}
...
Snake snake; //создаем переменную свежесозданного класса
int main(int argc, char **argv){
...
  if(snake.pos[0].x == eat.x && snake.pos[0].y == eat.y) //пример доступа к полям класса - через точку
  snake.move(); //пример доступа к методам - тоже через точку
Не настаиваю именно на своем выделении классов, полей в них и прочем. Чем больше вы будете экспериментировать тем лучше разберетесь.
0
9949 / 2949 / 497
Регистрация: 05.10.2013
Сообщений: 8,028
Записей в блоге: 242
09.07.2018, 15:57
У этой книги есть любительский перевод, вроде бы, хорошего качества:Но я всегда все книги читаю только на английском.

Добавлено через 4 часа 14 минут
Цитата Сообщение от anton3d Посмотреть сообщение
там синтаксис такой же как у пайтона
У вас было знакомство с Python? Если да, то этот тутор по OpenGL + GLUT Python Snake Game. Его несложно будет перевести на C++, если пройти этот тутор тоже: C++ 2D Pong Game
0
 Аватар для COKPOWEHEU
4090 / 2688 / 432
Регистрация: 09.09.2017
Сообщений: 11,965
10.07.2018, 13:40
Решился все-таки написать простенькую змейку на OpenGL 1 + SDL2. Настройка клавиш в файле settings.cfg. Столкновения не приводят к поражению.
Вложения
Тип файла: rar res.rar (476.7 Кб, 5 просмотров)
0
2 / 2 / 0
Регистрация: 08.06.2018
Сообщений: 66
10.07.2018, 18:04  [ТС]
COKPOWEHEU,
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
printf, scanf - лишним не будет.
по правде,один раз в жизни использовал printf, scanf в задаче на олимпиаде,где суть была в том,что если использовать cin/cout то не поместишься в лимит в 16 мб оперативки.А так,обходил стороной,поэтому и не понял.

Я там доделал функцию рестарта еще.Теперь хочу весь код раскидать по классам,а переменные запихнуть в структуры,и будет конфетка)
0
9949 / 2949 / 497
Регистрация: 05.10.2013
Сообщений: 8,028
Записей в блоге: 242
10.07.2018, 19:37
Цитата Сообщение от anton3d Посмотреть сообщение
по правде,один раз в жизни использовал printf, scanf в задаче на олимпиаде
В учавствовали в школьных олимпиадах по программированию? Или в олимпиадах в ВУЗ'е? Я время от времени решаю простенькие задачки на ресурсе codewars.com для себя. Мне нравится этот ресурс тем, что там прямо в браузере можно писать и запускать свои тесты перед отправкой на проверку серверу. Ещё мне нравится, что там система рейтинга для подбора задач, как в игре Го, через кю и даны. Я считаю это полезно периодически решать задачки на изучаемых языках, тренируются определённые навыки. Это весело и интересно.
0
2 / 2 / 0
Регистрация: 08.06.2018
Сообщений: 66
11.07.2018, 02:15  [ТС]
8Observer8, на acmp и codeforces
в школьных участвовал,сейчас-только в интернете

Добавлено через 5 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#include <iostream>
#include <Windows.h>
#include <conio.h>
#include <ctime>
#include <fstream>
#include <iomanip>
 
using namespace std;
 
bool game_status;
const int fldwidth = 77, fldheight = 22, stime = 60;
char field[fldheight][fldwidth], shead, stail, msym, sdir, rkey, dir, ldir;
int lastposx[100], lastposy[100], hscore, coutr, length, score, shposx, shposy, mposx, mposy ,ans;//намутить структур
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
unsigned int start_time = clock();//время
unsigned int search_time;
 
void set_food() {//создает еду на пустом рандомном месте
    do
    {
        mposx = rand() % (fldwidth - 4) + 2;//возле стенок очень просто подохнуть,поэтому костылем отнимаем 4ед(2 от правой стены/2 от левой(т.е.одна на символ стены,а вторая на пустой после стены-таким образом еда спавнится максимум за один символ от стены и меня никто не будет ругать за кривую механику поворота(заметка-попытатся починить потом)))
        mposy = rand() % (fldheight - 4) + 2;//то же самое проделываем для нижней и верхней стенок
    } while (field[mposy][mposx] != ' ');//так мы избегаем спавна еды внутри змеи
    field[mposy][mposx] = msym;
}
 
void move() {//функция постоянного движения
    field[lastposy[coutr - 1]][lastposx[coutr - 1]] = ' ';//затираем прошлые координаты
    field[0][0] = 201;//изза кривизны кода пропадает один уголок-этот костыль все чинит
    lastposx[coutr - 1] = shposx;//двигаем по иксу
    lastposy[coutr - 1] = shposy;//двигаем по игреку
                                 /*field[shposy][shposx] = ' ';*///уже не помню зачем я это делал,пока что убрал и вроде ничего не изменилось,пусть пока будет,а то вдруг баги какие-то появятся,если что-потом уберу
    switch (dir)//проверяем что ввел пользователь 
    {
    case 'L'://влево
        shposx -= 1;
        break;
    case 'R'://вправо
        shposx += 1;
        break;
    case 'D'://вниз
        shposy += 1;
        break;
    case 'U'://вверх
        shposy -= 1;
        break;
    }
    if (field[shposy][shposx] == stail)
        game_status = false;//если в координатах головы оказывается символ хвоста-заканчиваем игру
    if (shposx < 1 or shposx>75 or shposy<1 or shposy>20)
        game_status = false;//если координаты головы входят в стену-заканчиваем игру(можно было использовать способ выше,но делал это все в разное время,а сейчас лопатить код впадлу-учту на будущее
    if (shposx == mposx && shposy == mposy) {//если координаты головы и еды пересеклись
        ++score;//увеличиваем счет
        ++length;//увеличиваем длину
        set_food();//спавним новую еду,старая сама заменяется символом головы
    }
}
 
void init() {//функция инициализации
    ifstream in("highscore.txt");//подключаем файл с рекордом,если таковой имеется
    in >> hscore;//считываем рекорд
    in.close();//закрываем файл
    system("color 0f");//играем с цветами
    SetConsoleTextAttribute(hConsole, (WORD)((0 << 4) | 2));//играем с цветами
    srand(time(NULL));//считаем время
    game_status = true;//запускаем игру
    start_time = clock();
    search_time = 0;
 
    for (int i = 1; i < 21; ++i) {
        for (int j = 1; j < 76; ++j) {
            field[i][j] = ' ';
        }
    }//зарисовываем все пустотой 
 
    for (int i = 1; i < 21; ++i) {//стены вертикальные
        field[i][0] = 186;
    }
    for (int i = 1; i < 21; ++i) {//стены вертикальные
        field[i][76] = 186;
    }
    for (int i = 1; i < 76; ++i) {//стены горизонтальные
        field[0][i] = 205;
    }
    for (int i = 1; i < 76; ++i) {//стены горизонтальные
        field[21][i] = 205;
    }
    field[0][0] = 201;//углы
    field[0][76] = 187;
    field[21][76] = 188;
    field[21][0] = 200;
    score = 0;//счет
    shposx = 11;//первая позиция головы по иксу
    shposy = 11;//первая позиция головы по игреку
    coutr = 1;//счетчик
    length = 3;//стартовая длина
    dir = 'R';//стартовое направление
    ldir = 'R';//стартовое прошлое направление 
    msym = '*';//символ еды
    shead = '@';//символ головы
    stail = 'o';//символ хвоста
    set_food();
}
 
void update() {//функция обновления положения змеи
    move();
    if (_kbhit()) {//если была нажата клавиша
        rkey = _getch();//считываем ее
        sdir = static_cast<int>(rkey);//переводим
        ldir = dir;//перед тем как присвоить новое направление-сохраняем старое
        switch (sdir)//новое направление 
        {
        case 75://влево
            if (ldir != 'R')
                dir = 'L';
            break;
        case 77://вправо
            if (ldir != 'L')
                dir = 'R';
            break;
        case 80://вниз
            if (ldir != 'U')
                dir = 'D';
            break;
        case 72://вверх
            if (ldir != 'D')
                dir = 'U';
            break;
        }
    };
    field[shposy][shposx] = shead;//новое положение головы
    field[lastposy[coutr - 1]][lastposx[coutr - 1]] = 'o';//тут дальше сложная магия которая отрисовывает нам хвост и когда счетчик доходит до длины рисует новый хвост на 1ед длинне старого(только если длина увеличилась)
    if (length == coutr) {
        for (int i = 1; i <= length; ++i) {
            field[lastposy[coutr - i]][lastposx[coutr - i]] = 'o';
        }
    }
    if (coutr == length)
        coutr = 0;
    ++coutr;
    unsigned int end_time = clock();//считаем время-вообще нужно бы засунуть это в апдейт
    search_time = end_time - start_time;
}
 
void render() {//функция отображения поля с текущими параметрами
    for (int i = 0; i < 22; ++i) {
        for (int j = 0; j < 77; ++j) {
            if ((i == 0) or (i == 21) or (j == 0) or (j == 76)) {
                SetConsoleTextAttribute(hConsole, (WORD)((0 << 4) | 1));//играем с цветами для стен
                cout << field[i][j];
                SetConsoleTextAttribute(hConsole, (WORD)((0 << 4) | 2));//играем с цветами для змейки
            }
            else {
                if (field[i][j] == '*') {
                    SetConsoleTextAttribute(hConsole, (WORD)((0 << 4) | 12));//играем с цветами для еды
                    cout << field[i][j];
                    SetConsoleTextAttribute(hConsole, (WORD)((0 << 4) | 2));//играем с цветами для змейки
                }
                else {
                    cout << field[i][j];
                }
            }
        }
        cout << endl;
    }
    
    SetConsoleTextAttribute(hConsole, (WORD)((0 << 4) | 7));//играем с цветами для счета
    cout << "SCORE:" << ' ' << score << ' ' << "Time:" << ' ' << fixed << setprecision(2) << search_time / 1000.0 << 's' << ' ' << "HIGHSCORE:" << ' ' << hscore;
    SetConsoleTextAttribute(hConsole, (WORD)((0 << 4) | 2));//возвращаем цвет змеи
    Sleep(stime);//спим для плавности картинки
    system("cls");//чистим экран
}
 
void end_game() {//в конце игры проверяем побили ли мы рекорд
        if (score > hscore) {
            hscore = score;
            cout << "Your new highscore:" << hscore << endl;
            ofstream out("highscore.txt");
            out << hscore;
            out.close();
        }
}
 
void menu() {//менюшка
SetConsoleTextAttribute(hConsole, (WORD)((0 << 4) | 2));
cout << "                       ______                _            "<< endl;
cout << "                      / _____)              | |           "<< endl;
cout << "                     ( (____   ____   _____ | |  _  _____ "<< endl;
cout << "                      \\____ \\ |  _ \\ (____ || |_/ )| ___ |"<< endl;
cout << "                      _____) )| | | |/ ___ ||  _ ( | ____|"<< endl;
cout << "                     (______/ |_| |_|\\_____||_| \\_)|_____)"<< endl;
cout << "                                                          "<< endl;
cout << "Press ENTER to start new game:" << endl;
    while (true) {
        ans = _getch();
        if (ans == 13) {
            break;
        }
    }
}
 
int main() {//мейн
    menu();
    restart:
    init();//инициализируем
    while (game_status) {//пока идет игра
        update();//обновляем
        render();//рисуем
 
    }
    end_game();
    cout << "Press ENTER to restart,or ESC to exit:";
    while (true) {
        ans = _getch();
            if (ans == 13){
                goto restart;
            }
            if (ans == 27) {
                return 0;
            }
    }
}
Вот-публикую последнюю версию-кое чего допилил)
Внешне больше не изменится,хотя как я понимаю-после переноса на curses перестанет мигать,так ведь?
Осталось довести код до ума
П.С.:Не ругайте за гото,я абсолютно уверен-что тут в нем не запутаюсь,злоупотреблять не собираюсь,и вижу его тут-как самое наглядное и простое решение.
0
2 / 2 / 0
Регистрация: 08.06.2018
Сообщений: 66
11.07.2018, 02:18  [ТС]
вот еще в exe
Вложения
Тип файла: rar Snake.rar (12.5 Кб, 0 просмотров)
0
 Аватар для COKPOWEHEU
4090 / 2688 / 432
Регистрация: 09.09.2017
Сообщений: 11,965
11.07.2018, 07:58
Цитата Сообщение от anton3d Посмотреть сообщение
Теперь хочу весь код раскидать по классам,а переменные запихнуть в структуры,и будет конфетка)
Что-то в "последнем коде" классов и структур не прибавилось.
Цитата Сообщение от anton3d Посмотреть сообщение
Не ругайте за гото
Здесь goto все-таки не нужен. Для возвращения назад по коду используются операторы циклов:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
while(game_status){
  init();//инициализируем
 
  while (game_status) {//пока идет игра
    update();//обновляем
    render();//рисуем
  }
 
  end_game();
  cout << "Press ENTER to restart,or ESC to exit:";
  do{
    ans = _getch();
    if (ans == KEY_ENTER) game_status=1;
  }while(ans != KEY_ESC && ans != KEY_ENTER);
}
Цитата Сообщение от anton3d Посмотреть сообщение
как я понимаю-после переноса на curses перестанет мигать,так ведь?
Нет. Вот часть атрибутов вывода текста:
Code
1
2
3
4
5
6
7
A_NORMAL        | нормальный, переустановка всего остального
A_STANDOUT      | наиболее яркий режим
A_UNDERLINE     | подчеркивание
A_REVERSE       | обратное изображение
A_BLINK         | мигание
A_DIM           | тусклый или полуяркий режим
A_BOLD          | четкий или очень яркий режим
0
9949 / 2949 / 497
Регистрация: 05.10.2013
Сообщений: 8,028
Записей в блоге: 242
11.07.2018, 10:01
Цитата Сообщение от anton3d Посмотреть сообщение
на acmp и codeforces
codeforces не встречал, посмотрю. На acmp я штук 50 решил в течение последних 5 лет. Немного пробовал acm.timus.ru. Я когда начал решать на acmp, мне захотелось на C++ писать свои тесты. То есть как на сервере у них сделано - сервер прогоняет решение через ряд тестов, выдавая на каком тесте произошла ошибка, когда их ожидаемый результат не совпал с результатом, который вернула написанная функция. Мне хотелось научиться раскрывать, какие тесты у них на сервере, чтобы по мере решения задачи дописывать свои тесты. В конечном итоге научиться, так анализировать задачу, чтобы учесть максимально возможные тесты, а на сервер уже отправлять решение с первого раза (или с близкого к первому разу). Сначала я нашёл библиотеку, которая облегчает эту задачу - CppUnit, потом повстречал самую популярную на данный момент библиотеку GTest (GoogleTest), добавочно к ней идёт GMock (GoogleMock). GMock нужен, чтобы инжектировать зависимости (для быстрого запуска тестов) - файловая система, сеть, веб, сторонние API (функции, классы), базы данных. Далее, я нашёл методологию TDD (разработка через тестирование), которая заключается в том, что мы пишем тест для функции, пишем код функции, чтобы этот тест выполнился, опять пишем тест. Далее, код можно рефакторить, не боясь, что-то сломать, так как какой-нибудь тест, покажет, что сломалось. Если интересно, то здесь примеры, как подключить GTest и GMock к Visual Studio, а тут серия видео туториалов: Google C++ Testing, GTest, GMock Framework Part- 1 : Introduction
youtube
0
2 / 2 / 0
Регистрация: 08.06.2018
Сообщений: 66
11.07.2018, 13:32  [ТС]
COKPOWEHEU,
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Что-то в "последнем коде" классов и структур не прибавилось.
скоро все будет)
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Для возвращения назад по коду используются операторы циклов:
хмм,окей я реализую этот вариант
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Нет.
А в чем тогда его преимущество,кроме того,что там вывод по-человечески сделан?
0
 Аватар для COKPOWEHEU
4090 / 2688 / 432
Регистрация: 09.09.2017
Сообщений: 11,965
11.07.2018, 14:03
Цитата Сообщение от anton3d Посмотреть сообщение
скоро все будет)
Ждем
Цитата Сообщение от anton3d Посмотреть сообщение
хмм,окей я реализую этот вариант
Мест, где goto оправдан, не так уж много. В основном это выход из вложенных циклов или обработка ошибок.
Но вот для перехода назад он не оправдан никогда - для этого существуют циклы.
В моей практике был единственный случай использования goto, при преобразовании класса (где при любой ошибке стоял return с разными кодами возврата) в линейную программу, которая должна быть максимально простой. Так что либо выносить все в функцию, либо городить вложенные if'ы, либо таки goto.
Цитата Сообщение от anton3d Посмотреть сообщение
А в чем тогда его преимущество,кроме того,что там вывод по-человечески сделан?
Именно в том что вывод по-человечески сделан. Ну и переносимость.
0
2 / 2 / 0
Регистрация: 08.06.2018
Сообщений: 66
14.07.2018, 19:28  [ТС]
COKPOWEHEU, я немного поправил код,все ли здесь хорошо?Решил отложить классы пока код не длинный,но про структуры не забыл.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
#include <iostream>
#include <Windows.h>
#include <conio.h>
#include <ctime>
#include <fstream>
#include <iomanip>
 
#define KEY_UP 72
#define KEY_RIGHT 77
#define KEY_LEFT 75
#define KEY_DOWN 80
#define KEY_ENTER 13
#define KEY_ESC 27
 
using namespace std;
 
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
unsigned int start_time, search_time;
 
const int fldwidth = 77, fldheight = 22, stime = 60;//не получилось обьявить внутри структуры
 
struct Snake { //объявляем тип данных - структура змейки
    int shposx, shposy, length;
    int dir, ldir, sdir;
    int lastposx[100], lastposy[100];
    char shead, stail;
};
struct Meal {
    int  mposx, mposy;
    char msym;
};
struct Field {
    char field[fldheight][fldwidth];
    char hwall, vwall, lucor, ldcor, rucor, rdcor, fs;
};
struct GameInfo {
    bool game_status;
    int hscore, score;
};
struct HelpVars {
    char rkey;
    int coutr, ans;
};
 
struct Snake s;
struct Meal m;
struct Field f;
struct GameInfo gi;
struct HelpVars hv;
 
void set_food() {//создает еду на пустом рандомном месте
    do
    {
        m.mposx = rand() % (fldwidth - 4) + 2;//возле стенок очень просто подохнуть,поэтому костылем отнимаем 4ед(2 от правой стены/2 от левой(т.е.одна на символ стены,а вторая на пустой после стены-таким образом еда спавнится максимум за один символ от стены и меня никто не будет ругать за кривую механику поворота(заметка-попытатся починить потом)))
        m.mposy = rand() % (fldheight - 4) + 2;//то же самое проделываем для нижней и верхней стенок
    } while (f.field[m.mposy][m.mposx] != ' ');//так мы избегаем спавна еды внутри змеи
    f.field[m.mposy][m.mposx] = m.msym;
}
 
void move() {//функция постоянного движения
    f.field[s.lastposy[hv.coutr - 1]][s.lastposx[hv.coutr - 1]] = ' ';//затираем прошлые координаты
    f.field[0][0] = f.lucor;//изза кривизны кода пропадает один уголок-этот костыль все чинит
    s.lastposx[hv.coutr - 1] = s.shposx;//двигаем по иксу
    s.lastposy[hv.coutr - 1] = s.shposy;//двигаем по игреку
 
    switch (s.dir)//проверяем что ввел пользователь 
    {
    case 'L'://влево
        s.shposx -= 1;
        break;
    case 'R'://вправо
        s.shposx += 1;
        break;
    case 'D'://вниз
        s.shposy += 1;
        break;
    case 'U'://вверх
        s.shposy -= 1;
        break;
    }
    if (f.field[s.shposy][s.shposx] == s.stail)
        gi.game_status = false;//если в координатах головы оказывается символ хвоста-заканчиваем игру
 
    if (f.field[s.shposy][s.shposx] == f.hwall or f.field[s.shposy][s.shposx] == f.vwall)
        gi.game_status = false;//если в координатах головы оказывается символ стены-заканчиваем игру
 
    if (s.shposx == m.mposx && s.shposy == m.mposy) {//если координаты головы и еды пересеклись
        ++gi.score;//увеличиваем счет
        ++s.length;//увеличиваем длину
        set_food();//спавним новую еду,старая сама заменяется символом головы
    }
}
 
void init() {//функция инициализации
    ifstream in("highscore.txt");//подключаем файл с рекордом,если таковой имеется
    in >> gi.hscore;//считываем рекорд
    in.close();//закрываем файл
    SetConsoleTextAttribute(hConsole, (WORD)((0 << 4) | 2));//играем с цветами
    srand(time(NULL));//считаем время
    start_time = clock();
    search_time = 0;
    gi.score = 0;//счет
    s.shposx = 11;//первая позиция головы по иксу
    s.shposy = 11;//первая позиция головы по игреку
    hv.coutr = 1;//счетчик
    s.length = 3;//стартовая длина
    s.dir = 'R';//стартовое направление
    s.ldir = 'R';//стартовое прошлое направление 
    m.msym = '*';//символ еды
    s.shead = '@';//символ головы
    s.stail = 'o';//символ хвоста
    f.vwall = 186;//символ вертикальной стены
    f.hwall = 205;//символ горизонтальной стены
    f.lucor = 201;//углы
    f.rucor = 187;
    f.rdcor = 188;
    f.ldcor = 200;
    f.fs = ' ';
    for (int i = 1; i < 21; ++i) {
        for (int j = 1; j < 76; ++j) {
            f.field[i][j] = f.fs;
        }
    }//зарисовываем все пустотой 
 
    for (int i = 1; i < 21; ++i) {//стены вертикальные
        f.field[i][0] = f.vwall;
    }
    for (int i = 1; i < 21; ++i) {//стены вертикальные
        f.field[i][76] = f.vwall;
    }
    for (int i = 1; i < 76; ++i) {//стены горизонтальные
        f.field[0][i] = f.hwall;
    }
    for (int i = 1; i < 76; ++i) {//стены горизонтальные
        f.field[21][i] = f.hwall;
    }
    f.field[0][0] = f.lucor;//углы
    f.field[0][76] = f.rucor;
    f.field[21][76] = f.rdcor;
    f.field[21][0] = f.ldcor;
 
    set_food();
}
 
void update() {//функция обновления положения змеи
    move();
    if (_kbhit()) {//если была нажата клавиша
        hv.rkey = _getch();//считываем ее
        s.sdir = static_cast<int>(hv.rkey);//переводим
        s.ldir = s.dir;//перед тем как присвоить новое направление-сохраняем старое
        switch (s.sdir)//новое направление 
        {
        case KEY_LEFT://влево
            if (s.ldir != 'R')
                s.dir = 'L';
            break;
        case KEY_RIGHT://вправо
            if (s.ldir != 'L')
                s.dir = 'R';
            break;
        case KEY_DOWN://вниз
            if (s.ldir != 'U')
                s.dir = 'D';
            break;
        case KEY_UP://вверх
            if (s.ldir != 'D')
                s.dir = 'U';
            break;
        }
    };
    f.field[s.shposy][s.shposx] = s.shead;//новое положение головы
    f.field[s.lastposy[hv.coutr - 1]][s.lastposx[hv.coutr - 1]] = 'o';//тут дальше сложная магия которая отрисовывает нам хвост и когда счетчик доходит до длины рисует новый хвост на 1ед длинне старого(только если длина увеличилась)
    if (s.length == hv.coutr) {
        for (int i = 1; i <= s.length; ++i) {
            f.field[s.lastposy[hv.coutr - i]][s.lastposx[hv.coutr - i]] = 'o';
        }
    }
    if (hv.coutr == s.length)
        hv.coutr = 0;
    ++hv.coutr;
    unsigned int end_time = clock();//считаем время-вообще нужно бы засунуть это в апдейт
    search_time = end_time - start_time;
}
 
void render() {//функция отображения поля с текущими параметрами
    for (int i = 0; i < 22; ++i) {
        for (int j = 0; j < 77; ++j) {
            if ((i == 0) or (i == 21) or (j == 0) or (j == 76)) {
                SetConsoleTextAttribute(hConsole, (WORD)((0 << 4) | 1));//играем с цветами для стен
                cout << f.field[i][j];
                SetConsoleTextAttribute(hConsole, (WORD)((0 << 4) | 2));//играем с цветами для змейки
            }
            else {
                if (f.field[i][j] == '*') {
                    SetConsoleTextAttribute(hConsole, (WORD)((0 << 4) | 12));//играем с цветами для еды
                    cout << f.field[i][j];
                    SetConsoleTextAttribute(hConsole, (WORD)((0 << 4) | 2));//играем с цветами для змейки
                }
                else {
                    cout << f.field[i][j];
                }
            }
        }
        cout << endl;
    }
    
    SetConsoleTextAttribute(hConsole, (WORD)((0 << 4) | 7));//играем с цветами для счета
    cout << "SCORE:" << f.fs << gi.score << f.fs << "Time:" << f.fs << fixed << setprecision(2) << search_time / 1000.0 << 's' << f.fs << "HIGHSCORE:" << f.fs << gi.hscore;
    SetConsoleTextAttribute(hConsole, (WORD)((0 << 4) | 2));//возвращаем цвет змеи
    Sleep(stime);//спим для плавности картинки
    system("cls");//чистим экран
}
 
void end_game() {//в конце игры проверяем побили ли мы рекорд
        if (gi.score > gi.hscore) {
            gi.hscore = gi.score;
            cout << "Your new highscore:" << f.fs << gi.hscore << endl;
            ofstream out("highscore.txt");
            out << gi.hscore;
            out.close();
        }
}
 
void menu() {//менюшка
SetConsoleTextAttribute(hConsole, (WORD)((0 << 4) | 2));
cout << "                       ______                _            "<< endl;
cout << "                      / _____)              | |           "<< endl;
cout << "                     ( (____   ____   _____ | |  _  _____ "<< endl;
cout << "                      \\____ \\ |  _ \\ (____ || |_/ )| ___ |"<< endl;
cout << "                      _____) )| | | |/ ___ ||  _ ( | ____|"<< endl;
cout << "                     (______/ |_| |_|\\_____||_| \\_)|_____)"<< endl;
cout << "                                                          "<< endl;
cout << "Press ENTER to start new game:" << endl;
    while (true) {
        hv.ans = _getch();
        if (hv.ans == KEY_ENTER) {
            gi.game_status = true;//запускаем игру
            break;
        }
    }
}
 
int main() {//мейн
    menu();
    while (gi.game_status) {
        init();//инициализируем
        while (gi.game_status) {//пока идет игра
            update();//обновляем
            render();//рисуем
 
        }
        end_game();
        cout << "Press ENTER to restart,or ESC to exit:";
        do{
            hv.ans = _getch();
            if (hv.ans == KEY_ENTER) {
                gi.game_status = true;
            }
        } while ((hv.ans != KEY_ESC) and (hv.ans != KEY_ENTER));
    }
    return 0;
}
Добавлено через 3 минуты
если все гуд,приступаю к curses
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
14.07.2018, 19:28
Помогаю со студенческими работами здесь

Прошу вашей критики
Народ, всем привет, в общем я только начал изучать верстку. Взял шаблон вот тут: Хотел сделать резиновую верстку, но остановился...

Прошу критики и рекомендаций
Уважаемые форумчане! Выношу на ваш суд свою БД. Раньше я никогда не занималась созданием баз, но рискнула взять на себя такую...

Прошу критики от профессионалов...
Все время работал с классическим html, но решил попробовать блогинг. Создал блог 29 января 2012 - сами видите-еще зародыш, но не успел...

Прошу критики моего списка
Я написал код, но я новичок, уверен, что в нем есть косяки. Например, как написать список, чтобы по нему можно было пройтись циклом...

Прошу критики веб-дизайна
Занимаюсь самообучением веб-дизайну. Хочу услышать адекватную критику и советы. Знаю, что еще очень многое не умею, но хотелось бы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Модель здравосохранения 17. Планы на выгорание
anaschu 23.05.2026
Вот конкретная схема реализации: В классе Работник добавить: накопленнаяУсталость — растёт каждый час работы, снижается в перерывы и болезни коэффициентПрезентеизма — снижает продуктивность. . .
Изменение цветов в палитре gif файла aka фавикона
russiannick 23.05.2026
Изменение цветов в палитре gif файла, юзаемого как фавиконка в составе html-файла, помещенная в base64, средствами нативного Java Script, навеянное сном в майский день. Для работы необходим браузер,. . .
Модель здравосохранения 16. Слишком хорошие и здоровые сотрудники уходят, недовольные зарплатой
anaschu 23.05.2026
Отладка увольнений и настройка производительности Сегодня во второй половине дня разобрались с механикой увольнений и настроили коэффициент сложности заданий. Вот что было сделано. . . .
Как я стал коммунистом))) Модель сохранения здоровья сотрудников, запись блога номер 15
anaschu 23.05.2026
Внезапно хорошее здоровье сотрудников не нужно капиталистам?))
Модель здравоСохранения 15. Как мы чинили AnyLogic модель рабочего коллектива: сочленение диаграммы состояний болезней и поломок в ресурспул
anaschu 23.05.2026
Как мы чинили AnyLogic модель рабочего коллектива Сегодня разобрались с пятью багами, из-за которых модель либо падала с ошибкой, либо давала совершенно бессмысленные результаты. Каждый баг был. . .
Диалоги с ИИ
zorxor 23.05.2026
Насколько я понимаю - Вы - Искусственный Интеллект. Это так? Да, всё верно. Я — искусственный интеллект. Я представляю собой большую языковую модель, созданную для помощи в самых разных задачах. . . .
Модель здравосохранения 14. Собираем всю модель вместе.
anaschu 22.05.2026
Модель собрана. В будущих постах на видео я покажу, как она работает. В этом посте запускаем её, проверяем результаты и разбираем что можно с ней делать дальше. Перед запуском проверяем. . .
Модель здравоохранения 13. Добавление самой системы здравоохранения.
anaschu 22.05.2026
В предыдущем посте мы настроили болезни. Теперь добавим события, которые управляют здоровьем всего коллектива, а также настроим рабочий график и расчёт финансов. В Main создаём четыре события. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru