Как сделать игру города на python
Перейти к содержимому

Как сделать игру города на python

  • автор:

 

Python. Игра в города

Это просто, открываем Вики. Остается сделать следующее:

  1. скачать страницу
  2. спарсить города из таблицы
  3. сохранить в файл

Парсим города в файл

Теперь у нас есть cities.txt в котором 1117 городов.

Что будем делать?

Обычная игра в города, которую все мы знаем. Пользователь всегда будет начинать первым. Игра заканчивается либо когда пользователь сдается либо когда у нас не осталось городов на текущую букву.

Для этого нам потребуется 2 хранилища: одно для набора городов, которые были названы, второе для оставшихся городов.

Еще нам нужно фильтровать последние буквы города если его название заканчивается на твердый знак, например, то нужно взять следующую букву с конца. Всего таких букв будет 4: (“Ъ”, “ь”, “ы”, “й”).

Также нужно произвести некоторую оптимизацию имен городов: перевести все имена в нижний регистр и заменить “ё” на “е”.

Ну а дальше все достаточно просто: получаем название города от пользователя, смотрим в списке уже названных городов на случай если пользователь забыл, что этот город уже был назван; смотрим в списке доступных городов, на случай опечатки или придумывания названия; и проверяем что пользователь назвал город с нужной буквы. После этих проверок выясняем на какую букву будем выбирать следующий город, получаем город на эту букву из списка доступных, обновляем состояние наборов городов и выводим. Если у нас нет больше городов на указанную букву, то все.

Кодируем

Для начала реализуем метод, который будет приводить имя города в общий вид

Этой функцией мы будем пользоваться при получении названия города от пользователя и при загрузке списка городов из файла.

Загружаем список городов

Открываем файл, получаем список строк и обрабатываем через функцию normalize_city_name все строки из файла которые содержат хотябы один печатный символ.

Такой подход безопасен, так как это не генераторное выражение и на следующей строке счетчик ссылок на открытый файл станет равен нулу и пайтон закроект файл перед тем как уничтожить объект представляющий его в памяти. Однако я рекомендую все таки использовать контекстный менеджер для все видов операций при работе с файлами, так как сказанное выше не относится, например к интерпретатору IronPython, так как он имеет более сложный механизм сборщика мусора.

Этот код гарантирует что файл будет корректно закрыт, даже если во время операции чтения будет вызвано исключение. Более подробно об этом можно почитать в документации по контекстным менеджерам.

Теперь нам нужно попросить пользователя ввести город, после этого произвести все необходимые проверки

  1. Получаем ввод от пользователя. char or “any” потому что char изначально будет None, когда игра только началась.
  2. нормализуем строку
  3. создаем словарь который будет передан как **kwargs в методы проверки
  4. производим все проверки и ожидаем что все будут True
  5. если не все проверки были пройдены, то повторяем все еще раз

check_list — это список содержащий ссылки на функции которые принимают первым аргументом город и что-то что им нужно для выполнения проверки. Таких метода у нас 3

Первая функция проверяет что город начинается с нужной буквы, второй — что город еще не был назван и третий — что такой город нам известен.

Декоратор check_point позволяет зарегистрировать любой метод как метод проверки города от пользователя, для его работы нужно объявить список, в котором будут все проверки и обернуть требуемые функции в декоратор.

Как мы видим код декоратора прост. Мы используем знание о том что тело декоратора выполняется на этапе загрузки модуля и добавляем ссылку на функцию в список. Декоратор возвращает сам метод никак его не изменяя. Более подробно про декораторы описано в серии статей на хабре.

Мне нравится данный подход тем, что так явно видно что функция is_available является функией проверки. Хотя есть и минус, который решается через ООП, отсутствие явного интерфейса. Только задокументировав, можно сообщить, что такой метод должен принимать и возвращать.

После всех проверок, нам нужно будет переместить названный город в кеш и убрать его из списка доступных

И затем выбрать букву на которую должен начинаться следующий город

city[::-1] — позволяет проитерировать название города в обратном порядке, то же самое делает функция reversed(). Блок else у for выполнится только в том случае если не сработает break, что невозможно.

Теперь можно реализовать функцию которая будет описывать ход компьютера

Тут та же логика, если break не выполнился, то это значит что мы не нашли города на эту букву, а значит пользователь победил.

И осталось реализовать точку входа

 

Функция cycle из модуля itertools принимает в качестве аргумента итерируемый объект и позволяет бесконечно его итерировать. Таким образом мы на каждую итерацию меняем функцию *_point, описывающую кто делает ход, так мы реализуем пошаговую логику игры. Сначала будет выполнен метод user_point, потом ai_point и так по кругу.

Игра в города на питоне с использованием регулярных выражений

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

Что-то пошло не так в этом варианте программы: вызванный город не удаляется.

По совету друга я изменил строчку на patterns=[r'[<>]\S\D+\S’.format(c)] для того, чтобы программа нормально читала русский язык, однако тут вылезли другие проблемы программа начала выводить сразу несколько городов подряд, к тому же не удаляет эти города.

В связи с этим хочу спросить совета: как изменить код, чтобы город был удален после вызова?

Игра Города¶

Игра начинается с того что один из игроков называет город и следующему игроку нужно назвать город, который будет начинаться на последнюю букву предыдущего:

Задание¶

Реализовать версию, в которой будет возможность вводить любые слова и будет проверка на совпадение первой и последней буквы

Сделать так чтобы можно было вводить слова в любом регистре

Добавить проверку на существование города, который введёт пользователь

Сделать чтобы города не могли повторяться

Добавить графический интерфейс с помощью библиотеки easygui

Добавить возможность играть с компьютером. Для этого потребуется библиотека random и функция choice

Игра в города на Python

Игра в города — это всем знакомая с детства игра. Тот кто начинает обычно говорит «Москва» и дальше нужно назвать город на букву «А», т.к. Москва кончается на А. Игру в города можно написать на Python. Это будет игра для одного человека в которой человек будет играть против компьютера. Что бы компьютер мог играть он должен будет иметь в своем распоряжении список всех городов России. Вот такую игру мы и напишем в этом уроке.

Давайте начнем писать программу постепенно усложняя ее. План у нас такой:

  • Создадим основной цикл игры
  • Добавим загрузку всех городов из внешнего файла
  • Добавим все нужные проверки

Основной цикл игры в Города

Добавим игровой цикл игры который позволит играть по очереди с компьютером пока игра не завершится. Игра у нас будет завершена в 2 случаях:

  • Если компьютер в своей базе не найдет город на нужную букву — в этом случае победил человек
  • Если человек не может назвать очередной город на нужную букву и вместо названия города пишет кодовое слово «стоп».

Так же мы добавим основную проверку для этой игры — это проверку того что названный город начинается на нужную букву. А нужная буква — это последняя буква в названии города на предыдущем шаге. Эту букву будем хранить в переменной «s_end».

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

Добавим загрузку городов из файла

Список городов лучше всего хранить отдельно от текста программы. Это позволит сделать игру универсальной. Например можно будет поменять список на города Мира, а не только России. Или например поиграть в страны, а не в города. Вам нужно будет только заменить список в текстовом файле.

Вот файл со всеми городами России: города.txt. Файл нужно поместить в каталог с программой.

А вот простой код для осуществления загрузки этого файла.

Добавим проверки

Основную проверку мы уже добавили — это проверка, что город на нужную букву. Но кроме того нужно добавить еще 2 проверки:

  • Проверка, что назван реально существующий город.
  • Проверка, что этот город еще не называли.

Компьютер не сможет обманывать, но человек легко может схитрить и назвать компьютеру не существующий город на нужную букву. Для проверки того, что город действительно существует нужно после ответа человека проверить — содержится ли названный город в базе данных городов.

Кроме того каждый город должен быть назван только один раз. По этому создадим пустой список и в него будем записывать все названные города. И при очередном ходе будем проверять, что названный город не содержится в списке уже названных.

У нас увеличивается количество переменных для хранения городов:

  • cityes_all — тут просто список всех городов России
  • cityes — тут список городов которые можно использовать на данном шаге. Это список всех городов без тех городов которые уже назвали.
  • cityes_old — тут список городов которые уже называли. В начале он пуст.

Так же добавим проверку на символы исключения. Например назван город «Астрахань» — последняя буква «ь». Нет города на эту букву. По этому последней буквой будем считать предпоследнюю, т.е. «н». Список таких символов будем хранить в переменной «symbols_bad».

Полный код игры в города на Python

Вот полный код игры с возможностью загрузить города из файла и со всем нужными проверками.

Домашнее задание

В основном цикле игры есть переменная которая отвечает за то чей следующий ход — человека или компьютера. Попробуйте изменить программу так что бы следующим ходом был постоянно ход компьютера. Так вы заставите сыграть в игру Города компьютер с компьютером. В результате получится довольно длинная цыпочка из названных городов.

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *