Top / 新しいカテゴリを作る
HTML convert time: 0.014 sec.

新しいカテゴリを作る

Last-modified: 2016-01-29 (金) 16:42:54
 

カテゴリ判定のしくみ

 オリジナルのカテゴリを作るには、まずどのようにカードのカテゴリが識別されているかを知っておく必要があります。以下でその仕組みについて説明します。

setcode

 cards.cdbを開き、datas.setcodeの欄を見ると、カードごとにいろいろな数値が書き込まれていると思います。
 この値が、そのカードの所属するカテゴリを示しています。

「クリフォート・エイリアス」
setcode = 0xaa「クリフォート」

 「クリフォート」カードのsetcode欄には全て0xaaが表示されているはずです。つまり「クリフォート」= 0xaaということです。全てのカテゴリにこのように数字が1つずつ割り当てられています。

0x6E「魔導」
0x6F「ヒロイック」
0x70「先史遺産」...

 あるカテゴリに含めたいと思ったら、そのカテゴリの数値を調べて、setcodeに入れればいいというわけです。

 また、複数のカテゴリをまたがる場合、setcodeはカテゴリを示す値を2バイト(4ケタ)単位で結合した値になります。

「ジャンク・ウォリアー」
setcode = 0x6600430100 -> 0066, 0043, 0100
0x66「ウォリアー」
0x43「ジャンク」
0x100「シンクロンを素材とするSモンスター」
「サイバー・エンド・ドラゴン」
setcode = 0x1030093 -> 0103, 0093
0x103「サイバー・ドラゴンを融合素材とするモンスター」
0x93「サイバー」

 どのカテゴリにも所属しないなら、setcodeは0です。

他カテゴリに含まれるカテゴリ

 ところで、カテゴリの中には「魔導」に対する「魔導書」のように、別のカテゴリにすっかり含まれてしまうカテゴリが存在します。これがちょっとややこしいです。
 このようなカテゴリは、含まれるカテゴリの数値の上位8ビット(上1桁)に識別用の値を結合した数値で表されます。

0x106E「魔導書」 = 0x006E「魔導」と 0x1(識別用の値)

 この識別用の値には法則があり、ビットパターン(2進数表示)を意識する必要があります。

 「セイバー」「X-セイバー」「XX-セイバー」のように、カテゴリが入れ子状になっている場合は、識別値のビットパターンが下位カテゴリの識別値のビットパターンを含んでいなければなりません。

0x000d「セイバー」    -> 0(0000)
0x100d「X-セイバー」 -> 1(0001)
0x300d「XX-セイバー」-> 3(0011)
  ^ここ

 「X-セイバー」で1が立っている全ての桁には、「XX-セイバー」でも1が立っています。これが含んでいるということです。
 一方、「HERO」に対する「E・HERO」「E-HERO」のように、互いを含まない上位カテゴリが複数ある場合は、その識別値のビットパターンも、互いを含んではなりません。

0x0008「HERO」    -> 0(0000)
0x3008「E・HERO」-> 3(0011)
0x5008「V・HERO」-> 5(0101)
0x6008「E-HERO」-> 6(0110)
0xA008「M・HERO」-> A(1010)
0xC008「D・HERO」-> C(1100)
  ^ここ

 1の立っている場所が少しづつずらされていることが分かると思います。

判定の実例

 以上をふまえると、カードがカテゴリに含まれるかどうかを判定する時に、どのような処理が行われているのか推測できます。
 以下で「CNo.107 超銀河眼の時空龍」が「銀河眼」に含まれるか?を例に説明してみます。

 まずプログラムはそのカードのsetcodeを参照し、数値を2バイトごとに区切ります。

「CNo.107 超銀河眼の時空龍」
setcode = 0x307b1048 -> 307b, 1048

 そして、区切った値と判定したい値の、下位24ビット同士を比較し、一致するか調べます。一致しなければ次の区切りに移ります。

307b  107b「銀河眼」
 ^^^   ^^^

 上の通り0x07bで一致しています。(0x07bは「ギャラクシー」を示します)
 一致したなら、次に区切った値の上位8ビットのビットパターンが、判定対象の上位8ビットのビットパターンを含むものか確認します。含まなければまた次の区切りに移ってやり直します。

307b  107b「銀河眼」
^     ^

 3は1のビットパターンを全て含んでいるので成功です。これで「CNo.107 超銀河眼の時空龍」が「銀河眼」に属することが確認できました。

 ややこしいやり方ですが、単純に値を結合するとカテゴリ値が大きくなりすぎるので、そのための対策だと思います。
 (とはいえ、setcodeに使用されているSQLITE3のINTEGER型の最大サイズは8バイトなので、この方法であっても、互いを含まないカテゴリ5つ以上に同時に属するカードが出てきた場合には、8バイトでは収まりきらなくなってしまうでしょう)

オリジナルカテゴリの作り方

 長々と書きましたが、上記を踏まえてオリジナルカテゴリの作り方をまとめてみます。

  • 全く新しいカテゴリを作る場合
     単に0x0~FFFの範囲で被らない新しい値をsetcodeに設定するだけです。
  • 既存のカテゴリを拡張する場合
     前述の通りビットパターンに注意します。
     例えば「XX-セイバー」から「XXX-セイバー」を作るなら、
    下3桁 = 0x00d「セイバー」
    上1桁 = 0x100d「X-セイバー」の1(001)と
            0x300d「XX-セイバー」の3(011)を共に含む数
           (0x7(111), 0xb(1011)、0xf(1111)など)
     という値にする必要があります。
     これらを満たす値、例えば0x700dを設定してやれば、同時に「X-セイバー」「XX-セイバー」にも属することになり、既存のサポートを受けることもできる、というわけです。
    (ビットパターン的に、「XXXX-セイバー」は作れるが、「XXXXX-セイバー」は無理ということも分かります)

カテゴリ定数の一覧

 こちらに一覧があります。