Gacha written in python-Practice 2 ・ Basics of step-up gacha-

Contents

In the actual game, there are various types of gacha, This time, we will create a kind of step-up gacha.

** The following sources have been modified and implemented **

Gacha written in python-Practice 1-

What is a step-up gacha?

A step-up gacha is a gacha in which ** lottery target items ** and ** lottery settings ** change depending on the execution count of the target gacha. The reason for the name step up is that it is basically set to makebetter items more accessibleas the number of executions increases. After that, repeating the number of times will be expressed by the word step up.

Data structure of step-up gacha

First, decide what will change if you step up. This time, [previous](https://qiita.com/saib-ryo/items/cb792f90cc24259da7fa#%E3%82%AC%E3%83%81%E3%83%A3%E6%83%85%E5% A0% B1% E3% 83% 87% E3% 83% BC% E3% 82% BF% E6% A7% 8B% E9% 80% A0% E3% 81% AE% E5% A4% 89% E6% 9B% Based on the data structure of B4), we will make modifications so that the setting of how to draw gacha (** gacha_lottery **) will be stepped up.

To make the idea easier to understand, we will perform repairs in steps (steps).

Refurbishment step 1

First, add a setting called ** step_up ** as gacha_type.

gacha

id start_time end_time gacha_group gacha_type
1 2020-05-01 00:00:00 2020-05-31 23:59:59 A normal
6 2020-06-01 00:00:00 2020-06-30 23:59:59 C normal
10 2020-05-01 00:00:00 2020-05-31 23:59:59 A step_up

gacha_lottery

id gacha_type item_type times rarity omake_times omake_rarity cost
normal_1 normal 0 1 0 0 0 10
normal_11 normal 0 10 0 1 3 100
step_up step_up 0 1 0 0 0 10

Refurbishment step 2

Add the item ** step_no ** to ** gacha_lottery ** so that you can set ever by the number of step-ups, and set by step`.

gacha_lottery

id gacha_type step_no item_type times rarity omake_times omake_rarity cost
normal_1 normal 0 1 0 0 0 10
normal_11 normal 0 10 0 1 3 100
step_up_1 step_up 1 0 1 0 0 0 10
step_up_2 step_up 2 0 2 0 1 3 30
step_up_3 step_up 3 0 3 0 2 3 50
step_up_4 step_up 4 0 10 0 1 5 100

Repair step 3

For gachas with gacha_type of normal, step_no is set to ** 0 ** and there is no step-up setting.

gacha_lottery

id gacha_type step_no item_type times rarity omake_times omake_rarity cost
normal_1 normal 0 0 1 0 0 0 10
normal_11 normal 0 0 10 0 1 3 100
step_up_1 step_up 1 0 1 0 0 0 10
step_up_2 step_up 2 0 2 0 1 3 30
step_up_3 step_up 3 0 3 0 2 3 50
step_up_4 step_up 4 0 10 0 1 5 100

This step-up gacha will end when you have completed step 4 (no more can be executed).

図2.png

Creating gacha history

The state of the step-up gacha (probability, etc.) changes depending on the number of times the user has executed. In other words, `you need to record the number of times a user has executed the target gacha. ``

Therefore, create a place (table) where you can record the history of the number of gachas for each user and a process to record it.

User information (user)

id nick_name created_time
u001 taro 2020-05-31 23:59:59
u002 hana 2020-05-31 23:59:59

User gacha count history information (gacha_user_times)

user_id gacha_id gacha_type times updated_time
u001 10 step_up 1 2020-05-11 22:00:00
u002 10 step_up 2 2020-05-12 09:00:00

It is unique in multiple columns of user_id + gacha_id + gacha_type, and the number of times is incremented by +1 (update) each time it is executed. In the case of the first (first) execution, the number of times is set to 1 and a record is created (insert).

Implementation

The implementation specifications are summarized below.

--Difference in behavior of step-up gacha (for normal gacha) -Record the number history in ** gacha_user_times ** --Gacha_lottery of executable steps is extracted for the same ** gacha_type ** ――Every time you execute it, steps will progress one by one --When you execute up to step 4, it will be finished (no more execution)

-[Addition]: Newly added part -[Repair]: Repaired part

Gacha DB information

If you want to change the structure / data or reset the history, please re-execute this process.

gacha_db.py


# -*- coding: utf-8 -*-
import sqlite3
import random

def get_items():
    items = {
        5101: {"rarity": 5, "item_name": "UR_Brave", "item_type": 1, "hp": 1200},
        4201: {"rarity": 4, "item_name": "SSR_Warrior", "item_type": 2, "hp": 1000},
        4301: {"rarity": 4, "item_name": "SSR_Wizard", "item_type": 3, "hp": 800},
        4401: {"rarity": 4, "item_name": "SSR_Priest", "item_type": 4, "hp": 800},
        3201: {"rarity": 3, "item_name": "SR_Warrior", "item_type": 2, "hp": 600},
        3301: {"rarity": 3, "item_name": "SR_Wizard", "item_type": 3, "hp": 500},
        3401: {"rarity": 3, "item_name": "SR_Priest", "item_type": 4, "hp": 500},
        2201: {"rarity": 2, "item_name": "R_Warrior", "item_type": 2, "hp": 400},
        2301: {"rarity": 2, "item_name": "R_Wizard", "item_type": 3, "hp": 300},
        2401: {"rarity": 2, "item_name": "R_Priest", "item_type": 4, "hp": 300},
        3199: {"rarity": 3, "item_name": "SR_Brave", "item_type": 1, "hp": 600},
        4101: {"rarity": 4, "item_name": "SSR_Brave", "item_type": 1, "hp": 1000},
        5201: {"rarity": 5, "item_name": "UR_Warrior", "item_type": 2, "hp": 1300},
        5301: {"rarity": 5, "item_name": "UR_Wizard", "item_type": 3, "hp": 1000},
    }

    return convert_values(items)

def get_gacha_items():
    items = {
        1:  {"gacha_group": "A", "weight": 3, "item_id": 5101},
        2:  {"gacha_group": "A", "weight": 9, "item_id": 4201},
        3:  {"gacha_group": "A", "weight": 9, "item_id": 4301},
        4:  {"gacha_group": "A", "weight": 9, "item_id": 4401},
        5:  {"gacha_group": "A", "weight": 20, "item_id": 3201},
        6:  {"gacha_group": "A", "weight": 20, "item_id": 3301},
        7:  {"gacha_group": "A", "weight": 20, "item_id": 3401},
        8:  {"gacha_group": "A", "weight": 40, "item_id": 2201},
        9:  {"gacha_group": "A", "weight": 40, "item_id": 2301},
        10: {"gacha_group": "A", "weight": 40, "item_id": 2401},
        11: {"gacha_group": "B", "weight": 15, "item_id": 4201},
        12: {"gacha_group": "B", "weight": 30, "item_id": 3201},
        13: {"gacha_group": "B", "weight": 55, "item_id": 2201},
        14: {"gacha_group": "C", "weight": 1, "item_id": 5101},
        15: {"gacha_group": "C", "weight": 1, "item_id": 5201},
        16: {"gacha_group": "C", "weight": 1, "item_id": 5301},
        17: {"gacha_group": "C", "weight": 9, "item_id": 4101},
        18: {"gacha_group": "C", "weight": 6, "item_id": 4201},
        19: {"gacha_group": "C", "weight": 6, "item_id": 4301},
        20: {"gacha_group": "C", "weight": 6, "item_id": 4401},
        21: {"gacha_group": "C", "weight": 20, "item_id": 3201},
        22: {"gacha_group": "C", "weight": 20, "item_id": 3301},
        23: {"gacha_group": "C", "weight": 20, "item_id": 3401},
        24: {"gacha_group": "C", "weight": 40, "item_id": 2201},
        25: {"gacha_group": "C", "weight": 40, "item_id": 2301},
        26: {"gacha_group": "C", "weight": 40, "item_id": 2401},
    }

    return convert_values(items)

def get_gacha():
    items = {
        1: {"start_time": "2020-05-01 00:00:00", "end_time": "2020-05-31 23:59:59", "gacha_group": "A",
            "gacha_type": "normal"},
        3: {"start_time": "2020-05-25 00:00:00", "end_time": "2020-05-31 23:59:59", "gacha_group": "B",
            "gacha_type": "fighter"},
        4: {"start_time": "2020-06-01 00:00:00", "end_time": "2020-06-04 23:59:59", "gacha_group": "C",
            "gacha_type": "omake_2"},
        5: {"start_time": "2020-05-20 00:00:00", "end_time": "2020-05-31 23:59:59", "gacha_group": "A",
            "gacha_type": "omake_fighter"},
        6: {"start_time": "2020-06-01 00:00:00", "end_time": "2020-06-30 23:59:59", "gacha_group": "C",
            "gacha_type": "normal"},
        10: {"start_time": "2020-05-01 00:00:00", "end_time": "2020-05-31 23:59:59", "gacha_group": "A",
            "gacha_type": "step_up"},
    }

    return convert_values(items)

#【Refurbishment】
def get_gacha_lottery():
    items = {
        "normal_1":  {"gacha_type": "normal", "step_no": 0, "item_type": 0, "times": 1, "rarity": 0, "omake_times": 0, "omake_rarity": 0, "cost":10},
        "normal_11":  {"gacha_type": "normal", "step_no": 0, "item_type": 0, "times": 10, "rarity": 0, "omake_times": 1, "omake_rarity": 3, "cost":100},
        "fighter":  {"gacha_type": "fighter", "step_no": 0, "item_type": 0, "times": 2, "rarity": 0, "omake_times": 0, "omake_rarity": 0, "cost":30},
        "omake_2":  {"gacha_type": "omake_2", "step_no": 0, "item_type": 0, "times": 9, "rarity": 2, "omake_times": 2, "omake_rarity": 3, "cost":150},
        "omake_fighter":  {"gacha_type": "omake_fighter", "step_no": 0, "item_type": 2, "times": 5, "rarity": 0, "omake_times": 1, "omake_rarity": 3, "cost":100},
        "step_up_1": {"gacha_type": "step_up", "step_no": 1, "item_type": 0, "times": 1, "rarity": 0, "omake_times": 0,
                     "omake_rarity": 0, "cost": 10},
        "step_up_2": {"gacha_type": "step_up", "step_no": 2, "item_type": 0, "times": 2, "rarity": 0, "omake_times": 1,
                      "omake_rarity": 3, "cost": 30},
        "step_up_3": {"gacha_type": "step_up", "step_no": 3, "item_type": 0, "times": 3, "rarity": 0, "omake_times": 2,
                      "omake_rarity": 3, "cost": 50},
        "step_up_4": {"gacha_type": "step_up", "step_no": 4, "item_type": 0, "times": 10, "rarity": 0, "omake_times": 1,
                      "omake_rarity": 5, "cost": 100},
    }

    return convert_values(items)

#【add to】
def get_users():
    items = {
        "u001": {"nick_name": "taro"},
        "u002": {"nick_name": "hana"},
    }

    return convert_values(items)


def convert_values(items: dict):
    values = []
    keys = []
    for id,info in items.items():
        if len(keys) == 0 :
            keys = list(info.keys())
            keys.insert(0,'id')

        value = list(info.values())
        value.insert(0,id)
        values.append(tuple(value))
    return keys,values

def print_rows(rows, keys: list):
    for row in rows:
        result = []
        for key in keys:
            result.append(str(row[key]))
        print(",".join(result))


def main():
    con = sqlite3.connect("data.db")
    con.row_factory = sqlite3.Row
    cursor = con.cursor()

    cursor.execute("DROP TABLE IF EXISTS gacha")

    cursor.execute(
        """CREATE TABLE gacha 
          (id INTEGER PRIMARY KEY AUTOINCREMENT
          ,start_time DATETIME
          ,end_time DATETIME
          ,gacha_group VARCHAR(32)
          ,gacha_type VARCHAR(32)
          )
        """
    )

    cursor.execute("DROP TABLE IF EXISTS gacha_items")
    cursor.execute(
        """CREATE TABLE gacha_items 
          (id INTEGER PRIMARY KEY AUTOINCREMENT
          ,gacha_group VARCHAR(32)
          ,weight INTEGER
          ,item_id INTEGER
          )
        """
    )

    #【Refurbishment】
    cursor.execute("DROP TABLE IF EXISTS gacha_lottery")
    cursor.execute(
        """CREATE TABLE gacha_lottery 
          (id VARCHAR(32) PRIMARY KEY
          ,gacha_type VARCHAR(32)
          ,step_no INTEGER
          ,item_type INTEGER
          ,times INTEGER
          ,rarity INTEGER
          ,omake_times INTEGER
          ,omake_rarity INTEGER
          ,cost INTEGER
          )
        """
    )

    cursor.execute("DROP TABLE IF EXISTS items")
    cursor.execute(
        """CREATE TABLE items 
          (id INTEGER PRIMARY KEY AUTOINCREMENT
          ,rarity INTEGER
          ,item_name VARCHAR(64)
          ,item_type INTEGER
          ,hp INTEGER
          )
        """
    )

    #【add to】
    cursor.execute("DROP TABLE IF EXISTS users")
    cursor.execute(
        """CREATE TABLE users 
          (id VARCHAR(16) PRIMARY KEY
          ,nick_name VARCHAR(64)
          )
        """
    )

    #【add to】
    cursor.execute("DROP TABLE IF EXISTS gacha_user_times")
    cursor.execute(
        """CREATE TABLE gacha_user_times 
          (user_id VARCHAR(16) 
          ,gacha_id INTEGER
          ,gacha_type VARCHAR(32)
          ,times INTEGER
          ,updated_time DATETIME          
          ,PRIMARY KEY(user_id,gacha_id,gacha_type)
          )
        """
    )


    keys, values = get_items()
    sql = "insert into {0}({1}) values({2})".format('items', ','.join(keys), ','.join(['?'] * len(keys)))
    cursor.executemany(sql,values)
    select_sql = "SELECT * FROM items ORDER BY id"
    result = cursor.execute(select_sql)
    print("===items===")
    print_rows(result, keys)

    keys, values = get_gacha_items()
    sql = "insert into {0}({1}) values({2})".format('gacha_items', ','.join(keys), ','.join(['?'] * len(keys)))
    cursor.executemany(sql,values)
    select_sql = "SELECT * FROM gacha_items ORDER BY id"
    result = cursor.execute(select_sql)
    print("===gacha_items===")
    print_rows(result, keys)


    keys, values = get_gacha()
    sql = "insert into {0}({1}) values({2})".format('gacha', ','.join(keys), ','.join(['?'] * len(keys)))
    cursor.executemany(sql,values)
    select_sql = "SELECT * FROM gacha ORDER BY id"
    result = cursor.execute(select_sql)
    print("===gacha===")
    print_rows(result, keys)

    keys, values = get_gacha_lottery()
    sql = "insert into {0}({1}) values({2})".format('gacha_lottery', ','.join(keys), ','.join(['?'] * len(keys)))
    cursor.executemany(sql,values)
    select_sql = "SELECT * FROM gacha_lottery ORDER BY id"
    result = cursor.execute(select_sql)
    print("===gacha_lottery===")
    print_rows(result, keys)

    #【add to】
    keys, values = get_users()
    sql = "insert into {0}({1}) values({2})".format('users', ','.join(keys), ','.join(['?'] * len(keys)))
    cursor.executemany(sql,values)
    select_sql = "SELECT * FROM users ORDER BY id"
    result = cursor.execute(select_sql)
    print("===users===")
    print_rows(result, keys)

    con.commit()
    con.close()

if __name__ == '__main__':
    main()

Gacha processing

gacha.py


import random
import sqlite3
from datetime import datetime

def convert_row2dict(row) -> dict:
    if row is None:
        return {}
    keys = row.keys()
    return {key: row[key] for key in keys}

def gacha(lots, times: int=1) -> list:
    return random.choices(tuple(lots), weights=lots.values(), k=times)

def get_rarity_name(rarity: int) -> str:
    rarity_names = {5: "UR", 4: "SSR", 3: "SR", 2: "R", 1: "N"}
    return rarity_names[rarity]

#Executable gacha information list
def get_gacha_list(cursor, now_time: int) -> dict:
    select_sql = "SELECT * FROM gacha ORDER BY id"
    rows = cursor.execute(select_sql)
    results = {}
    for row in rows:
        start_time = int(datetime.strptime(row["start_time"], '%Y-%m-%d %H:%M:%S').timestamp())
        end_time = int(datetime.strptime(row["end_time"], '%Y-%m-%d %H:%M:%S').timestamp())
        #Narrow down the target gacha information within the range of the date and time
        if start_time <= now_time <= end_time:
            results[row["id"]] = convert_row2dict(row)

    return results

#【Refurbishment】
#Executable gacha information list (gacha_(Including lottery information)
def get_available_gacha_info_list(cursor, now_time: int, user_id:str) -> dict:
    gacha_list = get_gacha_list(cursor, now_time)
    for gacha_id, info in gacha_list.items():
        lottery_info_list = get_gacha_lottery_by_type(cursor, info["gacha_type"])
        gacha_user = get_gacha_user_times(cursor, user_id, gacha_id, info["gacha_type"])

        set_list = []
        for lottery_info in lottery_info_list:
            if lottery_info["step_no"] > 0:
                now_step_no = 1
                if len(gacha_user) > 0:
                    now_step_no = gacha_user["times"] + 1
                if now_step_no == lottery_info["step_no"]:
                    set_list.append(lottery_info)
            else:
                set_list.append(lottery_info)
        gacha_list[gacha_id]["gacha_lottery_list"] = set_list
    return gacha_list

def get_gacha(cursor, gacha_id: int, now_time: int) -> dict:
    select_sql = "SELECT * FROM gacha WHERE id = ? ORDER BY id"
    cursor.execute(select_sql, (gacha_id,))
    row = cursor.fetchone()
    start_time = int(datetime.strptime(row["start_time"], '%Y-%m-%d %H:%M:%S').timestamp())
    end_time = int(datetime.strptime(row["end_time"], '%Y-%m-%d %H:%M:%S').timestamp())
    #Narrow down the target gacha information within the range of the date and time
    if start_time <= now_time <= end_time:
        return convert_row2dict(row)

    return {}


def get_gacha_lottery(cursor, gacha_lottery_id: str) -> dict:
    select_sql = "SELECT * FROM gacha_lottery WHERE id = ? ORDER BY id"
    cursor.execute(select_sql, (gacha_lottery_id,))
    row = cursor.fetchone()
    return convert_row2dict(row)


def get_gacha_lottery_by_type(cursor, gacha_type: str) -> list:
    select_sql = "SELECT * FROM gacha_lottery WHERE gacha_type = ? ORDER BY id"
    rows = cursor.execute(select_sql, (gacha_type,))

    results = []
    for row in rows:
        row_dict = convert_row2dict(row)
        results.append(row_dict)
    return results


def get_items_all(cursor) -> dict:
    select_sql = "SELECT * FROM items ORDER BY id"
    rows = cursor.execute(select_sql)
    results = {}
    for row in rows:
        row_dict = convert_row2dict(row)
        results[row["id"]] = row_dict
    return results


def get_gacha_items(cursor, gacha_group: str) -> dict:
    select_sql = "SELECT * FROM gacha_items WHERE gacha_group = ? ORDER BY id"
    rows = cursor.execute(select_sql, (gacha_group,))
    results = {}
    for row in rows:
        row_dict = convert_row2dict(row)
        results[row["id"]] = row_dict
    return results


def get_gacha_items_all(cursor) -> dict:
    select_sql = "SELECT * FROM gacha_items ORDER BY id"
    rows = cursor.execute(select_sql)
    results = {}
    for row in rows:
        row_dict = convert_row2dict(row)
        results[row["id"]] = row_dict
    return results


#【Refurbishment】
def get_gacha_info(cursor, gacha_id: int, gacha_lottery_id: str, now_time: int, user_id: str):
    gacha = get_gacha(cursor, gacha_id, now_time)
    gacha_lottery = get_gacha_lottery(cursor, gacha_lottery_id)

    if len(gacha) == 0:
        print("===Gacha that cannot be executed_id:%s===" % (gacha_id))
        return None, None

    if len(gacha_lottery) == 0:
        print("===Gacha that does not exist_lottery_id:%s===" % (gacha_lottery_id))
        return None, None

    if gacha["gacha_type"] != gacha_lottery["gacha_type"]:
        print("===gacha_type is different:%s,%s===" % (gacha["gacha_type"],gacha_lottery["gacha_type"]))
        return None, None

    # step_up Gacha check
    if gacha_lottery["step_no"] > 0:
        max_step_no = get_max_step_no(cursor, gacha["gacha_type"])
        gacha_user = get_gacha_user_times(cursor, user_id, gacha_id, gacha["gacha_type"])
        step_no = 1
        if len(gacha_user) > 0:
            step_no = gacha_user["times"] + 1
        if max_step_no < step_no:
            print("===Up to the maximum step has been executed (maximum step):%s, the step you are going to perform:%s)===" %(max_step_no,gacha_lottery["step_no"]))
            return None, None

        if gacha_lottery["step_no"] != step_no:
            print("===Different from the steps that can be performed (current step:%s, the step you are going to perform:%s)===" %(step_no, gacha_lottery["step_no"]))
            return None, None

    return gacha, gacha_lottery


#【add to】
def get_gacha_user_times(cursor, user_id: str, gacha_id: int, gacha_type: str) -> dict:
    select_sql = "SELECT * FROM gacha_user_times WHERE user_id = ? AND gacha_id = ? AND gacha_type = ?"
    cursor.execute(select_sql, (user_id,gacha_id,gacha_type))
    row = cursor.fetchone()

    return convert_row2dict(row)


#【add to】
def get_max_step_no(cursor, gacha_type: str) -> dict:
    select_sql = "SELECT MAX(step_no) AS max_step_no FROM gacha_lottery WHERE gacha_type = ?"
    cursor.execute(select_sql, (gacha_type,))
    row = cursor.fetchone()

    row_dict = convert_row2dict(row)
    return row_dict["max_step_no"]


#【add to】
def update_gacha_user_times(cursor, user_id: str, gacha_id: int, gacha_type: str, update_time: int):
    row = get_gacha_user_times(cursor, user_id, gacha_id, gacha_type)
    dt = datetime.fromtimestamp(update_time)
    if len(row) == 0:
        keys = ("user_id","gacha_id","gacha_type","times","updated_time")
        sql = "insert into {0}({1}) values({2})".format('gacha_user_times', ','.join(keys), ','.join(['?'] * len(keys)))
        cursor.execute(sql, (user_id,gacha_id,gacha_type,1,dt))
    else:
        sql = "UPDATE gacha_user_times SET times = times + 1, updated_time = ? WHERE user_id = ? AND gacha_id = ? AND gacha_type = ?"
        cursor.execute(sql, (dt,user_id,gacha_id,gacha_type))


#【Refurbishment】
def set_gacha(cursor, now_time: int, user_id:str):
    cursor = cursor
    now_time = now_time
    user_id = user_id
    items = get_items_all(cursor)

    #Extract the lottery target list
    def get_lots(gacha_group: str, lottery_info: dict):
        gacha_items = get_gacha_items(cursor, gacha_group)
        dic_gacha_items = {}
        for gacha_item_id, gacha_item in gacha_items.items():
            gacha_item["item_info"] = items[gacha_item["item_id"]]
            dic_gacha_items[gacha_item_id] = gacha_item

        lots = {}
        omake_lots = {}
        for id, info in dic_gacha_items.items():
            if lottery_info["item_type"] and lottery_info["item_type"] != info["item_info"]["item_type"]:
                continue

            if not(lottery_info["rarity"]) or lottery_info["rarity"] <= info["item_info"]["rarity"]:
                lots[id] = info["weight"]

            if lottery_info["omake_times"]:
                if not(lottery_info["omake_rarity"]) or lottery_info["omake_rarity"] <= info["item_info"]["rarity"]:
                    omake_lots[id] = info["weight"]

        return lots, omake_lots

    #Gacha execution
    def exec(exec_gacha_id: int, exec_gacha_lottery_id: str) -> list:
        gacha_info, gacha_lottery_info = get_gacha_info(cursor, exec_gacha_id, exec_gacha_lottery_id, now_time, user_id)
        if gacha_info is None or gacha_lottery_info is None:
            return []

        print("==%s==:gacha_group:%s" % (gacha_lottery_info["id"], gacha_info["gacha_group"]))
        lots, omake_lots = get_lots(gacha_info["gacha_group"], gacha_lottery_info)
        ids = gacha(lots, gacha_lottery_info["times"])
        if len(omake_lots) > 0:
            ids.extend(gacha(omake_lots, gacha_lottery_info["omake_times"]))

        #In the case of step-up gacha, update the number of executions
        if len(ids) > 0 and gacha_lottery_info["step_no"] > 0:
            update_gacha_user_times(cursor, user_id, exec_gacha_id, gacha_info["gacha_type"], now_time)

        return ids

    return exec


def main():
    con = sqlite3.connect("data.db")
    con.row_factory = sqlite3.Row
    cursor = con.cursor()

    #【add to】
    #Actually, the user ID will be obtained from the authentication information.
    user_id = "u001"

    #Specify the gacha execution date and time to check the operation
    now_time = int(datetime.strptime("2020-05-01 00:00:00", '%Y-%m-%d %H:%M:%S').timestamp())

    #【add to】
    #Feasible gacha_lottery
    available_list = get_available_gacha_info_list(cursor,now_time,user_id)
    for gacha_id,available in available_list.items():
        print(gacha_id,available)

    #Initialization (set execution date and time, items, etc.)
    func_gacha = set_gacha(cursor, now_time, user_id)


    items = get_items_all(cursor)
    gacha_items = get_gacha_items_all(cursor)
    #Execute one-shot gacha
    # gacha_id and gacha_lottery_id passed at runtime
    ids = func_gacha(1,"normal_1")
    for id in ids:
        item_info = items[gacha_items[id]["item_id"]]
        print("ID:%d, %s, %s" % (id, get_rarity_name(item_info["rarity"]), item_info["item_name"]))

    #Execute 11 consecutive gachas
    # gacha_id and gacha_lottery_id passed at runtime
    ids = func_gacha(1,"normal_11")
    for id in ids:
        item_info = items[gacha_items[id]["item_id"]]
        print("ID:%d, %s, %s" % (id, get_rarity_name(item_info["rarity"]), item_info["item_name"]))

    #【add to】
    #Step-up gacha
    for i in [1, 2, 3, 4, 5]:
        gacha_lottery_id = "step_up_{0}".format(str(i))
        ids = func_gacha(10,gacha_lottery_id)
        if len(ids) > 0:
            for id in ids:
                item_info = items[gacha_items[id]["item_id"]]
                print("ID:%d, %s, %s" % (id, get_rarity_name(item_info["rarity"]), item_info["item_name"]))

    #【add to】
    con.commit()


    con.close()


if __name__ == '__main__':
    main()

Execution result

1st time

1 {'id': 1, 'start_time': '2020-05-01 00:00:00', 'end_time': '2020-05-31 23:59:59', 'gacha_group': 'A', 'gacha_type': 'normal', 'gacha_lottery_list': [{'id': 'normal_1', 'gacha_type': 'normal', 'step_no': 0, 'item_type': 0, 'times': 1, 'rarity': 0, 'omake_times': 0, 'omake_rarity': 0, 'cost': 10}, {'id': 'normal_11', 'gacha_type': 'normal', 'step_no': 0, 'item_type': 0, 'times': 10, 'rarity': 0, 'omake_times': 1, 'omake_rarity': 3, 'cost': 100}]}
10 {'id': 10, 'start_time': '2020-05-01 00:00:00', 'end_time': '2020-05-31 23:59:59', 'gacha_group': 'A', 'gacha_type': 'step_up', 'gacha_lottery_list': [{'id': 'step_up_1', 'gacha_type': 'step_up', 'step_no': 1, 'item_type': 0, 'times': 1, 'rarity': 0, 'omake_times': 0, 'omake_rarity': 0, 'cost': 10}]}
==normal_1==:gacha_group:A
ID:9, R, R_Wizard
==normal_11==:gacha_group:A
ID:1, UR, UR_Brave
ID:10, R, R_Priest
ID:9, R, R_Wizard
ID:5, SR, SR_Warrior
ID:5, SR, SR_Warrior
ID:8, R, R_Warrior
ID:9, R, R_Wizard
ID:10, R, R_Priest
ID:10, R, R_Priest
ID:9, R, R_Wizard
ID:5, SR, SR_Warrior
==step_up_1==:gacha_group:A
ID:2, SSR, SSR_Warrior
==step_up_2==:gacha_group:A
ID:9, R, R_Wizard
ID:4, SSR, SSR_Priest
ID:3, SSR, SSR_Wizard
==step_up_3==:gacha_group:A
ID:9, R, R_Wizard
ID:2, SSR, SSR_Warrior
ID:2, SSR, SSR_Warrior
ID:3, SSR, SSR_Wizard
ID:7, SR, SR_Priest
==step_up_4==:gacha_group:A
ID:9, R, R_Wizard
ID:10, R, R_Priest
ID:6, SR, SR_Wizard
ID:9, R, R_Wizard
ID:2, SSR, SSR_Warrior
ID:7, SR, SR_Priest
ID:10, R, R_Priest
ID:8, R, R_Warrior
ID:10, R, R_Priest
ID:7, SR, SR_Priest
ID:1, UR, UR_Brave
===Gacha that does not exist_lottery_id:step_up_5===

Second time

1 {'id': 1, 'start_time': '2020-05-01 00:00:00', 'end_time': '2020-05-31 23:59:59', 'gacha_group': 'A', 'gacha_type': 'normal', 'gacha_lottery_list': [{'id': 'normal_1', 'gacha_type': 'normal', 'step_no': 0, 'item_type': 0, 'times': 1, 'rarity': 0, 'omake_times': 0, 'omake_rarity': 0, 'cost': 10}, {'id': 'normal_11', 'gacha_type': 'normal', 'step_no': 0, 'item_type': 0, 'times': 10, 'rarity': 0, 'omake_times': 1, 'omake_rarity': 3, 'cost': 100}]}
10 {'id': 10, 'start_time': '2020-05-01 00:00:00', 'end_time': '2020-05-31 23:59:59', 'gacha_group': 'A', 'gacha_type': 'step_up', 'gacha_lottery_list': []}
==normal_1==:gacha_group:A
ID:7, SR, SR_Priest
==normal_11==:gacha_group:A
ID:9, R, R_Wizard
ID:4, SSR, SSR_Priest
ID:2, SSR, SSR_Warrior
ID:8, R, R_Warrior
ID:8, R, R_Warrior
ID:5, SR, SR_Warrior
ID:10, R, R_Priest
ID:7, SR, SR_Priest
ID:10, R, R_Priest
ID:7, SR, SR_Priest
ID:5, SR, SR_Warrior
===Up to the maximum step has been executed (maximum step):4, the step you are going to perform:1)===
===Up to the maximum step has been executed (maximum step):4, the step you are going to perform:2)===
===Up to the maximum step has been executed (maximum step):4, the step you are going to perform:3)===
===Up to the maximum step has been executed (maximum step):4, the step you are going to perform:4)===
===Gacha that does not exist_lottery_id:step_up_5===

Consideration

The first time, steps 1 to 4 are executed. Also, you can see that the how to draw the gacha changes according to the step, and you are stepping up. Since the result of the first execution is recorded (commit) for the second time, you can see that the step-up gacha has ended without being able to execute. Depending on the state of the number of steps at the time of execution, an error message is displayed according to it, so if you edit the calling method and try the process, you can feel the change in behavior.

The one created this time is only an implementation of basic processing for the purpose of understanding the mechanism of step-up gacha, and does not implement complicated control. By observing the behavior of step-up gachas in various games and thinking about what kind of control is lacking, you can see what you can do by applying step-up gachas.

Recommended Posts

Gacha written in python-Practice 2 ・ Basics of step-up gacha-
Gacha written in python-Practice 3 ・ Addition of step-up gacha functions-
Gacha written in python-Practice 1-
Gacha written in python-Addition of period setting function-
Gacha written in Python-Data design-
Gacha written in Python -BOX gacha-
Simple gacha logic written in Python
Gacha written in python-Rarity confirmed with bonus-
The basics of running NoxPlayer in Python
Gacha written in python-Implementation in basic data structure-
Simple simulation of virus infection
Simulation of the contents of the wallet
A complete understanding of Python's asynchronous programming
A complete understanding of Python's object-oriented programming
Complete everything with Jupyter ~ Introduction of nbdev ~
Gacha written in python-Practice 2 ・ Basics of step-up gacha-
Basics of Python ①
Basics of python ①
Basics of I / O screen using tkinter in python3
Basics of Python scraping basics
# 4 [python] Basics of functions
Basics of network programs?
Basics of Perceptron Foundation
Basics of regression analysis
Basics of python: Output
Comparison of exponential moving average (EMA) code written in Python
What beginners learned from the basics of variables in python