Оцените код игры, плиз.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Привет. Это моя первая полноценная законченная программа — результат выполнения уроков сайта и самообразования. Чувства переполняют, но жена мою игру нифига не оценила :*(
Поэтому выкладываю сюда. Идея конечно же не моя — с давних пор валялся в компе англоязычный экзешник неизвестного происхождения. Написал русскоязычную версию по его мотивам. Хотелось бы услышать конструктивную критику.
Выскажу своё скромное мнение :)
Первое, что бросилось в глаза, это не совсем понятная организация объявлений и реализаций функций
comp_move
иuser_move
. Зачем объявлять их, и тут же реализовывать? Достаточно только реализации, если вы сначала реализуете все вспомогателнные функции, а только потомmain
. Хотя, в кошерном виде, структура файла, содержащего реализацию ф-цииmain
должа иметь следующий вид:И, вообще, реализацию функций, как и их определние лучше выносить в отдельные файлы, иначе, при добавлении пары-тройки функций вы получите плохочитаемый код.
Так же, если я не ошибаюсь, вызовы функций построены с ошибкой. Дело в том, что у вас функция
comp__move
вызываетuser_move
, аuser_move
вызываетcomp_move
. Таким образом, программый стек будет забиваться адресами возврата из функций, и, после очень долгой игры , ваша программа получит segmentation fault. Но это мелочи.Теперь по реализациям функций.
Функция
comp_move
реализована, на мой взгляд, хорошо. Единственный минус —srand(time(0))
нужно перенести вmain
, поскольку достаточно одного вызова этой функции.Функция
user_move
реализована не очень хорошо :(Проверку выхода за пределы лучше реализовывать в цикле, дабы экономить стек и избегать спагетти на своём экране.
Реакцию на результат сравнения тоже можно вынести в цикл, причины см. выше.
Причём сравнение, лучше реализовывать не с помощью
user_num > comp_num ? alt=1 : user_num < comp_num ? alt=2 : alt=3;
, а при помощи старых добрых конструкцийif
. Так и код становится понятней, и память экономится (это я про переменнуюalt
).Большое спасибо за отзыв! Учту ваши замечания. Что касается
я это сделал специально, чтобы игра длилась, пока пользователю не надоест играть и он сам не закроет программу. Я не придумал лучше способа, как это сделать не зацикливая функции по кругу. И этим же объясняется
Если не объявлять, компилятор встречает вызов comp_move до её реализации и выдает ошибку
[Error] 'comp_move' was not declared in this scope
А, ну да, моя ошибка :\
Slonopotam, такое использование рекурсии при длительной игре приведёт к аварийному завершению приложения. Если хочешь проверить, сделай файл из символов '1', разделённых пробелом, размером 10-20-100Кб и подай на вход своей программе:
У меня твоя программа вылетала уже при размере файла 10Кб (компилировал в MSVS C++ 2013 со стандартными настройками).
Вообще, такое использование рекурсии — однозначно вред. Для организации циклов в языке имеются специальные конструкции. Это и безопаснее и быстрее работает.
Сделал бы бесконечный цикл. Это обычная практика в таких делах.
О! Вот бесконечный цикл и был моей первой идеей, как это можно сделать. Но я решил, что рекурсии будут выглядеть солиднее! :))
Буду знать. Спасибо!
А Вы бы попробовали выводить строчки на экране разными цветами. Так сказать, навести красоту. :) Женщины такое любят. Может быть, и Вашей жене больше понравится.
Удивительным образом Ваша программа похожа на мою собственную. Только я не встречала англоязычных версий — писала сама.
Отличия, конечно, тоже есть, но они легко поправимы. 1) В моей программе не задан уровень сложности. Всегда выбирается число от 1 до 50. 2) У меня в программе нет бесконечного цикла, она работает только один раз.
Отличия, конечно, тоже есть, но они легко поправимы. 1) В моей программе не задан уровень сложности. Всегда выбирается число от 1 до 50. 2) У меня в программе нет бесконечного цикла, она работает только один раз.
Я думаю существует много реализаций этой программы на разных языках, учитывая её простоту. А до разноцветных строчек я еще обязательно доберусь. :)
Вариант без рекурсии с минимальными правками:
Мне не очень понравилось логическое разбиение программы на две функции: ход компьютера и ход игрока. На уровне ощущений. Видимо потому, что пользовательский интерфейс переплетён с логикой программы, и в программе имеется повторяющийся код.
Кстати, гарантированно отгадать число из интервала 1..50 за 5 ходов невозможно. Этот уровень сложности надо назвать «Вам повезёт!».
Вот код моей программы. Разноцветной.
Ещё одно отличие в том, что здесь кол-во попыток не задаётся заранее, а определяется по ходу. Она короче и проще (например, здесь нет ни одной функции).
Olly, в статье Пишем змейку на C++ есть реализация класса для вывода цветного текста на консоль. Там правда все достаточно аскетичненько, но работает. И лицензия GPL — так что можно юзать ))
Фтьiкай, спасибо!
Правда, я не спрашивала... Но интересно было посмотреть чужой опыт.
Когда-то я задавалась этим вопросом. Нашла в интернете и написала программку, в которой слово «Привет» выводится разными цветами:
А потом уже я смогла выводить строчки разными цветами.
Нарыл более простой способ менять цвет и фона и текста целиком с помощью system(). Если требуется установить значение 1 раз, напишите команду в глобальной области.
Slonopotam, ты — просто мастер находить нужную информацию!
Я попробовала ввести точно такой же текст. Почему-то приветствие печатается только 2 раза вместо трёх. Зато разными цветами и на разном фоне.
Здесь два недостатка.
system()
очень медленная.Через системные вызовы — оно более гибко и правильно.
Или пользовать
ncurses
/PDcurses
, если нужна переносимость.Olly,
Печатается 3 раза. Только последнюю выдачу ты не успеваешь заметить, потому что окно консоли закрывается. Поставь в конце ещё один
_getch()
и будет тебе счастье. Или запускай в Visual Studio через Ctrl-F5.Cranium, поставила в конце _getch() и получила то самое счастье! Спасибо!