Карткова гра для телеграм.

Основи Python и Django. -> Опис завдання.

Карткова гра для телеграми.

Завдання: розробити карткову гру для телеграм.

start page

Інструменти:

Telebot (pytelegrambotapi) – клієнт телеграм.

Pillow – бібліотека для роботи із зображеннями.

Суть гри.

Спочатку гравцям дається по 20 грн. на рахунок.

На початку гри кожен гравець покладає на ставку в 1 грн

Користувачеві дається 3 карти з 24 (без дам вальтів та королей).

Підрахунок набраних очок ведеться для карток однакової масті.

Туз - 11, решта за номіналом.

Виграшні комбінації: три тузи та 3 шістки (останні найвищі).

Після роздачі гравець вибирає із 3-х варіантів.

  1. Впасти. При цьому комп’ютер забирає усі гроші на коні.

  2. Розкрити карти. Перевіряються окуляри та визначається переможець.

  3. Продовжити гру. Гравець кладе на кін ще 1 грн. та слово дається комп’ютеру.

Після чого комп’ютеру лунає 3 карти та вибирає він.

Логіка роботи комп’ютера.

При наборі менше 11 варіант 1.

При наборі між 12 та 17 вибирає між 2 і 3 з ймовірністю 50/50.

При наборі між 18 і 21 між 2 і 3, але з ймовірністю 30/70 на користь 3 варіанти

При наборі вище 21 – 3 варіант

Після обнулення рахунку гра призупиняється.

Технічні вимоги.

Роздані карти, рахунки користувачів та інші необхідні стани гри зберігати та зчитувати з json файлу.

Роздані карти надсилати однією картинкою в телеграм (комбінуючи в одну бібліотеку Pillow)

Вибір варіантів зробити кнопками.

Репозиторій із недоробленою програмою.

Можна брати приклади коду.

Що там потрібно доробити:

  • перевірка карток однакової масті при підрахунку

  • Рахунки користувачів

  • варіант продовження гри користувачем

  • логіка гри комп’ютера

Основи Python и Django. -> Карткова гра для телеграм.

Карткова гра для телеграм.

Суть гри описує гра БлекДжек.

Коли користувач послідовно набирає випадкові карти з колоди і набирає бали трохи більше 21.

Після проходження курсу студент навчиться наступного.

Встановлювати та використовувати бібліотеки Python.

Створювати телеграм бота та надсилати повідомлення в мессенджер.

Генерувати та працювати з випадковими числами.

Реагувати на події в telegram.

Обробляти зображення за допомогою Pillow.

Працювати з файловою системою та форматом json.

Реалізація.

Для возів робота є кілька бібліотек.

python-telegram-bot - має дещо складний синтаксис тому будемо використовувати pytelegramapi

Встановимо бібліотеку.

pip install pyTelegramBotAPI

Реєструємо бота.

Заходимо в клієнті на BotFather та набираємо ім’я та логін бота.

Створення бота.

import telebot
bot = telebot.TeleBot(key)

@bot.message_handler(commands=['start'])
def start_message(message):
    bot.send_message(message.chat.id, 'Привет, ты написал мне /start')

bot.polling()

ВВибираємо випадкові карти та рахуєм очки.

from os import listdir
from os.path import isfile, join
import random

def get_score(cards):
    score = 0
    for card in cards:
        num = int(card.split('-')[0])
        score += num
    return score

def get_random_cards():
    path = 'images'
    out = []
    onlyfiles = [f for f in listdir(path) if isfile(join(path, f))]
    for i in range(1,3):
        rand = random.randint(0,len(onlyfiles)-1)
        out.append(onlyfiles[rand])
        onlyfiles.pop(rand)
    return out

Надсилаємо картинки і скільки набрали.

cards = get_random_cards()
score = get_score(cards)
bot.send_message(message.chat.id, 'Вы набрали: %s!' % score)
for card in cards:
    bot.send_photo(chat_id=room_id, photo=open('images/%s' % card, 'rb'))

Робимо функцію для склеювання картинок в одну.

Встановлюємо інструмент

pip install Pillow

Визначаємо функцію

from PIL import Image
def combine_images(cards,name):
    images = []
    for image in cards:
        images.append(Image.open('images/%s' % image))
    new_im = Image.new('RGB', (210, 107))
    x_offset = 0
    for im in images:
        new_im.paste(im, (x_offset,0))
        x_offset += 70
new_im.save(name)

Використовуємо.

combine_images(cards,'player.png')
bot.send_photo(chat_id=room_id, photo=open('player.png', 'rb'))

Надсилаємо 2 кнопки.

@bot.message_handler(commands=['start'])
def start_message(message):
    user_cards = get_random_cards()
    markup = InlineKeyboardMarkup()
    markup.add(InlineKeyboardButton('Взять новую карту',callback_data='new'))
    markup.add(InlineKeyboardButton('Прекратить',callback_data='done'))
    bot.send_message(message.chat.id,'Вы набрали %s' % get_score(user_cards), reply_markup=markup)
    combine_images(user_cards,'tmp.jpg')
    bot.send_photo(chat_id=message.chat.id, photo=open('tmp.jpg','rb'))

Створюємо додатковий модуль bd.py для роботи з базою даних.

import json

def save_bd(data):
    with open('bd.json','w') as f:
        rowdata = json.dumps(data)
        f.write(rowdata)


def read_bd():
    with open('bd.json','r') as f:
        rowdata = f.read()
        data = json.loads(rowdata)
        return data

def add_cards(cards):
    data = read_bd()
    data['cards'] = cards
    save_bd(data)

Робимо обробники.

@bot.callback_query_handler(lambda payload: payload.data=='done')
def button_done(query):
    comp_cards = get_random_cards()
    comp_score = get_score(comp_cards)
    bot.send_message(query.message.chat.id,'Комп'ютер набрав %s' % comp_score)
    db = read_bd()
    user_score = get_score(db['cards'])
    print('%s<%s' % (user_score,comp_score) )
    if(user_score<comp_score):
        bot.send_message(query.message.chat.id,'Ви програли!')
    elif(user_score>comp_score):
        bot.send_message(query.message.chat.id,'Ви програли!')
    else:
        bot.send_message(query.message.chat.id,'Нічия!')


@bot.message_handler(commands=['start'])
def start_message(message):
    user_cards = get_random_cards()
    add_cards(user_cards)
    markup = InlineKeyboardMarkup()
    markup.add(InlineKeyboardButton('Взяти нову карту',callback_data='new'))
    markup.add(InlineKeyboardButton('Припинити',callback_data='done'))
    bot.send_message(message.chat.id,'Ви набрали %s' % get_score(user_cards), reply_markup=markup)
    combine_images(user_cards,'tmp.jpg')
    bot.send_photo(chat_id=message.chat.id, photo=open('tmp.jpg','rb'))