Automatische vollständige JCG-Deckverteilung mit Python

Einführung

** * Dieser Artikel richtet sich an Personen, die Programmiererfahrung mit Python haben. ** ** **

Zusätzlich wird folgendes Wissen vorausgesetzt. ・ Grundlegende Grammatik von Python ・ Visualisierung von Daten mit matplotlib

Zweck

Ruft eine Kartenliste von der JCG-Site ab und aggregiert und grafischisiert automatisch Klassenverteilungen und Archetypverteilungen.

Ansatz

Auf der JCG-Website werden Registrierungsinformationen wie Informationen zum Turniersieg, Check-in-Status, Registrierungsdeck usw. in einer Textdatei im JSON-Format zusammengefasst. Holen Sie sich die Kartenliste aus dieser JSON-Datei und sortieren Sie die Decktypen nach der Nummernzusammensetzung.

Was ist JSON?

JSON (JavaScript Object Notation) ist eine Notation zum Ausdrücken strukturierter Daten. Stellen Sie sich vor, es stellt eine hierarchische Struktur zwischen Texten dar, wie die hierarchische Struktur eines Verzeichnisses. In der JCG-JSON-Datei werden die Registrierungsdaten beispielsweise im folgenden Format beschrieben.

example.json


{
	"result": "success",
	"participants": [
		{
			"id": "42155", 
			"chk": 1, #Check-in Status
			"nm":  "somey", #Registrierter Name
			"dk": [ #Deckinformationen
				{
					"cl": 3, #Klasse 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"
				}, #Deck 1 Kartenliste (um genau zu sein, Teil der Portal-URL)
				{
					"cl": 8, #Klasse 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"
				} #Deck 2 Kartenliste (um genau zu sein, Teil der Portal-URL)
			],
			"en": 1527921725,
			"te": 1, #Gewinninformationen
			"pr": 1,
			"cu": 0
		},

Erfassung von Deckinformationen

Informationen zum Deck werden im Schlüsselteil "hs" der JSON-Datei gespeichert.

Zum Beispiel in der obigen JSON-Datei

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


 Ist das Deck Informationen.

 Fünfstellige alphanumerische Zeichen (wie "6so2A"), die durch Punkte getrennt sind, repräsentieren eine Karte, und 40 davon repräsentieren ein Deck.
 Überprüfen Sie das Shadowverse-Portal auf die Übereinstimmung zwischen diesen alphanumerischen Zeichen und dem Kartennamen.
 Wenn Sie sich die Portal-URL genauer ansehen, werden Sie feststellen, dass sie aus 40 alphanumerischen Zeichen besteht, ähnlich einer JSON-Datei.

 (Beispiel: Zauberhexe)
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

 Zum Beispiel erscheinen am Ende drei alphanumerische Zeichen "6t_RI" in einer Reihe, was bedeutet, dass drei "Yin und Yang Gründer, Kuon" enthalten sind.

### Architype Klassifizierung

 Erstellen Sie eine Beurteilungsformel, um Archetypen anhand von Informationen zu Art und Anzahl der im Deck enthaltenen Karten zu klassifizieren.
 Verwenden Sie für die Beurteilungsformel eine Karte, mit der der Archetyp so eindeutig wie möglich identifiziert werden kann.

 Beispiel: `` `6q95g``` (Zauberwerkzeugfachgeschäft) ist dreimal enthalten → Fachgeschäftshexe

### Analyseverfahren
 1. Fordern Sie eine JSON-Datei an
 (Im Folgenden Analyse der JSON-Datei)
 2. Bestätigung der Gewinninformationen (Weiter mit 3, wenn ein Gewinner gefunden wird)
 3. Holen Sie sich die Kartenliste
 4. Architype-Klassifizierung (Wenn ✕✕ ○ oder mehr ist, □□ Elf usw.)
 5. Wiederholen Sie die Schritte 2-4
 6. Nachdem die Archetypklassifizierung aller Teilnehmer abgeschlossen ist, aggregieren und grafisch darstellen

### Ein Beispiel für Aggregationsergebnisse

 ** JCG Shadowverse Open 14. Saison Vol.29 22. August Rotation Tournament Group Qualifying **

 ** Klassenverteilung **
 <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 ">
 ** Archetypverteilung **
 <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 ">

# Codierung
 * Da Sie Autodidakt im Programmieren sind, folgen Sie möglicherweise nicht redundantem Code oder Zoll.
 Bitte bewahren Sie die folgenden Codierungsbeispiele nur als Referenz auf.
### Bibliothek importieren
 Importieren Sie zuerst die erforderlichen Bibliotheken.


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

import requests
import json

Zählerdefinition

Definiert Variablen, mit denen die Anzahl der Klassen und Archetypen aggregiert wird. Es definiert auch eine zweidimensionale Wörterbuchvariable `` `arche_dict```, um die Anzahl der Klassen, die Anzahl der Architypes und den Archetypnamen zuzuordnen.

Die Archetypvariablen und Archetypnamen im folgenden Code sind Beispiele zum Zeitpunkt des Schreibens des Artikels (22. August 2020). Wenn sich die Umgebung aufgrund des Zeitpunkts neuer Aufzählungszeichen oder zusätzlicher Kartenmontage erheblich ändert, schreiben Sie sie entsprechend der neuen Umgebung entsprechend um.

counter.py


#Definition des Klassenzählers
E = R = W = D = Nc = V = B = Nm = 0
#Architype Zähler Definition
E1 = E2 = R1 = R2 = W1 = W2 = W3 = D1 = D2 = Nc1 = Nc2 = V1 = V2 = B1 = B2 = Nm1 = 0
#Andere Architype-Zähler
OE = OR = OW = OD = ONc = OV = OB = ONm = 0

#Wörterbuch des Klassenzählers, des Archetypnamens, des Archetypzählers
arche_dict = {"E":{"Reno Seus E.":E1, "Amatsu E.":E2, "Andere E.":OE},"R": {"Evolution R.":R1, "Kooperation R.":R2, "Andere R.":OR},"W": {"Zauber W.":W1, "Fachgeschäft W.":W2, "Arkan W.":W3, "Andere W.":OW},"D": {"D verwerfen":D1, "Wal D.":D2, "Andere D.":OD},"Nc": {"Meifu Nc":Nc1, "Begräbnis Nc":Nc2,  "Andere Nc":ONc},"V": {"Steuerung V.":V1, "Raserei V.":V2, "Andere V.":OV},"B": {"Eira B.":B1, "Kontrolle B.":B2, "Andere B.":OB},"Nm": {"AFNm":Nm1, "Andere Nm":ONm}}

Architype Urteilsformel

Definiert eine Funktion, die den Architype bestimmt. Es empfängt Klasseninformationen und eine Liste von 40 Karten als Argumente und sortiert sie in der Reihenfolge der Klassifizierung → Archetypklassifizierung.

Ein Beispiel für die Beurteilungsformel ist unten gezeigt. Um die Genauigkeit der Klassifizierung zu verbessern, legen wir durch Ausprobieren eine geeignete Beurteilungsformel fest.

json_request.py


#Klassen-, Archetypanalyse
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: #Elf
        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: #königlich
        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: #Hexe
        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: #Drachen
        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: #Nekromant
        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: #Vampir
        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: #Bischof
        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: #Nemesis
        Nm += 1
        if sv_deck.count("6zcK2") == 3:
            Nm1 += 1
        else:
            ONm += 1

JSON-Datei abrufen

json_request.py


#Geben Sie die JCG-Turniernummer ein
compe_num = input("Bitte geben Sie die JCG-Turniernummer ein, nach der Sie suchen möchten")
#URL der Turnier-JSON-Datei
jcg_url = "https://sv.j-cg.com/compe/view/entrylist/" +  str(compe_num) + "/json"
#Json-Datei anfordern
res_jcg = requests.get(jcg_url)
#Daten im JSON-Format speichern
j_txt = json.loads(res_jcg.text)

Analysieren Sie JSON-Datei- und Aggregatklassen und Archetypen

data-processing.py


for i in range(len(j_txt["participants"])):
    #Bestätigung der Gewinninformationen
    if j_txt["participants"][i]["te"] == 0: #Hat verloren
        continue
    elif j_txt["participants"][i]["te"] == 1: #Gewinnen
        for j in range(2):
            #Klasseninformationen abrufen
            class_ij = j_txt["participants"][i]["dk"][j]["cl"]
            #Erfassung von Karteninformationen
            deck_ij = j_txt["participants"][i]["dk"][j]["hs"]
            #Bestimmen Sie den Archetyp anhand der Klassenkarteninformationen
            deck_arche_analysis(deck_ij, class_ij)
    else:
        continue

Formatieren Sie Daten für Diagramme

data.py


#Reflexion der Aggregationsergebnisse
arche_dict = {"E":{"Reno Seus E.":E1, "Amatsu E.":E2, "Andere E.":OE},"R": {"Evolution R.":R1, "Kooperation R.":R2, "Andere R.":OR},"W": {"Zauber W.":W1, "Fachgeschäft W.":W2, "Arkan W.":W3, "Andere W.":OW},"D": {"D verwerfen":D1, "Wal D.":D2, "Andere D.":OD},"Nc": {"Meifu Nc":Nc1, "Begräbnis Nc":Nc2,  "Andere Nc":ONc},"V": {"Steuerung V.":V1, "Raserei V.":V2, "Andere V.":OV},"B": {"Eira B.":B1, "Kontrolle B.":B2, "Andere B.":OB},"Nm": {"AFNm":Nm1, "Andere Nm":ONm}}

#Klassenanzahl, Label-Array
class_count = [E, R, W, D, Nc, V, B, Nm]
class_name = ["E", "R", "W", "D", "Nc", "V", "B", "Nm"]

#Architype-Anzahl, Label-Array
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,[])

Grafik

Stellen Sie abschließend die Analyseergebnisse grafisch dar. Ein Beispiel für das Diagramm ist unten dargestellt. Versuchen Sie jedoch, es mit Ihrem bevorzugten Layout grafisch darzustellen.

** * Wenn Sie den folgenden Code so ausführen möchten, wie er ist, müssen Sie die japanische Schriftart in matplotlib festlegen. ** ** ** Wenn Sie es so ausführen möchten, wie es ist, laden Sie die Schriftart herunter, die auf den folgenden Artikel verweist, und legen Sie sie im selben Verzeichnis wie diese Python-Datei ab.

https://tech-k-labs.xyz/post/others/matplotlib_with_heroku/ (Zeichnen Sie eine Grafik von Matplotlib auf Heroku)

graphs.py


#Matplotlib importieren
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
#Die folgenden zwei Zeilen gelten für japanische Einstellungen
from matplotlib.font_manager import FontProperties
fontprop = FontProperties(fname="ipaexg.ttf")

#Farbeinstellungen
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"])

#Kreisdiagramm der Klassenverteilung
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 ")

#Balkendiagramm der Archetypverteilung
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("Anzahl der Nutzung",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 ")

Ausführungsergebnis

Geben Sie die 4-stellige Turniernummer am Ende der JCG-URL ein und führen Sie sie aus. (Turnier-URL diesmal geprüft: https://sv.j-cg.com/compe/2328)

** Befehlszeile ** execute.png ** Klassenverteilung ** class_pie_2328.png ** Archetypverteilung ** class_bar_2328.png

abschließend

Dieses Mal erklärte ich als Beispiel die Archetypanalyse der Rotationsumgebung. Wenn Sie die Beurteilungslogik ändern, können Sie die unbegrenzte Umgebung analysieren. Wenn Sie also interessiert sind, versuchen Sie es bitte.

Referenz 1: Vergleich der Anzahl der angenommenen (Entwicklungs-) Karten

Sie können auch automatisch eine Vergleichstabelle der Anzahl der Einstellungen erstellen, indem Sie den Kartennamen und die Anzahl der Karten vom Shadowverse-Portal durch Web-Scraping abrufen.

** Beispiel: JCG Shadowverse Open 14. Staffel Vol.29 22. August Rotationsturnier Finalturnier ** ** Zauberhexe ** list_W_2356.png

Mehr dazu in einem anderen Artikel, wenn ich die Gelegenheit dazu habe.

Referenz 2: (Entwicklung) Aus Discord ausführen

Es ist auch möglich, ein Programm von Discord aus mit dem Discord-Bot auszuführen. discord.png

Recommended Posts

Automatische vollständige JCG-Deckverteilung mit Python
Generieren Sie mit Python automatisch eine Häufigkeitsverteilungstabelle auf einmal
Erstellen Sie automatisch eine Python-Dokumentation mit Sphinx
Erstellen Sie automatisch eine Python-API-Dokumentation mit Sphinx
[Python] Betreiben Sie den Browser automatisch mit Selenium
FizzBuzz in Python3
Suchen und laden Sie YouTube-Videos automatisch mit Python herunter
Scraping mit Python
Statistik mit Python
Überprüfen Sie Python-Skripte automatisch mit GitHub + Travis-CI + Pycodestyle
Scraping mit Python
Python mit Go
Twilio mit Python
In Python integrieren
Spielen Sie mit 2016-Python
AES256 mit Python
Getestet mit Python
Formatieren Sie Python-Code mit Emacs automatisch in PEP8-kompatiblen Code
Versuchen Sie, Python-Dokumente automatisch mit Sphinx zu generieren
Python beginnt mit ()
mit Syntax (Python)
Bingo mit Python
Zundokokiyoshi mit Python
1. Mit Python 2-1 gelernte Statistiken. Wahrscheinlichkeitsverteilung [diskrete Variable]
Excel mit Python
Mikrocomputer mit Python
Mit Python besetzen
Fügen Sie Bilder mit Python + α automatisch in Powerpo-Materialien ein
Verwenden Sie Cursur, das in Python automatisch mit sqlite3 geschlossen wird
Der NW-Ingenieur hat versucht, Adressen mit Pythons netaddr zu aggregieren
[Python] Erstellen Sie mit cx_Freeze eine Verteilungsdatei für das Tkinter-Programm
Übersetzen Sie DeepL automatisch mit Python und Selen ins Englische
Serielle Kommunikation mit Python
Zip, entpacken mit Python
Django 1.11 wurde mit Python3.6 gestartet
Primzahlbeurteilung mit Python
Python mit Eclipse + PyDev.
Socket-Kommunikation mit Python
Datenanalyse mit Python 2
Scraping in Python (Vorbereitung)
Logistische Verteilung in Python
Python lernen mit ChemTHEATER 03
Sequentielle Suche mit Python
Führen Sie Python mit VBA aus
Umgang mit Yaml mit Python
Löse AtCoder 167 mit Python
Serielle Kommunikation mit Python
[Python] Verwenden Sie JSON mit Python
Python lernen mit ChemTHEATER 05-1
Lerne Python mit ChemTHEATER
Führen Sie prepDE.py mit python3 aus
1.1 Erste Schritte mit Python
Tweets mit Python sammeln
Binarisierung mit OpenCV / Python
3. 3. KI-Programmierung mit Python
Kernel-Methode mit Python
Nicht blockierend mit Python + uWSGI
Scraping mit Python + PhantomJS
Führen Sie die Python-Datei automatisch aus
Tweets mit Python posten