WSN追加案(関数): 効果系カードの取り扱い
効果系カード(特殊技能・アイテム・召喚獣)を式で扱う仕組みを用意する必要があります。
まずカードをどのように特定するかが問題です。2~3種類のアプローチが考えられます。
- カードにフィールド全体の通し番号を振る
-
キャラクターと荷物袋の中で通し番号を振る
- 特殊技能・アイテム・召喚獣で個別に通し番号を振る
- 全てまとめて通し番号を振る
1.を選んだ場合、パフォーマンスなどいろいろ技術的な問題が出てきそうです。2.を選ぶ場合、関係関数の引数が増えます。
例えば2.-b.を選んだ場合、以下のように関数呼び出しがかなり煩わしい事になります(この例ではカードの種類に番号を振って特殊技能=1とする)。
CARDNAME(SELECTED(), 1, FINDCARD(SELECTED(), 1, "*"))
ただ、大雑把に扱いすぎない方が技術的な妥当性が高いので、後々の拡張が容易になるはずです。シグネチャの煩雑さは我慢するべきなのかもしれません。
いずれにせよ、最初の選択が肝要になるので、時間をかけて検討する必要があると思います。
Comments (16)
-
reporter -
reporter 上記の案の最大の問題は、一つのカードを単一のパラメータで表す方法が無い事です。場合によっては恐ろしく使い勝手が悪くなってしまうかもしれません。色々なケースを検討する必要があります。
-
reporter 選択カードを返す関数を用意するとして、上記の案では2~3件の関数が必要になってきます。
SELECTEDCARD_CAST() → 選択カードを持つキャスト番号、または荷物袋(-1)
SELECTEDCARD_TYPE() → 選択カードのタイプ
SELECTEDCARD_NUMBER() → 選択カードの通し番号
明らかに使い勝手が最悪です。また、フィールド全体のキーコードを検索して見つかったカードを返す関数を用意するとして、その戻り値にも同じ問題が発生します。たとえば以下のような式を書くのは明らかに馬鹿げていますし、パフォーマンス的にも無駄が多いです。
CARDNAME(FINDKEYCODE_CAST(0, “攻撃“), FINDKEYCODE_TYPE(0, “攻撃“), FINDKEYCODE_NUMBER(0, “攻撃“))
やはり全体通し番号の方がいいかもしれません。
他の選択肢を検討しようとすると、複合パラメータのような新しい文法が必要になってきます。
-
reporter 全体通し番号だと以下のようになります。
<関数名>(<通し番号>, <関数ごとの引数> ...)
選択カードのカード名を取る処理は以下のように簡潔になります。
CARDNAME(SELECTEDCARD())
通し番号式の問題は、特定のキャラクターが持っているカードだけ検索するような処理が煩雑になる事です。選択メンバが持っているアイテムカードを名前によって検索するといったような場合、追加のパラメータが必要になります。
FINDCARD("*", SELECTED(), 2)
-
reporter しばらく考えていたのですが、複数の通し番号(+種カード類)で表現した方が後々よさそうなので、それをどう簡潔に実現するか考えています。
リストを使う、連想配列を新たに用意して使う、構造体的なものを定義して使えるようにする、といった案がありますが、将来の事を考えるとやはり専用のオブジェクトを用意できる構造体的なものを用意する方法がよさそうに思えます。
後で仕様を考えます。
-
reporter #1020を立てました。
-
reporter -
CARDTYPE
ですが、アクションカードが考慮されていないように見えますが、アクションカードは選択カードにできないんでしたっけ… -
reporter 選択カードにできます。
実装時に考えていた事をコメントに書くのを忘れてたんですが、アクションカードとその枠をカード情報でどう表現するかに悩んでいます。
- アクションカードは戦闘時の手札です。所持カードの枠はありません。
- 戦闘時の手札という枠を設けると、効果系カードがどちらの枠に属しているか曖昧になります(手札にある特殊技能やアイテムはどちらの枠に属しているのか?)。
いまのところアクションカードだけ例外としてその枠に行くようにする形がよさそうかなぁと考えているのですが、実装まではまだしていません。
このようにアクションカードは特殊なので、カードタイプの番号は
-1
とかでよさそうです。
-
reporter しばらく考えているのですが、戦闘時の手札という枠は筋が悪そうな気がしています。上の1.と2.がややこしくなる理由は、そもそも手札枠とカード所持枠が別物だからです。インスタンス化とでも呼ぶべきか、特殊技能カードの所持枠にあるカードはバトル時に何枚も配付されてきます。しかしカード情報が相手にしているのはインスタンスではなく本体の方なのです。
アクションカードも事情は同じです。手札や山札には複数の同一アクションカードがありますが、処理対象となるのはその複数カードの元になるアクションカード自体のデータです。そうなると、
CARDINFO
にACTIONCARDID
のようなパラメータを設けて、IDによってアクションカードを表現できた方がいいのかもしれません。 -
reporter とりあえず上記の
ACTIONCARDID
を設けました。また、後々のために構造体の内容をある程度隠蔽する仕組みを設けました(#1020)。アクションカードの場合、
CARDRARITY
やCARDPRICE
やCARDCOUNT
は意味のある値を返せません。とりあえず希少度や価格はスキンの定義そのままを、回数は0
を返すようにしてありますが、これは-1
のようなエラー値でもいいかもしれません。 -
reporter https://bitbucket.org/k4nagatsuki/cardwirthpy-reboot/issues/653/#comment-60539415
アクションカードの場合、
CARDTYPE
が-1
を返すと書くのを忘れていました。シンボルの定義も必要です。 -
reporter ACTIONという単語が一般的過ぎるので迷ったあげく
ACTIONCARD
にしました。 -
reporter #910で改行を扱えるようになったので、カード解説の取り扱いが可能になります。
CARDDESC(カード情報) -> 文字列
という形になるかと思います。これまでシナリオ側から取得できなかった情報なので、問題が起きないかちょっと考えてみます。
-
reporter カードの一致性判定のために無意味な文字列を末尾にくっつけているような場合、使い方によっては問題が出るかもしれません。
取り扱いに注意を要するデメリットと取得できるメリットだと後者の方が上回りそうな気がします。
-
reporter CARDDESC
をやるなら普通に考えてCASTDESC
も必要で、そしてCWには歴史的に「キャラクターの解説文はエディタによって折り返し位置に改行が入れられる(そうしないとクラシックエンジンでは正しく表示されない)」という問題があった事を思い出して頭を抱えています。とりあえず保留にします。
- Log in to comment
今のところ以下の形を考えています。
<関数名>(<キャスト番号(-1=荷物袋>, <カード種類(0=全て,1=特殊技能,2=アイテム,3=召喚獣>, <通し番号>, <関数ごとの引数> ...)
煩雑ではありますが、問題は起きにくいはずです(結局複雑なものを表現するには複雑な構造が必要みたいです)。荷物袋が
-1
なのは、該当キャストが存在しない時の戻り値0
との混同を防ぐためです。