Gacha written in Python -BOX gacha-

Contents

Let's create a BOX gacha. The following sources will be used. (Gacha written in Python-Data design-)

What is BOX Gacha?

There are a fixed number of lottery tickets in the lottery box (BOX), and the gacha ends when ** all are drawn **. (Please note that the BOX gacha that automatically replenishes the lottery of the lower rarity is a fake. It will burn big)

Probability of BOX gacha

There is no weight setting for each item in the lottery. The probability of drawing one item is the probability of using the total number (n) in the BOX as a parameter.

  p = \frac{1}{n}

The probability after drawing one is as follows

  p = \frac{1}{n-1}

Implementation of BOX gacha

gacha_box.py


import random

#Use closures to keep the BOX state
def gacha_box(gacha_items: dict):
    #Extract ID
    #weight is not used
    items = [key for key in gacha_items.keys()]

    def lottery(times: int=1):
        #If the number of lottery is larger than the remaining number, match the remaining number
        if len(items) < times:
            times = len(items)
        #Non-overlapping lottery
        ids =  random.sample(items, k=times)
        #Delete the ID drawn from the item
        for key in ids:
            items.remove(key)
        return ids

    return lottery

def gacha(gacha_items: dict, times: int=1) -> list:
    #Create a dictionary of IDs and weights required for lottery
    lots = {key: info["weight"] for key, info in gacha_items.items()}
    return random.choices(tuple(lots), weights=lots.values(), k=times)

def main():
    #Gacha item information
    gacha_items = {
        1: {"weight": 1, "rarity": 5, "item_name": "UR_HOGE"},
        2: {"weight": 1, "rarity": 5, "item_name": "UR_FUGA"},
        3: {"weight": 9, "rarity": 4, "item_name": "SSR_HOGE"},
        4: {"weight": 9, "rarity": 4, "item_name": "SSR_FUGA"},
        5: {"weight": 20, "rarity": 3, "item_name": "SR_HOGE"},
        6: {"weight": 20, "rarity": 3, "item_name": "SR_FUGA"},
        7: {"weight": 30, "rarity": 2, "item_name": "R_HOGE"},
        8: {"weight": 30, "rarity": 2, "item_name": "R_FUGA"},
        9: {"weight": 40, "rarity": 1, "item_name": "N_HOGE"},
        10: {"weight": 40, "rarity": 1, "item_name": "N_FUGA"}
    }

    #Rarity name
    rarity_names = {5: "UR", 4: "SSR", 3: "SR", 2: "R", 1: "N"}

    #Number of lottery
    times = 10

    #Get a list of ids by lottery
    ids = gacha(gacha_items, times)

    #Result output
    print("Normal gacha")
    for id in ids:
        print("ID:%d, %s, %s" % (id, rarity_names[gacha_items[id]["rarity"]], gacha_items[id]["item_name"]))

    print("=======")
    #Store lottery function in func
    func = gacha_box(gacha_items)
    times = 3
    box_ids = func(times)
    print("BOX Gacha: 1st time,Number of lottery settings:%d,Number of lottery results:%d" %(times,len(box_ids)))
    for id in box_ids:
        print("ID:%d, %s, %s" % (id, rarity_names[gacha_items[id]["rarity"]], gacha_items[id]["item_name"]))

    times = 8
    box_ids = func(times)
    print("BOX Gacha: Second time,Number of lottery settings:%d,Number of lottery results:%d" %(times,len(box_ids)))
    for id in box_ids:
        print("ID:%d, %s, %s" % (id, rarity_names[gacha_items[id]["rarity"]], gacha_items[id]["item_name"]))

if __name__ == '__main__':
    main()

Execution result

Normal gacha
ID:9, N, N_HOGE
ID:4, SSR, SSR_FUGA
ID:3, SSR, SSR_HOGE
ID:10, N, N_FUGA
ID:9, N, N_HOGE
ID:4, SSR, SSR_FUGA
ID:7, R, R_HOGE
ID:5, SR, SR_HOGE
ID:9, N, N_HOGE
ID:9, N, N_HOGE
=======
BOX Gacha: 1st time,Number of lottery settings:3,Number of lottery results:3
ID:2, UR, UR_FUGA
ID:8, R, R_FUGA
ID:4, SSR, SSR_FUGA
BOX Gacha: Second time,Number of lottery settings:8,Number of lottery results:7
ID:6, SR, SR_FUGA
ID:1, UR, UR_HOGE
ID:5, SR, SR_HOGE
ID:9, N, N_HOGE
ID:10, N, N_FUGA
ID:3, SSR, SSR_HOGE
ID:7, R, R_HOGE

Consideration

The execution result of BOX gacha is different from normal gacha, and there is no duplication of ID throughout the first and second times. Also, in the second time, control is performed when the number of lottery settings and the number of lottery results are different, and you can see that the lottery is done within the remaining number in the BOX. Actually, the correct method is to check the remaining number in the BOX before executing the gacha and control it so that more gachas cannot be executed. It is a good idea to add a function to get the remaining number in BOX to the return value of gacha_box function.

#Use closures to keep the BOX state
def gacha_box(gacha_items: dict):
    #Extract ID
    #weight is not used
    items = [key for key in gacha_items.keys()]

    def lottery(times: int=1):
        #If the number of lottery is larger than the remaining number, match the remaining number
        if len(items) < times:
            times = len(items)
        #Non-overlapping lottery
        ids =  random.sample(items, k=times)
        #Delete the ID drawn from the item
        for key in ids:
            items.remove(key)
        return ids

    #Get the remaining number in the BOX
    def remain():
        return len(items)

    return lottery, remain
   func, remain = gacha_box(gacha_items)
   times = 10
   if remain() < times:
       print("BOX remaining number error")
       return False
   box_ids = func(times)

Recommended Posts

Gacha written in Python -BOX gacha-
Simple gacha logic written in Python
Gacha written in python-Practice 1-
Gacha written in Python-Data design-
Easy password box in Python
Squid Lisp written in Python: Hy
Compatibility diagnosis program written in python
Quadtree in Python --2
Python in optimization
CURL in python
Fourier series verification code written in Python
Metaprogramming in Python
Python 3.3 in Anaconda
Geocoding in python
SendKeys in Python
Stress Test with Locust written in Python
Meta-analysis in Python
Unittest in python
Markov chain transition probability written in Python
Epoch in Python
Sudoku in Python
DCI in Python
quicksort in python
nCr in python
N-Gram in Python
Gacha written in python-Rarity confirmed with bonus-
Programming in python
Plink in Python
Constant in python
Lifegame in Python.
FizzBuzz in Python
Sqlite in python
StepAIC in Python
N-gram in python
LINE-Bot [0] in Python
Csv in python
Disassemble in Python
Reflection in Python
Gacha written in python-Implementation in basic data structure-
Constant in python
Gacha written in python-Practice 2 ・ Basics of step-up gacha-
nCr in Python.
format in python
Scons in Python3
Puyo Puyo in python
python in virtualenv
PPAP in Python
Quad-tree in Python
Reflection in Python
Chemistry in Python
Hashable in python
DirectLiNGAM in Python
LiNGAM in Python
Flatten in python
flatten in python
Gacha written in python-Practice 3 ・ Addition of step-up gacha functions-
Gacha written in python-Addition of period setting function-
Introduction to Effectiveness Verification Chapter 2 Written in Python
Sorted list in Python
Daily AtCoder # 36 in Python
Clustering text in Python