Ваш браузер устарел. Рекомендуем обновить его до последней версии.

Info Board


Russian_Roulette.py >>

Animate_Revolver.py >>

Файл .exe для игры в CMD >>

Sounds >>

GitHub >>

Игра Русская рулетка

Опубликовано 07.11.2023

Знаменательно, что именно 7 ноября по новому стилю календаря произошла Октябрьская революция. Да просто героем текущего блога будет красавец РЕВОЛЬВЕР!

А Вы знали? - В револьвере роль патронника играют отверстия его барабана, также называемые кáморами!

Суть игры. В револьвере 6 патронов. Стрелок должен вложить в барабан револьвера от 1 до 6 патронов и нажать на спусковой крючок. Каждому отверстию патронника соответствует номер от 1 до 6. Патронникам с вложенными стрелком патронами, случайным образом будут присвоены номера. Затем среди шести чисел, соответствующих номерам патронников, будет случайным образом выбрано одно для выстрела. Если оно совпадёт с патронником, где вложен патрон, то появится надпись: "Выстрел", если нет, тогда надпись: "Пустой!". Для более жизненной картины, в некоторых вариантах игры также будет иметь место одна Осечка! Она выбирается также случайным образом среди патронников с вложенными патронами.

В анимационных вариантах игры (для одного игрока) на экране появляется окно с анимацией выстрела револьвера. Анимация воспроизведена через фреймворк Tkinter. В связи с этим, код, отвечающий за анимацию, лучше сделать в отдельном файле (например Animate_Revolver.py), а затем просто импортировать рабочие функции… Также в корне проекта нужно создать папку 'sounds' и переместить в неё звуковое и видео сопровождение игры >>

Варианты игры "Русская рулетка":

✅ Классика. Для одного без осечек. С анимацией.

✅ Игра для одного с осечкой. С анимацией.

✅ Игра для двоих с осечкой. Без анимации.

Пример результата игры на двоих:

Выберите число патронов от 1 до 6: 2
Патроны вложены в патронники №: 4, 1
Крутим барабан...
Стрелок 1 спускает курок!
Пустой! :) || Патронник № 2
Крутим барабан...
Стрелок 2 спускает курок!
Осечка! ❤️ || Патронник № 1
Крутим барабан...
Стрелок 1 спускает курок!
Выстрел! * || Патронник № 4
Конец игры ☠️ на 3 выстреле!

Итак, ниже представлен скрипт для запуска первого варианта игры. Создаём его в первом файле Russian_Roulette.py:

from Animate_Revolver import run_gif_animation_shot, run_gif_animation_empty, run_gif_animation_misfire, gunshot_sounds
import random
import time

"""
РУССКАЯ РУЛЕТКА. Классика без осечек с анимацией.
Classic version without misfires with animation.
"""

def russian_roulette_classic():

"""В револьвере роль патронника играют отверстия его барабана, также называемые кáморами."""
while True:

try:
# Ввод количества патронов, помещаемых в барабан револьвера:
# C ростом количества патронов в барабане, вероятность выстрела повышается!
shooter_choice = int(input("Выберите число патронов от 1 до 6: "))

if 1 <= shooter_choice <= 6:
# Генерация случайных номеров, соответствующих отверстиям патронника (каморы).
# Присваиваем каждому патрону, вложенному в камору - свой номер в патроннике:
bullet_chamber_numbers = random.sample(range(1, 7), shooter_choice)

chambers = ', '.join(map(str, sorted(bullet_chamber_numbers)))
print(f"Патроны вложены в патронники №: {chambers}")

# Задаём случайный выбор номера патронника в барабане для выстрела:
shot = random.choice(range(1, 7))

# Крутим барабан:
print("Крутим барабан...")

time.sleep(1)
print(f"Стрелок спускает курок!")
time.sleep(1)

# Сравниваем, что номер патронника для выстрела совпадает с номером, где находится патрон:
if shot == bullet_chamber_numbers or shot in bullet_chamber_numbers:

# Запустим анимацию, зареалим выстрел и пошумим:
run_gif_animation_shot('sounds/shot_revolver.gif', 'sounds/shot.wav')

print(f"\u27A4 Выстрел! * || Патронник № {shot}")
else:
run_gif_animation_empty('sounds/misfire_empty.gif', 'sounds/empty.wav')
print(f"Пустой! \u263B || Патронник № {shot}")
break
except ValueError:

print("Нужно ввести количество патронов от 1 до 6!")

# Запуск игры
def main():

russian_roulette_classic()

if __name__ == '__main__':
main()

В файле "Animate_Revolver.py" размещаем скрипты с анимацией (приведём здесь один пример):

from tkinter import *
import threading
from PIL import Image, ImageTk
import simpleaudio as SAudio

# Анимация выстрела
def run_gif_animation_shot(image_path, sound_path):
root = Tk() # Создаём окно

# Выводим окно поверх остальных:
# root.lift()
root.attributes('-topmost', True)

# Делаем окно по центру
w, h = 370, 300
sw = root.winfo_screenwidth()
sh = root.winfo_screenheight()
x = (sw - w) / 2
y = (sh - h) / 2
root.geometry('%dx%d+%d+%d' % (w, h, x, y))

# Загрузка gif-файла
gif_image = Image.open(image_path)

# Получение списка всех кадров анимации
frames = []
for frame in range(0, gif_image.n_frames):
gif_image.seek(frame)
frames.append(ImageTk.PhotoImage(gif_image))

# Создание метки и установка первого кадра анимации
label = Label(root)
label.pack()
label.configure(image=frames[0])

def play_sound(sound_path):
wave_obj = SAudio.WaveObject.from_wave_file(sound_path)
play_obj = wave_obj.play()
play_obj.wait_done()

# Функция закрытия:
def close_window():
root.destroy()

# Функция для обновления кадров анимации
def update(uframe):
label.configure(image=frames[uframe])
uframe = (uframe + 1) % len(frames)
# Воспроизведём звук на определенном кадре анимации:
if uframe == 18:
threading.Thread(target=play_sound, args=(sound_path,)).start()
# Повтор анимации:
root.after(100, update, uframe)
# Закрываем окно после указанного кол-ва мсек:
root.after(2500, close_window)

root.after(100, update, 0)
root.mainloop()

Метод after() в tkinter используется для планирования запуска функции через определенное количество времени. Первый аргумент метода after() указывает время задержки в миллисекундах перед выполнением функции. Второй аргумент - это имя функции, которую нужно вызвать. В этом примере это update(). Дополнительные аргументы после имени функции передаются в саму функцию. В данном случае передаётся аргумент 0.

Некоторые операционные системы или окружения оконного менеджера могут не поддерживать или не правильно обрабатывать атрибут "-topmost". В этом случае использование root.lift() может быть полезным дополнением, чтобы гарантировать, что окно будет отображаться поверх остальных окон независимо от особенностей системы.

Также в данном примере добавлена функция play_sound(), которая использует модуль simpleaudio для воспроизведения звукового файла формата WAV. Затем, в функции update() добавлена логика для запуска воспроизведения звука на определённом кадре анимации (в данном случае на кадре 18). Звук проигрывается в отдельном потоке с помощью модуля threading, чтобы не блокировать выполнение анимации.