foxxtrott

難しいことは分かりません

Riot Games APIでchampionIdからチャンピオン名を取得する

実行環境などはRiot Games APIをPythonで叩く - foxxtrottを参照。

つまづき

RiotWatcherのmatchやspectateで試合情報を取得する際、プレイヤーがどのチャンピオンをピックしたかという情報は、266や103といった、championIdとして取得される。
しかしchampionIdのままでは、人間が見てどのチャンピオンを指すのか分からない。そこでこのchampionIdをチャンピオン名に変換したい。

Data Dragonのチャンピオン情報のデータ構造メモ - foxxtrottで述べたように、Data Dragonの全チャンピオン情報は、各チャンピオン名をkey、チャンピオンデータをvalueに持つ階層dictになっている。
すなわち、チャンピオン名からチャンピオンデータ中のchampionIdを取得することは容易であり、例えば

#LoLバージョンの取得
region = 'jp1'
versions = rw.data_dragon.versions_for_region(region)

#Data Dragonからチャンピオン情報を取得
champions_data = rw.data_dragon.champions(versions['v'])

#AatroxのIDを取得表示
Aatrox_ID = champions_data['data']['Aatrox']['key']
print(Aatrox_ID)


実行結果

266

などで大丈夫だが、逆にchampionIdからチャンピオン名を取得するにはひと手間必要というわけである。

どうすんの

先述のchampions_dataを取得した上で、この関数を定義して使おう。

# championId(str)→チャンピオン名(str)
def championId_to_championName(championId):
    for name, dic in champions_data['data'].items():
        if dic['key'] == championId:
            return dic['name']


毎回for文が回るのが嫌な人は、↓の辞書をコードにコピペしちゃおう。

{'266': 'Aatrox', '103': 'Ahri', '84': 'Akali', '12': 'Alistar', '32': 'Amumu', '34': 'Anivia', '1': 'Annie', '22': 'Ashe', '136': 'Aurelion Sol', '268': 'Azir', '432': 'Bard', '53': 'Blitzcrank', '63': 'Brand', '201': 'Braum', '51': 'Caitlyn', '164': 'Camille', '69': 'Cassiopeia', '31': "Cho'Gath", '42': 'Corki', '122': 'Darius', '131': 'Diana', '119': 'Draven', '36': 'Dr. Mundo', '245': 'Ekko', '60': 'Elise', '28': 'Evelynn', '81': 'Ezreal', '9': 'Fiddlesticks', '114': 'Fiora', '105': 'Fizz', '3': 'Galio', '41': 'Gangplank', '86': 'Garen', '150': 'Gnar', '79': 'Gragas', '104': 'Graves', '120': 'Hecarim', '74': 'Heimerdinger', '420': 'Illaoi', '39': 'Irelia', '427': 'Ivern', '40': 'Janna', '59': 'Jarvan IV', '24': 'Jax', '126': 'Jayce', '202': 'Jhin', '222': 'Jinx', '145': "Kai'Sa", '429': 'Kalista', '43': 'Karma', '30': 'Karthus', '38': 'Kassadin', '55': 'Katarina', '10': 'Kayle', '141': 'Kayn', '85': 'Kennen', '121': "Kha'Zix", '203': 'Kindred', '240': 'Kled', '96': "Kog'Maw", '7': 'LeBlanc', '64': 'Lee Sin', '89': 'Leona', '127': 'Lissandra', '236': 'Lucian', '117': 'Lulu', '99': 'Lux', '54': 'Malphite', '90': 'Malzahar', '57': 'Maokai', '11': 'Master Yi', '21': 'Miss Fortune', '62': 'Wukong', '82': 'Mordekaiser', '25': 'Morgana', '267': 'Nami', '75': 'Nasus', '111': 'Nautilus', '518': 'Neeko', '76': 'Nidalee', '56': 'Nocturne', '20': 'Nunu & Willump', '2': 'Olaf', '61': 'Orianna', '516': 'Ornn', '80': 'Pantheon', '78': 'Poppy', '555': 'Pyke', '133': 'Quinn', '497': 'Rakan', '33': 'Rammus', '421': "Rek'Sai", '58': 'Renekton', '107': 'Rengar', '92': 'Riven', '68': 'Rumble', '13': 'Ryze', '113': 'Sejuani', '35': 'Shaco', '98': 'Shen', '102': 'Shyvana', '27': 'Singed', '14': 'Sion', '15': 'Sivir', '72': 'Skarner', '37': 'Sona', '16': 'Soraka', '50': 'Swain', '517': 'Sylas', '134': 'Syndra', '223': 'Tahm Kench', '163': 'Taliyah', '91': 'Talon', '44': 'Taric', '17': 'Teemo', '412': 'Thresh', '18': 'Tristana', '48': 'Trundle', '23': 'Tryndamere', '4': 'Twisted Fate', '29': 'Twitch', '77': 'Udyr', '6': 'Urgot', '110': 'Varus', '67': 'Vayne', '45': 'Veigar', '161': "Vel'Koz", '254': 'Vi', '112': 'Viktor', '8': 'Vladimir', '106': 'Volibear', '19': 'Warwick', '498': 'Xayah', '101': 'Xerath', '5': 'Xin Zhao', '157': 'Yasuo', '83': 'Yorick', '154': 'Zac', '238': 'Zed', '115': 'Ziggs', '26': 'Zilean', '142': 'Zoe', '143': 'Zyra'}

おまけ

さっきの辞書を作ってtxtへ出力/txtから読み込みするプログラム

# 'championID':'championName'のdictをtxtへ出力
dict_champion_id_to_name = {}
for key, value in champions_data['data'].items():
    for i in range(999):
        if value['key'] == str(i):
            dict_champion_id_to_name[value['key']] = value['name']
f = open('dict_champion_id_to_name.txt', 'w')
for key, value in dict_champion_id_to_name.items():
    f.write(f'{key}:{value}\n')
f.close()
#'championID':'championName'のdictをtxtから読み込み
dict_champion_id_to_name = {}
f = open("dict_champion_id_to_name.txt",'r')
for line in f:
    line = line.rstrip('\n')
    fields = line.split(':')
    dict_champion_id_to_name[fields[0]] = fields[1]
f.close()

目から血が出そうなソースコードだ……

分かりやすくウマい赤ワイン【2000円以下】

まえがき

  • 個人の感想です。
  • ワインを飲みすぎて、最近痛風を発症しました。
  • 難しいことは分からないので、率直においしいと思ったものをチョイス。
  • それぞれの特徴とか合う料理とかは適宜リンク先のVivinoから。
  • あとワインを飲む前にワイングラスを買おう(選び方)。マジで全然違うから。

選び方

  • 1000円以下は当たり外れが大きすぎるので世間的によほど評価の良いもの以外は基本的に買わない。冒険するのはここじゃない。
  • 1000~1500円は迷ったらチリか南フランス産を買う(スペインも安くて高品質だが、好みではないため)。
  • 1500~2000円くらいからこれはうめえ!!!っていうワインがちらほら現れる。何本か飲んでいるうちに、自分の好きな産地・品種が分かってくるので、それを軸に開拓していく。しばらく続けていると、産地と品種と顔つきで味がある程度想像できるようになってくる。
  • 「金賞受賞」とかはマジで戯言だから気にしないほうが良い。

騙されたと思って1回飲んでみ

Chilano Vintage Collection Syrah(400円)

www.vivino.com
チリ:シラー / ドンキホーテ
コスパ重視なら一択。命題「安い⇒薄い青い不味い」ほぼ唯一の反例。怖いもの見たさで購入したが普通にワインとして成立してる。シラーを選んだけどカベルネソーヴィニヨンも普通にイケる。APY(Alcohol Per Yen)がビールの倍くらいある俺たちの味方。

Sierra Batuco Lone Rider Premium Selection(1500円)

チリ(マウレ):カルメネール、シラー、カベルネソーヴィニヨン / コストコ
www.vivino.com
死ぬほどうまくてリピートしたチリのブレンドワイン。一言でいうと、定評があるコノスルシリーズのCono Sur Organic Red Blend (Cabernet Sauvignon - Carmenere - Syrah)の完全上位互換。マジでうまいから見たら即買いで間違いない。ただコイツは最近どこにも見かけなくなってしまった。

Domaine Lafage Tessellae Vieilles Vignes Carignan(1700円)

フランス(コート・カタラン):カリニャン / イオンワイン
www.vivino.com
PP90+を連発しているらしいDomaine Lafageの中で一番おすすめがこれ。Château Saint-Rochも振れ幅はあるもののウマい。Bastide Miraflorsはシラーとグルナッシュの風味が別々に来る感じがあるが合う人には合いそう。どれもイオンワインにあって、南仏ワインの定番という感じ。近くにイオンワインがある人は買おう。

Farnese Fantini Casale Vecchio Montepulciano d'Abruzzo(2000円)

イタリア:モンテプルチアーノダブルッツォ / カルディ
www.vivino.com
各所で死ぬほど絶賛されている気がするが実際ウマい。飲みやすさと濃厚さの両立。今日はちょっと良いワインを買っちゃおうという時用。おいしいワイン飲んだことないんだよね〜なんかオススメある?と聞かれたらこれを答えると思う。これが好きならBelpostoが次のオススメ。

ここまでのが見つからなかった時用の控え

Alpaca, Cono Surなどお手頃チリ勢(600~1200円)

www.vivino.com
結局アルパカ。カベルネメルローはちぐはぐな感じでピノノワは薄いが、カルメネールはまとまりが良い。今日宅飲みしよーぜ的なノリで買うワイン。ちなみにチリのカルメネールは長らくメルローだと勘違いされていて、1994年のDNA鑑定でやっと別品種であることが判明した。

あとはCono Surシリーズ。
www.vivino.com
もはや説明不要。ビチクレタを飲んだことがある人はレゼルバシリーズを飲むと明らかに違うのでおすすめ。ガツンと行きたいならオーガニックブレンド

La Vieille Ferme Rougeなど南仏勢(1000~1500円)

フランス:シラー、グルナッシュ、カリニャン、サンソー / どこでも
www.vivino.com
フランス人の血液は半分くらいこのワインで出来てると言っても過言ではないデイリーワイン。南仏はボトルの形がブルゴーニュ型(なで肩)で見分けやすいし、初心者が高コスパワインを探すのに最適。てかだいたい飲みやすくてうまい。L'ArjolleとかOpen Nowとかもうまかった。

Atalaya Layaなどスペイン勢(1000~1500円)

スペイン(アルマンサ):ガルナッチャティントレラ70%、モナストレル30%
www.vivino.com
スペインワインは全体的に傾向が似ている(ジューシー・スパイシー・香り立ち華やか)ので、これが気に入った人はEl MiracleHéculaCune CrianzaEvodiaとかも飲むとよさげ。

番外:世間的に高評価だけどビミョーだと思ったワイン

王様の涙(500円)

www.vivino.com
印象に残らないワインランキングNo.1。アマゾンレビューでは絶賛気味

Conte di Campiano Appassimento(1400円)

イタリア(ヴェネト):ネグロアマーロ / イオンワイン
www.vivino.com
濃厚ぶどうジュース。PP90+取ってるしvivinoの評価も高いところをみると、俺のボトルがハズレだったのかな…。

The Seven Deadly Zins Old Vine Zinfandel(2000円)

アメリカ(ローダイ):ジンファンデル / コストコ
www.vivino.com
俺のジンファンデル嫌いを決定付けたワイン。アメリカの脳筋にF***って叫ばれている気分になった。


最近3000円以下最強との呼び声が高い689を手に入れてしまったので、誰か飲もう。
あと、もっとウマいの知ってるぜって人、おすすめを教えてください。

Data Dragonのチャンピオン情報のデータ構造メモ

チャンピオンの静的データ取得メモ。
実行環境などは前記事参照。
データ取得

#LoLバージョンの取得
region = 'jp1'
versions = rw.data_dragon.versions_for_region(region)

#Data Dragonからチャンピオン情報を取得
champions = rw.data_dragon.champions(versions['v'])

データ構造
このようにして得られるchampionsの中のchampions['data']に全チャンピオンの静的データが格納されている。各チャンピオン名をkey、チャンピオンデータをvalueに持つ階層dictになっており、重要そうなものについて具体的には以下。

  • 'チャンピオン名':
    • 'key': 'チャンピオン番号'
    • 'title': '二つ名'
    • 'info':
      • 'attack': '攻撃力(定性)'
      • 'defense': '防御力(定性)'
      • 'magic': '魔力(定性)'
      • 'difficulty': '難易度(定性)'
    • 'stats':
      • 'hp': HP初期値
      • 'hpperlevel': レベルごとのHP上昇値
      • 'mp': MP初期値
      • 'mpperlevel': レベルごとのMP上昇値
      • 'movespeed': MS値
      • 'armor': AR初期値
      • 'armorperlevel': レベルごとのAR上昇値
      • 'spellblock': MR初期値
      • 'spellblockperlevel': レベルごとのMR上昇値
      • 'attackrange': AA射程値*1
      • 'hpregen': HPReg初期値*2
      • 'hpregenperlevel': レベルごとのHPReg上昇値
      • 'mpregen': MPReg初期値*3
      • 'mpregenperlevel': レベルごとのMPReg上昇値
      • 'crit': Crit発生率
      • 'critperlevel': レベルごとのCrit発生率上昇値
      • 'attackdamage': AD初期値
      • 'attackdamageperlevel': レベルごとのAD上昇値
      • 'attackspeedperlevel': レベルごとのAS上昇率 *4
      • 'attackspeed' : AS基礎値

次回はこれを使って簡易的なオートアタックDPSの可視化をします。

*1:あれ、attackrangeperlevelは?TrisとかAA射程伸びるんだけどな…

*2:5秒毎

*3:5秒毎

*4:ASのみ'率'。すなわちAS = attackspeed * (1+attackspeedperlevel)^level

Riot Games APIをPythonで叩く

実行環境

準備

  1. Riot Developer Portalにサインアップ
  2. DASHBOARDタブ→REGENERATE API KEYからAPIキー(RGAPI-から始まる文字列)を取得
  3. RiotWatcherをインストール(pip install riotwatcher)

(RiotWatcherの代わりにCassiopeiaというフレームワークもあるっぽい)

モナー情報を取得するサンプル

from riotwatcher import RiotWatcher
rw = RiotWatcher('[ここにAPIキーを入力]')
region = 'jp1'
me = rw.summoner.by_name(region, '[ここにSNを入力]')
print(me)

実行結果(自分の場合)

{'id': 'kACJhYQiFUTUkSZQ9J8Yf-UyU4POFdqEWvs4gB-WqPZJ5qY', 'accountId': 'TXv_lJ95UT1SfrMccahYlf2tbT9_Y6l4CNU1YfhWsFUxhPk', 'puuid': '_kWKzyoKNaZqhWXppg3qVWc-8f-lmOCOucUbKw7B1t5TuqaPcSuMvkgVx1XBpGCaJhU7Oox4jLCzxQ', 'name': 'Suicabar J Foxx', 'profileIconId': 3221, 'revisionDate': 1556019974000, 'summonerLevel': 164}

このようにして得られる['id']はサモナー毎のランク情報などの呼び出しに必要になります。

リファレンスなど

Data Dragonのデータ構造が分からない…。

ブログ始めました。

Hello, world!

はじめまして、Suicabar J. Foxxです。

このブログでは、主に趣味関連のことを発信していきたいと思います。

 

趣味

LoL、車、読書、ワインなどです。

 

LoLとは?

League of Legends(略してLoL)というオンラインゲームです。

紹介記事:

gigazine.net

イマ風に言うところのe-sportsの一種で、日本にもプロリーグが存在します。

世界のトッププロは年収3億くらい稼いでるらしいです。

 

LoLにはキャラクター(チャンピオンと呼ばれる)が140体くらいいるのですが、それぞれのチャンピオンについてステータスや技の性能を深く知ることが非常に重要です。そこでこのようなスタッツサイトが多く存在します。こういったサイトで手が届いていない機能とかを自作していきたいと思っています。