はじめに
多くの場合、先行結論型で話すのが理系だとはわかっている。
ただ今回は教科書的、メモ帳的に書くので目次だけで許してほしい。
-
カード情報の入手(基本)
-
日本語カードの入手
-
特殊な事例
-
両面カード
-
分割カード
-
基本土地
カード情報の入手(基本)
まずmtgの公式sdk mtgsdkからデータをもらう
from mtgsdk import Card
cards = Card.all()
これで”カード情報”だけは手に入る。
筆記当時
>>>len(cards)
64521
>>>cards[0].name
‘Overtaker’
といったように手に入る。
日本語カードの入手
mtgsdkのCardクラスには、foreign_namesに他言語版のデータが入っている。
ktk(タルキール)のカードセットでは、
- foreign_names[0]=’German’
- foreign_names[1]=’Spanish’
- foreign_names[2]=’French’
- foreign_names[3]=’Italian’
- foreign_names[4]=’Japanese’
- …etc(計10言語)
のように格納されている。
格納自体は、
- foreign_names
- 言語
- name
- text
- type
- flavor
- imageUrl
- language
- multiverseid
のようになっている。
- 言語
よって、
for i in range(0,1,len(card[].foreign_names)):
if card[].foreign_names[i]['language']=='Japanese':
print(card[].foreign_names[i]['name'])
のようにすれば日本語カードの情報を掘り当てられる。
特殊な事例
mtgはしばらくはやっていないが、特殊なギミックがあるカードたちは多い
-
両面カード
変異や変身などで反転し別カードになる -
分割カード
2つの呪文が入っているカードたち、1つの面にそれぞれの名前が書いてある -
各種基本土地
同じ名前で同じ効果なのに同じパックで複数存在するカードたち
これらのカードはどのように処理されるのかを見てみる。
両面カード
両面カードなので当然カードの画像は2種類存在するし、
片面事に別カードである。
早速実験してみる。
#一応日本語カードがあるカードで選別
#フォーマットはイニストラード
card_isd=Card.where(set='isd').where(language='Japanese').all()
#まずは名前で調べる
name='Villagers of Estwald'
for i in range(1,len(card_isd)):
if card_isd[i].name == name:
print(i)
print(card_isd[i].name)
上記の結果は
>>>
で何も表示されない。
次に、
#一応日本語カードがあるカードで選別
#フォーマットはイニストラード
card_isd=Card.where(set='isd').where(language='Japanese').all()
#調べてから表示してみる
print(card_isd[38].name)
print(card_isd[39].name)
結果は、
>>>38
>>>Thraben Sentry // Thraben Militia
>>>39
>>>Thraben Sentry // Thraben Militia
なんと連番で登録されており、かつ//で名前が分割されている。
検索の場合は、マッチングを利用してあげると検索でき、
#一応日本語カードがあるカードで選別
#フォーマットはイニストラード
card_isd=Card.where(set='isd').where(language='Japanese').all()
#名前をマッチングで調べる
name='Villagers of Estwald'
for i in range(1,len(card_isd)):
if name in card_isd[i].name:
print(i)
print(card_isd[i].name)
結果は
>>>227
>>>Villagers of Estwald // Howlpack of Estwald
>>>228
>>>Villagers of Estwald // Howlpack of Estwald
とちゃんと表示される。
ちなみにどっちがどっちのカードかは、
>>> card_isd[227].text
'At the beginning of each upkeep, if no spells were cast last turn, transform Villagers of Estwald.'
>>> card_isd[228].text
'At the beginning of each upkeep, if a player cast two or more spells last turn, transform Howlpack of Estwald.'
の結果より、番号が小さい方が名前の左(表面)
番号が大きい方が名前の右(裏面)のようである。
分割カード
分割カードは両面カードの仕様とおそらくはほぼ同一だ。
早速実験してみる。
card_akh=Card.where(set='akh').where(language='Japanese').all()
#検索対象は徹頭+徹尾
name = 'Start'
for i in range(1,len(card_akh)):
if card_akh[i].name == name:
print(i)
print(card_akh[i].name
まあ、お察しだろうが結果は
>>>
何も出ないので、マッチングさせて、結果だけ表示させていただくが、
>>>219
>>>Start // Finish
>>>220
>>>Start // Finish
である。
どちらがどちらというと
>>> card_akh[219].text
'Create two 1/1 white Warrior creature tokens with vigilance.'
>>> card_akh[220].text
'Aftermath (Cast this spell only from your graveyard. Then exile it.)\nAs an additional cost to cast Finish, sacrifice a creature.\nDestroy target creature.'
となるので、名前左が番号が小さい方、
名前右が番号が大きい方とわかる。
以上が2枚分のカード情報があるカードのmtgsdkでの扱いである。
基本土地
基本土地カードは、正直、検索がものすごく面倒なカードである。
とりあえず検索してみよう。
name = 'Forest'
for i in range(1,len(card_akh)):
if name in card_akh[i].name:
print(i)
print(card_akh[i].name)
結果は、
>>>268
>>>Forest
>>>281
>>>Forest
>>>282
>>>Forest
>>>283
>>>Forest
正直、どれがどの柄のForestかはわからない。
一応見分けの付け方だけ(コードは自前で用意してほしい)書いておく。
-
調べたいカードの柄を用意(jpegなどで)
-
opencvで画像のマッチングを行う
-
一致率を算出し最も近い画像を表示する。
となる。
これだけで探せるのでぜひ頑張ってほしい。
おわりに
とりあえず、mtgsdkで日本語カードを操作する方法の基礎は書いたつもりだ。
他のサイトを見ればCard.all()で取得したデータを保存しているが、
一時的な、セットを指定した操作ならすぐ終わるので、
セット毎に保存するのが一番賢いやり方だと思っている。
all()ですべて取得しても数ヶ月後には役に立たなくなるのも嫌な点だ。
更新か所は数か所で終わらすのがスマートな気がする。
mtgのカード量はここ数年で数万単位で増えている。
必要な個所だけ更新する術はmtgsdkを長く扱う上では必須項目であろう。
ではよいMTGライフを。