Файл: Игра 3 в ряд на языке Python по дисциплине Языки и системы программирования. Данная программа осуществляет вывод на экран случайным образом расположенных объектов разного цвета и дальнейшие варианты их взаимодействия.docx

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 07.11.2023

Просмотров: 942

Скачиваний: 20

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Поэтому, если мы будем запускать скрипт message.py отдельно, сам по себе, то Python присвоит переменной __name__ значение __main__, далее в выражении if вызовет функцию main из этого же файла.Однако если мы будем запускать другой скрипт, а этот - message.py - будем подключать в качестве вспомогательного, для message.py переменная __name__ будет иметь значение message. И соответственно метод main в файле message.py не будет работать.Данный подход с проверкой имени модуля является более рекомендуемым подходом, чем просто вызов метода main. [3]1.5. Выражения PythonВ современных языках программирования принято производить большую часть обработки данных в выражениях. Синтаксис выражений у многих языков программирования примерно одинаков. Синтаксис выражений Python не удивит программиста чем-то новым. (Разве что цепочечные сравнения могут приятно порадовать.) Приоритет операций показан в таблице (в порядке уменьшения). Для унарных операций х обозначает операнд. Ассоциативность операций в Python -слева направо.Таблица 1.2. - Выражения Python

Операция

Название

lambda

Лямбда-выражение

or

Логическое ИЛИ

and

Логическое И

not x

Логическое НЕ

in, not in

Проверка принадлежности

is, is not

Проверка идентичности

<,<=,>,>=,!=, ==

Сравнения

^

Побитовое исключающее ИЛИ

&

Побитовое И

<<, >>

Побитовые сдвиги

+,-

Сложение и вычитание

*, /, %

Умножение, деление, остаток

+x, -x

Определение и смена знака

x

Побитовое НЕ

**

Возведение в степень

x.атрибут

Ссылка на атрибут

x[индекс]

Взятие элемента по индексу

f(аргумент)

Вызов функции

(…)

Скобки или кортеж

|

Побитовое ИЛИ

Порядок вычислений операндов определяется правилами:1. Операнд слева вычисляется раньше операнда справа во всех бинарных операциях, кроме возведения в степень.2. Цепочка сравнений вида a

< b) and (b <с) and ... and (у< z).

3. Перед фактическим выполнением операции вычисляются нужные для нее операнды. В большинстве бинарных операций предварительно вычисляются оба операнда (сначала левый), но операции or и and, а также цепочки сравнений вычисляют такое количество операндов, которого достаточно для получения результата.

4. Аргументы функций, выражения для списков, кортежей, словарей и т. п. вычисляются слева направо, в порядке следования в выражении. В случае неясности приоритетов желательно применять скобки, несмотря на то что одни и те же символы могут использоваться для разных операций, приоритеты которых не меняются. Так, «%» имеет тот же приоритет, что и «*», а потому в следующем примере скобки просто необходимы, чтобы операция умножения произошла перед операцией форматирования:


print «%i» % (i*j)


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


os.system(«dir»)

digits = re.compile(«\d+»)

print argv[0], environ


Повторный импорт модуля происходит гораздо быстрее, так как модули кэшируются интерпретатором. Загруженный модуль можно загрузить еще раз (например, если файл с текстом модуля изменился на диске) с помощью функции reload():


import mymodule reload(mymodule)


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


  1. Специальная часть


2.1. Python
для программирования игрЕсли сравнивать языки программирования, то это можно представить так:Python vs JavaPython - это интерпретируемый язык с динамической типизацией. Java же - компилируемый язык со статической типизацией. Эти различия делают Python и Java полными противоположностями друг друга в плане скорости запуска и выполнения программ. Код, написанный на Python, быстрее запускается и дольше выполняется. В то время как программы на Java медленнее запускаются, но гораздо быстрее выполняются.

Если говорить о сложности этих двух языков, то Java безусловно уступает Python в простоте изучения. На изучение Python у начинающего разработчика уходит несколько недель, а вот на изучение Java может понадобиться несколько месяцев.Python vs C/C++Все преимущества и недостатки языка Java, описанные выше, можно отнести и к C/C++ (что не удивительно, ведь Java - C-подобный язык). Однако всё же есть существенное отличие C/C++ от Python - это стоимость разработки и качество программного обеспечения. Для того чтобы разрабатывать на C/C++, программист должен обладать более высокой квалификацией. Из этого можно сделать вывод, что программное обеспечение, разработанное на C/C++, будет более качественным, но и стоить будет дороже.Ещё одно отличие Python от C/C++ - длина кода и простота его восприятия. Программы, написанные на языке Python, могут быть до 10 раз короче, чем на C/C++. Конечно же, это напрямую влияет на скорость разработки.Python vs JavaScriptPython и JavaScript входят в топ-2 в рейтинге TIOBE. Оба этих языка программирования являются объектно-ориентированными. Опять же, Python синтаксически проще JavaScript, но при этом программы, написанные на JavaScript, работают быстрее. Быстрая производительность JavaScript позволяет создавать приложения, которые действуют в режиме реального времени. Поэтому JS в большей степени используют для веб-разработки. [6]Главной целью приложения «3 в ряд» является зарабатывание определённого количества очков, получить которые можно при передвижении «плиток» в таком направлении, чтобы их количество стало 3 или больше. Также в игре присутствует ограничение по количеству «ходов». Это сделано для достижения казуальности игры и также, чтобы она имела возможность реиграбельности.Главными составляющими элементами игры являются: игровое поле, состоящее из строк и столбцов, игровые плитки с возможностью их передвижения, счётчики ходов и очков. Игрок может выделить 2 рядом стоящие плитки чтобы поменять их местами.
2.2. Запуск интерпретатораВозможно, самый простой способ выполнения программ Python заключается в том, чтобы набирать их в интерактивной командной строке Python, иногда называемой интерактивной подсказкой. Существует несколько способов запуска такой командной строки: в IDE-среде, из системной консоли и т.д. Предполагая, что в системе присутствует интерпретатор Python, установленный как исполняемая программа, наиболее нейтральный к платформам способ запуска интерактивного сеанса интерпретатора предусматривает ввод в командной строке операционной системы просто python без каких-либо аргументов. Например:

% python

Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64 bit



Type "help”, ’’copyright", "credits" or "license” for more information.

Для получения дополнительной информации наберите help, copyrightf credits или license.

>>> ^Z
Ввод слова python в приглашении командной оболочки вашей системы начинает интерактивный сеанс Python; символом % в этой книге обозначается обобщенное приглашение на ввод команд - вы не набираете его самостоятельно. В среде Windows выход из сеанса производится нажатием клавиатурной комбинации ; в среде Unix взамен применяется .Понятие приглашения командной оболочки системы является обобщенным, но способ получения доступа к нему доступ зависит от платформы.

  • В Windows вы можете ввести python в консольном окне DOS - программе, которая имеет имя cmd.exe и обычно известна как окно командной строки. Дополнительные сведения о запуске окна командной строки приведены во врезке “Где находится окно командной строки в Windows?” далее в главе.

  • В Mac OS X вы можете запустить интерактивный интерпретатор Python, дважды щелкнув на пункте Applications^ Utilities^Terminal (Приложения^Служебные1^Терминал) и затем введя python в открывшемся окне.

  • В Linux (и других разновидностях Unix) вы можете ввести команду python в окне командной оболочки или терминала (например, в xterm или в консоли, выполняющей командную оболочку вроде ksh или csh).

  • В других системах могут использоваться похожие или специфичные для платформы методы. Скажем, запуск интерактивного сеанса на карманном устройстве может требовать щелчка на значке Python в соответствующем окне.

Всякий раз, когда вы видите приглашение >>>, вы находитесь в интерактивном сеансе интерпретатора Python - здесь можно набирать любой оператор или выражение Python и выполнять его немедленно. [2]Интерпретатор ведёт себя сходно шеллу Unix: если он вызван, когда стандартный ввод привязан к устройству tty - он считывает и выполняет команды в режиме диалога; будучи вызванным с именем файла в качестве параметра или с файлом, назначенным на стандартный ввод - он читает и выполняет сценарий из этого файла.Другой способ запустить интерпретатор - директива python -c команда [arg] ... - при её использовании поочередно выполняются инструкции из команды (как при использовании опции -c Unix-шелла). В связи с тем, что инструкции Python часто содержат пробелы или другие специальные для шелла символы, рекомендуется заключать команды полностью в одинарные кавычки.Некоторые модули Python оказываются полезными при использовании их в качестве сценариев. Они могут быть запущены в этом виде командой python -m модуль [arg] ... - таким образом исполняется исходный файл модуля (как произошло бы, если бы вы ввели его полное имя в командной строке).Обратите внимание на различие между командами python file и python

При использовании файла сценария иногда полезно иметь возможность запустить сценарий и затем войти в интерактивный режим. Это может быть сделано через указание параметра -i перед именем сценария. (Этот способ не сработает, если сценарий считывается со стандартного ввода - по той самой причине, которая описана в предыдущем абзаце). [6]
2.3. Алгоритм реализации игровой части
В данном разделе осуществлён разбор программного кода модуля game.py с последующим описанием основных функций.

Запуск программы осуществляется через .py - файл находящийся в папке с игрой. Для запуска программы также понадобится установленный на компьютере язык программирования Python и пакет расширений для создания приложений Pygame.

Проект программы состоит из самого файла игры, а также папки с содержанием иконок плиток.

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

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

Строка:


for y in range(len(board)):

streak = 1

for x in range(1, len(board[y])):

if board[y][x] == board[y][x-1] and board[y][x] != 0:

streak += 1

else:

streak = 1

if streak >= 3:

return True


Столбец:


for x in range(len(board[0])):

streak = 1

for y in range(1, len(board)):

if board[y][x] == board[y-1][x] and board[y][x] != 0:

streak += 1

else:

streak = 1

if streak >= 3:

return True

return False


Функция len() возвращает длину (количество элементов) в объекте.

В кортеже хранится запись: каждый элемент кортежа содержит данные одного поля, а его позиция определяет семантику поля.

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

Но если считать кортеж набором полей, то количество элементов часто фиксиро-вано, а порядок имеет первостепенное значение. [4]

Далее идёт добавление элемента случайности:


def format_board(board):

while match_exists(board):

for y in range(len(board)):

for x in range(len(board[y])):

board[y][x] = random.randrange(1,7)

return board


В данном случае функция randrange возвращает случайное число в пределах промежутка от 1 до 7, так как в игре используется 6 различных элементов.



Рисунок 2.1. Файлы папки draw
Алгоритм работает так, чтобы не было повторений плиток при генерации игрового поля и соответственно, чтобы не появлялись цепочки из 3 последовательных плиток, так-как если в начале игры появится цепь из 3 и более плиток, тогда начнётся получение очков без участия игрока.

Далее идет отображение текстового представления игрового поля:


Рисунок 2.2. Изображение плиток



def show_board(grid):

for y in range(len(grid)):

for x in range(len(grid[y])):

print(grid[y][x], end = « «)

print()


Метод grid() позволяет поместить виджет в определенную ячейку условной сетки или grid'а.

Метод grid применяет следующие параметры:

  • column: номер столбца, отсчет начинается с нуля

  • row: номер строки, отсчет начинается с нуля

  • columnspan: сколько столбцов должен занимать элемент

  • rowspan: сколько строк должен занимать элемент

  • ipadx и ipady: отступы по горизонтали и вертикали соответственно от границ элемента до его содержимого

  • padx и pady: отступы по горизонтали и вертикали соответственно от границ ячейки grid’а до границ элемента

  • sticky: выравнивание элемента в ячейке, если ячейка больше элемента. Может принимать значения n, e, s, w, ne, nw, se, sw, которые указывают соответствующее направление выравнивания. [14]

Остановка (пауза) игрового поля:


def display_pause(clock, x):

pygame.display.flip()

clock.tick(x)


Разбор игрового процесса

Алгоритм проверки, находиться ли первая выделенная плитка рядом со второй. Если эта проверка успешна тогда происходит смена плиток друг с другом.






Рисунок 2.3. Смена плиток


def isAdjacent(selected_x, selected_y, x, y):

if selected_x+1 == x and selected_y == y:

return True

elif selected_x-1 == x and selected_y == y:

return True

elif selected_y+1 == y and selected_x == x:

return True

elif selected_y-1 == y and selected_x == x:

return True

return False

def swap(array, x1, y1, x2,y2 ):

temp = array[y1][x1]

array[y1][x1] = array[y2][x2]

array[y2][x2] = temp


Далее идут алгоритмы проверки строк и столбцов на совпадения:

Строка:


def elim_matches(board):

elim_list = []

for y in range(len(board)):

streak = 1

for x in range(1, len(board[y])):

if board[y][x] == board[y][x-1] and board[y][x] != 0:

streak += 1

else:

streak = 1

if streak == 3:

elim_list += [[y,x-2]]

elim_list += [[y,x-1]]

elim_list += [[y,x]]

elif streak > 3:

elim_list += [[y,x]]


Столбец:


for x in range(len(board[0])):

streak = 1

for y in range(1, len(board)):

if board[y][x] == board[y-1][x] and board[y][x] != 0:

streak += 1

else:

streak = 1

if streak == 3:

elim_list += [[y-2,x]]

elim_list += [[y-1,x]]

elim_list += [[y,x]]

elif streak > 3:

elim_list += [[y,x]]


Обнуление всех найденных совпадений:


for i in range(len(elim_list)):

y = elim_list[i][0]

x = elim_list[i][1]

board[y][x] = 0



return len(elim_list)


Дальше идет перенос плиток на пустые ячейки строго по оси y:


def board_filled(board):

for y in range(len(board)):

if 0 in board[y]:

return False

return True


Проверка игрового поля от нижнего левого угла вверх по каждому столбцу:


def drop_tiles(board):

for x in range(len(board [0])):

for y in range(len(board) - 2, -1, -1):

if board[y+1] [x] == 0 and board[y][x] != 0:

swap (board, x, y+1, x, y)


После проверки идёт заполнение пустых ячеек на верхней границе поля, которые остались после переноса плиток на пустые ячейки:


def fill_top(board):

for x in range (len(board [0])):

if board[0][x] == 0:

board[0][x] = random.randrange(1,7)


Разбор игрового интерфейса

Основой интерфейса является бокс с размещёнными на нём элементами: крайнее число очков, которое нужно набрать для победы, счётчик очков и счётчик ходов.


def main ()

WIDTH = 7

HEIGHT = 9

BOX_LENGTH = 70

selected = False

selected_x = None

selected_y = None

score = 0

turns_left = 20

GOAL_SCORE = 300

exit_game = False

gameover_displayed = False

os.environ['SDL_VIDEO_CENTERED'] = '1'

board = init_2DArray (WIDTH, HEIGHT)

format_board(board)

pygame.init()

sound.load()

screen = draw.create_screen(WIDTH, HEIGHT, BOX_LENGTH)

clock = pygame.time.Clock()

draw.window(board, turns_left, score, GOAL_SCORE)

pygame.display.flip()


В параметрах WIDTH, HEIGHT и BOX_LENGTH устанавливаются размеры игрового окна, а также расстояние между объектами по сетке. Значение score отвечает за количество очков, набираемых в игре. GOAL_SCORE отображает количество очков которое необходимо набрать для победы. Turns left отвечает за количество ходов которое даётся на игру. За отцентровку окна отвечает строка: os.environ['SDL_VIDEO_CENTERED'] = '1'.

Код для кнопки выхода из окна, а также для выделения игровых плиток:


while not exit_game:

while turns_left > 0 and not exit_game:

for event in pygame.event.get():

if event.type == pygame.QUIT:

exit_game = True

elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:

coord_pair = pygame.mouse.get_pos()

x = math.floor(coord_pair[0] / BOX_LENGTH)

y = math.floor(coord_pair[1] / BOX_LENGTH)

if x < WIDTH and y < HEIGHT:

if selected == False:

selected = True

selected_x = x

selected_y = y

draw.selected(x,y)

elif selected == True:

if isAdjacent(selected_x, selected_y, x, y):

swap (board, selected_x, selected_y, x, y)

draw.window(board, turns_left, score, GOAL_SCORE)

display_pause(clock, 2.5)


Смена плиток друг с другом и дальнейшее взаимодействие с элементами подсчитывания очков и количества ходов:


elif not match_exists(board):

swap (board, selected_x, selected_y, x, y)

draw.window(board, turns_left, score, GOAL_SCORE)

pygame.display.flip()


Снятие выделения с плиток после того, как с ними произошло взаимодействие:


elif not isAdjacent(selected_x, selected_y, x, y):

draw.window(board, turns_left, score, GOAL_SCORE)

pygame.display.flip()

selected = False

selected_x = None

selected_y = None


Алгоритм, отвечающий за подсчёт комбинаций подряд собранных цепочек из плиток:


if match_exists(board):

turns_left -= 1

turn_score = 0

combo_count = 2


Алгоритм, отвечающий за подсчёт очков по формуле: количество очков за ход, умноженное на количество комбинаций за ход:


combo_count -= 1

score += turn_score*combo_count

draw.window(board, turns_left, score, GOAL_SCORE)

pygame.display.flip()


Проигрывание эффекта победы если количество очков ровно GOAL_SCORE:


if not gameover_displayed:

if score >= GOAL_SCORE:

draw.win()

sound.play_effect(«win»)



1   2   3   4   5