Distribution totale automatique du deck JCG avec Python

introduction

** * Cet article est destiné à ceux qui ont de l'expérience en programmation avec Python. ** **

De plus, les connaissances suivantes sont supposées. ・ Grammaire de base de Python ・ Visualisation des données par matplotlib

Objectif

La liste des cartes est obtenue à partir du site JCG et la distribution des classes, la distribution des archétypes sont agrégées et représentées automatiquement.

approche

Sur le site JCG, les informations sur les inscrits telles que les informations sur les gagnants du tournoi, l'état de l'enregistrement, le deck d'inscription, etc. sont résumées dans un fichier texte au format JSON. Obtenez la liste des cartes à partir de ce fichier JSON et triez les types de cartes à partir de la composition des nombres.

Qu'est-ce que JSON

JSON (JavaScript Object Notation) est une notation pour exprimer des données structurées. Imaginez qu'il représente une structure hiérarchique entre les textes, comme une structure hiérarchique de répertoires. Par exemple, dans le fichier JCG JSON, les données du registrant sont décrites dans le format suivant.

example.json


{
	"result": "success",
	"participants": [
		{
			"id": "42155", 
			"chk": 1, #Statut d'enregistrement
			"nm":  "somey", #Nom enregistré
			"dk": [ #Informations sur le pont
				{
					"cl": 3, #Classe 1
					"hs": "3.3.6so2A.6so2A.5-gkQ.5-gkQ.5-gkQ.6_X7Q.6_X7Q.6_X7Q.6_djc.6_djc.6_djc.6turQ.6turQ.6turQ.6xnsw.6xnsw.6xnsw.6_ZZg.6_ZZg.6_ZZg.gHqNk.gHqNk.gHqNk.6ty_2.6ty_2.6ty_2.6q8sC.6q8sC.6q8sC.6twYy.6twYy.6twYy.6xpaI.6xpaI.5-glM.5-glM.5-glM.6t_RI.6t_RI.6t_RI"
				}, #Liste des cartes Deck 1 (pour être exact, une partie de l'URL du portail)
				{
					"cl": 8, #Classe 2
					"hs": "3.8.71TeA.71TeA.71TeA.6zemS.6zemS.6zemS.71QTC.71QTC.71QTC.6zd2w.6zd2w.6zd2w.6s2wi.6zcK2.6zcK2.6zcK2.6s65g.6zcKC.6zcKC.6zcKC.6s5My.6s5My.6s5My.6zhCY.6zhxQ.6zhxQ.6zhxQ.6-UTo.6-UTo.71Xo6.71Xo6.71Xo6.6oEnY.6oEnY.6oEnY.6oHDo.6oHDo.6vvW6.6vvW6.6vvW6"
				} #Liste des cartes Deck 2 (pour être exact, une partie de l'URL du portail)
			],
			"en": 1527921725,
			"te": 1, #Information gagnante
			"pr": 1,
			"cu": 0
		},

Acquisition des informations de pont

Les informations sur le deck sont stockées dans la partie clé "hs" du fichier JSON.

Par exemple, dans le fichier JSON ci-dessus

6so2A.6so2A.5-gkQ.5-gkQ.5-gkQ.6_X7Q.6_X7Q.6_X7Q.6_djc.6_djc.6_djc.6turQ.6turQ.6turQ.6xnsw.6xnsw.6xnsw.6_ZZg.6_ZZg.6_ZZg.gHqNk.gHqNk.gHqNk.6ty_2.6ty_2.6ty_2.6q8sC.6q8sC.6q8sC.6twYy.6twYy.6twYy.6xpaI.6xpaI.5-glM.5-glM.5-glM.6t_RI.6t_RI.6t_RI


 Est-ce que les informations sur le pont.

 Les caractères alphanumériques à cinq chiffres (tels que `` 6so2A '') séparés par des points représentent une carte, et 40 d'entre eux représentent un jeu.
 Vérifiez le portail Shadowverse pour la correspondance entre ces caractères alphanumériques et le nom de la carte.
 Si vous regardez de plus près l'URL du portail, vous verrez qu'elle est composée de 40 caractères alphanumériques, similaires à un fichier JSON.

 (Exemple: Spell witch)
https://shadowverse-portal.com/deckbuilder/create/3?hash=3.3.6so2A.6so2A.5-gkQ.5-gkQ.5-gkQ.6_X7Q.6_X7Q.6_X7Q.6_djc.6_djc.6_djc.6turQ.6turQ.6turQ.6xnsw.6xnsw.6xnsw.6_ZZg.6_ZZg.6_ZZg.gHqNk.gHqNk.gHqNk.6ty_2.6ty_2.6ty_2.6q8sC.6q8sC.6q8sC.6twYy.6twYy.6twYy.6xpaI.6xpaI.5-glM.5-glM.5-glM.6t_RI.6t_RI.6t_RI&lang=ja

 Par exemple, trois caractères alphanumériques `` `` 6t_RI``` apparaissent dans une rangée à la fin, ce qui signifie que trois "fondateurs Yin et Yang, Kuon" sont inclus.

### Classification Architype

 Créez une formule de jugement pour classer les archétypes en utilisant des informations sur le type et le nombre de cartes incluses dans le jeu.
 Pour la formule de jugement, utilisez une carte qui peut identifier de manière unique l'archétype autant que possible.

 Exemple: `` 6q95g '' (magasin spécialisé d'outils magiques) est inclus 3 fois → magasin spécialisé sorcière

### Procédure d'analyse
 1. Demandez un fichier json
 (Ci-après, analyse du fichier json)
 2. Confirmation des informations gagnantes (passez à 3 si un participant gagnant est trouvé)
 3. Obtenez la liste des cartes
 4. Classification Architype (Si ✕✕ est ○ ou plus, □□ elfe, etc.)
 5. Répétez les étapes 2 à 4
 6. Une fois la classification par archétype de tous les participants terminée, agréger et représenter graphiquement

### Un exemple de résultats d'agrégation

 ** JCG Shadowverse Open 14th Season Vol.29 22 août Rotation Tournament Group Qualifying **

 ** Répartition des classes **
 <img width="480" alt="class_pie_2328.png " src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693609/00e0c41e-4f70-ed10-627e-105cd08fa0f1.png ">
 ** Distribution des archétypes **
 <img width="480" alt="class_bar_2328.png " src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693609/14f786cb-6953-989a-89cf-5bbaa30cc21d.png ">

# codage
 * Parce que vous êtes autodidacte en programmation, vous ne pouvez pas suivre le code ou les coutumes redondants.
 Veuillez conserver les exemples de codage ci-dessous pour référence seulement.
### Importer la bibliothèque
 Importez d'abord les bibliothèques requises.


#### **`import.py`**
```python

import requests
import json

Définition du compteur

Définit les variables utilisées pour agréger le nombre de classes et d'archétypes. Il définit également une variable de dictionnaire bidimensionnelle arche_dict pour associer le nombre de classes, le nombre d'architypes et le nom de l'archétype.

Les variables d'archétype et les noms d'archétype dans le code ci-dessous sont des exemples au moment de la rédaction de l'article (22 août 2020). Si l'environnement change de manière significative en raison de la synchronisation de nouvelles puces ou du montage de cartes supplémentaires, veuillez réécrire comme il convient en fonction du nouvel environnement.

counter.py


#Définition du compteur de classe
E = R = W = D = Nc = V = B = Nm = 0
#Définition du compteur Architype
E1 = E2 = R1 = R2 = W1 = W2 = W3 = D1 = D2 = Nc1 = Nc2 = V1 = V2 = B1 = B2 = Nm1 = 0
#Autres compteurs Architype
OE = OR = OW = OD = ONc = OV = OB = ONm = 0

#Dictionnaire des compteurs de classes, noms d'archétypes, compteurs d'archétypes
arche_dict = {"E":{"Reno Seus E":E1, "Amatsu E":E2, "Autre E":OE},"R": {"Évolution R":R1, "Coopération R":R2, "Autre R":OR},"W": {"Épeler W":W1, "Magasin spécialisé W":W2, "Arcane W":W3, "Autre W":OW},"D": {"Jeter D":D1, "Baleine D":D2, "Autre D":OD},"Nc": {"Meifu Nc":Nc1, "Funérailles Nc":Nc2,  "Autre Nc":ONc},"V": {"Contrôle V":V1, "Frénésie V":V2, "Autre V":OV},"B": {"Eira B":B1, "Contrôle B":B2, "Autre B":OB},"Nm": {"AFNm":Nm1, "Autre Nm":ONm}}

Formule de jugement Architype

Définit une fonction qui détermine l'architype. Il reçoit des informations de classe et une liste de 40 cartes comme arguments, et les trie dans l'ordre de classification → classification par archétype.

Un exemple de la formule de jugement est présenté ci-dessous. Afin d'améliorer la précision de la classification, définissons une formule de jugement appropriée par essais et erreurs.

json_request.py


#Analyse de classe, d'archétype
def deck_arche_analysis(sv_deck, sv_class):
    global E,R,W,D,Nc,V,B,Nm
    global E1,E2,R1,R2,W1,W2,W3,D1,D2,Nc1,Nc2,V1,V2,B1,B2,Nm1
    global OE,OR,OW,OD,ONc,OV,OB,ONm
    if sv_class == 1: #Elfe
        E += 1
        if sv_deck.count("6lZu2") == 3:
            E1 += 1
        elif sv_deck.count("6pQTI") == 3:
            E2 += 1
        else:
            OE += 1
    elif sv_class == 2: #Royal
        R += 1
        if sv_deck.count("6td16") > 1:
            R1 += 1
        elif sv_deck.count("6_B9A") == 3:
            R2 += 1
        else:
            OR += 1
    elif sv_class == 3: #Sorcière
        W += 1
        if sv_deck.count("6_djc") == 3:
            W1 += 1
        elif sv_deck.count("6q95g") == 3:
            W2 += 1
        elif sv_deck.count("6t_Rc") == 3:
            W3 += 1
        else:
            OW += 1
    elif sv_class == 4: #Dragon
        D += 1
        if sv_deck.count("6yB-y") == 3:
            D1 += 1
        elif sv_deck.count("6_zhY") == 3:
            D2 += 1
        else:
            OD += 1
    elif sv_class == 5: #Nécromancien
        Nc += 1
        if sv_deck.count("6n7-I") > 1:
            Nc1 += 1
        elif sv_deck.count("70OYI") == 3:
            Nc2 += 1
        else:
            ONc += 1
    elif sv_class == 6: #Vampire
        V += 1
        if sv_deck.count("6rGOA") == 3:
            V1 += 1
        elif sv_deck.count("6v1MC") ==3:
            V2 += 1
        else:
            OV += 1
    elif sv_class == 7: #Évêque
        B += 1
        if sv_deck.count("6nupS") == 3:
            B1 += 1
        elif sv_deck.count("6nsN2") == 3:
            B2 += 1
        else:
            OB += 1
    elif sv_class == 8: #Némésis
        Nm += 1
        if sv_deck.count("6zcK2") == 3:
            Nm1 += 1
        else:
            ONm += 1

Obtenir le fichier JSON

json_request.py


#Entrez le numéro du tournoi JCG
compe_num = input("Veuillez saisir le numéro du tournoi JCG que vous souhaitez rechercher")
#URL du fichier JSON du tournoi
jcg_url = "https://sv.j-cg.com/compe/view/entrylist/" +  str(compe_num) + "/json"
#Demander un fichier json
res_jcg = requests.get(jcg_url)
#Enregistrer au format JSON
j_txt = json.loads(res_jcg.text)

Analyser le fichier JSON et agréger les classes et les archétypes

data-processing.py


for i in range(len(j_txt["participants"])):
    #Confirmation des informations gagnantes
    if j_txt["participants"][i]["te"] == 0: #Perdu
        continue
    elif j_txt["participants"][i]["te"] == 1: #Gagnant
        for j in range(2):
            #Obtenir des informations sur la classe
            class_ij = j_txt["participants"][i]["dk"][j]["cl"]
            #Acquisition des informations de la carte
            deck_ij = j_txt["participants"][i]["dk"][j]["hs"]
            #Déterminer l'archétype à partir des informations de la carte de classe
            deck_arche_analysis(deck_ij, class_ij)
    else:
        continue

Mettre en forme les données pour les graphiques

data.py


#Reflet des résultats d'agrégation
arche_dict = {"E":{"Reno Seus E":E1, "Amatsu E":E2, "Autre E":OE},"R": {"Évolution R":R1, "Coopération R":R2, "Autre R":OR},"W": {"Épeler W":W1, "Magasin spécialisé W":W2, "Arcane W":W3, "Autre W":OW},"D": {"Jeter D":D1, "Baleine D":D2, "Autre D":OD},"Nc": {"Meifu Nc":Nc1, "Funérailles Nc":Nc2,  "Autre Nc":ONc},"V": {"Contrôle V":V1, "Frénésie V":V2, "Autre V":OV},"B": {"Eira B":B1, "Contrôle B":B2, "Autre B":OB},"Nm": {"AFNm":Nm1, "Autre Nm":ONm}}

#Nombre de classes, tableau d'étiquettes
class_count = [E, R, W, D, Nc, V, B, Nm]
class_name = ["E", "R", "W", "D", "Nc", "V", "B", "Nm"]

#Nombre d'architype, tableau d'étiquettes
count = [list(arche_dict[key].values()) for key in arche_dict]
arche_count = sum(count,[])
label = [list(arche_dict[key].keys()) for key in arche_dict]
arche_name = sum(label,[])

Graphisme

Enfin, tracez les résultats de l'analyse. Un exemple de tracé est illustré ci-dessous, mais essayez de le représenter graphiquement avec votre mise en page préférée.

** * Si vous souhaitez exécuter le code suivant tel quel, vous devez définir la police japonaise dans matplotlib. ** ** Si vous souhaitez l'exécuter tel quel, téléchargez la police faisant référence à l'article suivant et placez-la dans le même répertoire que ce fichier python.

https://tech-k-labs.xyz/post/others/matplotlib_with_heroku/ (Dessinez un graphique de matplotlib sur Heroku)

graphs.py


#Importer matplotlib
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
#Les deux lignes suivantes concernent les paramètres japonais
from matplotlib.font_manager import FontProperties
fontprop = FontProperties(fname="ipaexg.ttf")

#Paramètres de couleur
class_colors = ["palegreen", "peachpuff", "mediumslateblue", "sienna","darkmagenta", "crimson", "wheat", "lightsteelblue"]
arche_colors = ["palegreen"]*len(arche_dict["E"]) +["peachpuff"]*len(arche_dict["R"]) +  ["mediumslateblue"] * len(arche_dict["W"]) + ["sienna"] * len(arche_dict["D"]) + ["darkmagenta"] * len(arche_dict["Nc"]) + ["crimson"] * len(arche_dict["V"]) + ["wheat"] * len(arche_dict["B"]) + ["lightsteelblue"] * len(arche_dict["Nm"])

#Graphique circulaire de la distribution des classes
fig1 = plt.figure()
plt.pie(class_count, labels=class_name, colors=class_colors, autopct="%.1f%%",pctdistance=1.35,wedgeprops={'linewidth': 2, 'edgecolor':"white"})
fig1.savefig("class_pie_"+compe_num+".png ")

#Graphique à barres de la distribution des archétypes
fig2 = plt.figure()
#x = np.array(list(range(len(arche_name))))
x = list(range(len(arche_name)))
plt.bar(x, arche_count, color=arche_colors)
plt.ylabel("Nombre d'utilisation",font_properties=fontprop)
plt.xticks(x,arche_name,rotation=90,font_properties=fontprop)
plt.subplots_adjust(left=0.1, right=0.95, bottom=0.25, top=0.95)
for x, y in zip(x, arche_count):
    plt.text(x, y, y, ha='center', va='bottom')

fig2.savefig("class_bar_"+compe_num+".png ")

Résultat d'exécution

Entrez le numéro de tournoi à 4 chiffres à la fin de l'URL JCG et exécutez. (URL du tournoi examinée cette fois: https://sv.j-cg.com/compe/2328)

** Ligne de commande ** execute.png ** Répartition des classes ** class_pie_2328.png ** Distribution des archétypes ** class_bar_2328.png

en conclusion

Cette fois, j'ai expliqué l'analyse des archétypes de l'environnement de rotation à titre d'exemple. Si vous modifiez la logique de jugement, vous pouvez analyser l'environnement illimité, donc si vous êtes intéressé, essayez-le.

Référence 1: Comparaison du nombre de cartes (de développement) adoptées

Vous pouvez également créer automatiquement un tableau de comparaison du nombre d'embauches en acquérant le nom de la carte et le nombre de cartes à partir du portail shadowverse par web scraping.

** Exemple: JCG Shadowverse Open 14th Season Vol.29 22 août Rotation Tournament Final Tournament ** ** Sorcière magique ** list_W_2356.png

Plus d'informations à ce sujet dans un autre article si j'en ai l'occasion.

Référence 2: (Développement) Exécuter à partir de Discord

Il est également possible d'exécuter un programme depuis Discord en utilisant le bot Discord. discord.png

Recommended Posts

Distribution totale automatique du deck JCG avec Python
Générez automatiquement une table de distribution de fréquence en un seul coup avec Python
Créer automatiquement la documentation Python avec Sphinx
Créez automatiquement la documentation de l'API Python avec Sphinx
[Python] Utiliser automatiquement le navigateur avec Selenium
FizzBuzz en Python3
Rechercher et télécharger automatiquement des vidéos YouTube avec Python
Grattage avec Python
Statistiques avec python
Vérifier automatiquement les scripts Python avec GitHub + Travis-CI + pycodestyle
Grattage avec Python
Python avec Go
Twilio avec Python
Intégrer avec Python
Jouez avec 2016-Python
AES256 avec python
Testé avec Python
Formater automatiquement le code Python en code compatible PEP8 avec Emacs
Essayez de générer automatiquement des documents Python avec Sphinx
python commence par ()
avec syntaxe (Python)
Bingo avec python
Zundokokiyoshi avec python
1. Statistiques apprises avec Python 2-1. Distribution de probabilité [variable discrète]
Excel avec Python
Micro-ordinateur avec Python
Cast avec python
Collez automatiquement des images dans des matériaux Powerpo avec python + α
Utilisez Cursur qui se ferme automatiquement avec sqlite3 en Python
L'ingénieur NW a essayé d'agréger les adresses avec le netaddr de Python
[Python] Créez un fichier de distribution pour le programme Tkinter avec cx_Freeze
Traduisez automatiquement DeepL en anglais avec Python et Selenium
Communication série avec Python
Zip, décompressez avec python
Django 1.11 a démarré avec Python3.6
Jugement des nombres premiers avec Python
Python avec eclipse + PyDev.
Communication de socket avec Python
Analyse de données avec python 2
Grattage en Python (préparation)
Distribution logistique en Python
Apprendre Python avec ChemTHEATER 03
Recherche séquentielle avec Python
Exécutez Python avec VBA
Manipuler yaml avec python
Résolvez AtCoder 167 avec python
Communication série avec python
[Python] Utiliser JSON avec Python
Apprendre Python avec ChemTHEATER 05-1
Apprenez Python avec ChemTHEATER
Exécutez prepDE.py avec python3
1.1 Premiers pas avec Python
Collecter des tweets avec Python
Binarisation avec OpenCV / Python
3. 3. Programmation IA avec Python
Méthode Kernel avec Python
Non bloquant avec Python + uWSGI
Grattage avec Python + PhantomJS
Exécuter automatiquement le fichier python
Publier des tweets avec python