オペコード全組み合わせテスト計画
概要
このドキュメントは、全オペコードと条件の組み合わせを体系的にテストするための計画です。
ゲーム状態(カード、エネルギー、デッキ、捨て札サイズなど)の変数を考慮した包括的なテストマトリックスを定義します。
1. オペコード分類
1.1 基本操作オペコード(Core Opcodes)
| オペコード |
ID |
説明 |
テスト優先度 |
O_DRAW |
10 |
カードを引く |
高 |
O_ADD_BLADES |
11 |
ブレード追加 |
高 |
O_ADD_HEARTS |
12 |
ハート追加 |
高 |
O_REDUCE_COST |
13 |
コスト削減 |
中 |
O_LOOK_DECK |
14 |
デッキを見る |
高 |
O_RECOVER_LIVE |
15 |
ライブ回復 |
高 |
O_BOOST_SCORE |
16 |
スコア増加 |
高 |
O_RECOVER_MEMBER |
17 |
メンバー回復 |
高 |
O_BUFF_POWER |
18 |
パワーバフ |
中 |
O_IMMUNITY |
19 |
免疫付与 |
中 |
O_MOVE_MEMBER |
20 |
メンバー移動 |
高 |
O_SWAP_CARDS |
21 |
カード交換 |
中 |
O_SEARCH_DECK |
22 |
デッキ検索 |
高 |
O_ENERGY_CHARGE |
23 |
エネルギーチャージ |
高 |
O_SET_BLADES |
24 |
ブレード設定 |
中 |
O_SET_HEARTS |
25 |
ハート設定 |
中 |
O_FORMATION_CHANGE |
26 |
フォーメーション変更 |
低 |
O_NEGATE_EFFECT |
27 |
効果無効化 |
高 |
O_ORDER_DECK |
28 |
デッキ順序変更 |
中 |
O_META_RULE |
29 |
メタルール |
中 |
1.2 選択・検索オペコード(Selection Opcodes)
| オペコード |
ID |
説明 |
テスト優先度 |
O_SELECT_MODE |
30 |
モード選択 |
高 |
O_MOVE_TO_DECK |
31 |
デッキに移動 |
高 |
O_TAP_OPPONENT |
32 |
相手をタップ |
高 |
O_PLACE_UNDER |
33 |
下に配置 |
中 |
O_REVEAL_CARDS |
40 |
カード公開 |
高 |
O_LOOK_AND_CHOOSE |
41 |
見て選ぶ |
高 |
O_CHEER_REVEAL |
42 |
チア公開 |
低 |
O_ACTIVATE_MEMBER |
43 |
メンバー活性化 |
高 |
O_ADD_TO_HAND |
44 |
手札に追加 |
高 |
O_COLOR_SELECT |
45 |
色選択 |
高 |
O_REPLACE_EFFECT |
46 |
効果置換 |
中 |
O_TRIGGER_REMOTE |
47 |
リモートトリガー |
中 |
O_REDUCE_HEART_REQ |
48 |
ハート要件削減 |
中 |
O_MODIFY_SCORE_RULE |
49 |
スコアルール変更 |
低 |
O_ADD_STAGE_ENERGY |
50 |
ステージエネルギー追加 |
中 |
O_SET_TAPPED |
51 |
タップ状態設定 |
高 |
O_ADD_CONTINUOUS |
52 |
継続効果追加 |
中 |
O_TAP_MEMBER |
53 |
メンバーをタップ |
高 |
1.3 特殊操作オペコード(Special Opcodes)
| オペコード |
ID |
説明 |
テスト優先度 |
O_PLAY_MEMBER_FROM_HAND |
57 |
手札からプレイ |
高 |
O_MOVE_TO_DISCARD |
58 |
捨て札に移動 |
高 |
O_GRANT_ABILITY |
60 |
アビリティ付与 |
中 |
O_INCREASE_HEART_COST |
61 |
ハートコスト増加 |
低 |
O_REDUCE_YELL_COUNT |
62 |
エール数削減 |
中 |
O_PLAY_MEMBER_FROM_DISCARD |
63 |
捨て札からプレイ |
高 |
O_PAY_ENERGY |
64 |
エネルギー支払い |
高 |
O_SELECT_MEMBER |
65 |
メンバー選択 |
高 |
O_DRAW_UNTIL |
66 |
指定枚数までドロー |
高 |
O_SELECT_PLAYER |
67 |
プレイヤー選択 |
中 |
O_SELECT_LIVE |
68 |
ライブ選択 |
高 |
O_REVEAL_UNTIL |
69 |
条件まで公開 |
高 |
O_INCREASE_COST |
70 |
コスト増加 |
低 |
O_PREVENT_PLAY_TO_SLOT |
71 |
スロットプレイ禁止 |
中 |
O_SWAP_AREA |
72 |
エリア交換 |
低 |
O_TRANSFORM_HEART |
73 |
ハート変換 |
中 |
O_SELECT_CARDS |
74 |
カード選択 |
高 |
O_OPPONENT_CHOOSE |
75 |
相手が選択 |
中 |
O_PLAY_LIVE_FROM_DISCARD |
76 |
捨て札からライブプレイ |
高 |
O_REDUCE_LIVE_SET_LIMIT |
77 |
ライブセット制限削減 |
低 |
O_PREVENT_ACTIVATE |
82 |
活性化禁止 |
中 |
O_ACTIVATE_ENERGY |
81 |
エネルギー活性化 |
高 |
O_PREVENT_SET_TO_SUCCESS_PILE |
80 |
成功山札への配置禁止 |
低 |
O_PREVENT_BATON_TOUCH |
90 |
バトンタッチ禁止 |
中 |
O_SET_HEART_COST |
83 |
ハートコスト設定 |
中 |
2. 条件分類
2.1 カウント条件(Count Conditions)
| 条件 |
ID |
説明 |
テスト変数 |
C_COUNT_STAGE |
203 |
ステージ枚数 |
0, 1, 2, 3 |
C_COUNT_HAND |
204 |
手札枚数 |
0, 1, 3, 5, 7, 10 |
C_COUNT_DISCARD |
205 |
捨て札枚数 |
0, 1, 3, 5, 10 |
C_COUNT_ENERGY |
213 |
エネルギー枚数 |
0, 1, 3, 5 |
C_COUNT_SUCCESS_LIVE |
218 |
成功ライブ数 |
0, 1, 2, 3 |
C_COUNT_LIVE_ZONE |
230 |
ライブゾーン枚数 |
0, 1, 2, 3 |
C_COUNT_GROUP |
208 |
グループ枚数 |
0, 1, 2, 3 |
C_COUNT_HEARTS |
223 |
ハート数 |
0, 1, 5, 10 |
C_COUNT_BLADES |
224 |
ブレード数 |
0, 1, 3, 5 |
2.2 状態条件(State Conditions)
| 条件 |
ID |
説明 |
テスト変数 |
C_TURN_1 |
200 |
ターン1かどうか |
true, false |
C_IS_CENTER |
206 |
センターかどうか |
true, false |
C_LIFE_LEAD |
207 |
ライフリード |
true, false |
C_HAS_MEMBER |
201 |
メンバー所持 |
card_id |
C_HAS_COLOR |
202 |
色所持 |
color_idx |
C_HAS_LIVE_CARD |
214 |
ライブカード所持 |
true, false |
C_HAND_HAS_NO_LIVE |
217 |
手札にライブなし |
true, false |
C_DECK_REFRESHED |
227 |
デッキリフレッシュ済み |
true, false |
C_HAS_MOVED |
228 |
移動済み |
true, false |
C_HAND_INCREASED |
229 |
手札増加済み |
true, false |
C_BATON |
231 |
バトン状態 |
true, false |
2.3 比較条件(Comparison Conditions)
| 条件 |
ID |
説明 |
テスト変数 |
C_COST_CHECK |
215 |
コスト確認 |
threshold, LE/GE |
C_RARITY_CHECK |
216 |
レアリティ確認 |
rarity |
C_SCORE_COMPARE |
220 |
スコア比較 |
diff |
C_OPPONENT_HAND_DIFF |
219 |
相手手札差 |
diff |
C_OPPONENT_ENERGY_DIFF |
225 |
相手エネルギー差 |
diff |
C_COST_LEAD |
240 |
コストリード |
true, false |
C_SCORE_LEAD |
241 |
スコアリード |
true, false |
C_HEART_LEAD |
242 |
ハートリード |
true, false |
C_COST_COMPARE |
246 |
コスト比較 |
diff |
C_BLADE_COMPARE |
247 |
ブレード比較 |
diff |
C_HEART_COMPARE |
248 |
ハート比較 |
diff |
2.4 フィルター条件(Filter Conditions)
| 条件 |
ID |
説明 |
テスト変数 |
C_GROUP_FILTER |
209 |
グループフィルター |
group_id |
C_SELF_IS_GROUP |
211 |
自分のグループ |
group_id |
C_TYPE_CHECK |
232 |
タイプ確認 |
member/live |
C_IS_IN_DISCARD |
233 |
捨て札にいる |
true, false |
C_AREA_CHECK |
234 |
エリア確認 |
area |
C_OPPONENT_HAS |
210 |
相手が所持 |
card_id |
C_OPPONENT_HAS_WAIT |
249 |
相手がWAIT状態 |
count |
3. ゲーム状態変数
3.1 プレイヤー状態
struct PlayerStateVariables {
hand_size: usize,
deck_size: usize,
discard_size: usize,
energy_size: usize,
live_zone_size: usize,
success_lives_size: usize,
stage: [i32; 3],
stage_tapped: [bool; 3],
blade_buffs: [i32; 3],
heart_buffs: [[u8; 7]; 3],
live_score_bonus: i32,
has_moved: bool,
hand_increased: bool,
deck_refreshed: bool,
}
3.2 グローバル状態
struct GlobalStateVariables {
turn: i32,
current_player: usize,
phase: Phase,
modal_answer: i32,
}
4. テストマトリックス
4.1 ドロー系オペコードテスト
O_DRAW テストマトリックス
| テストID |
デッキサイズ |
手札サイズ |
ドロー数 |
期待結果 |
| DRAW-01 |
5 |
0 |
1 |
hand=1, deck=4 |
| DRAW-02 |
5 |
5 |
3 |
hand=8, deck=2 |
| DRAW-03 |
0 |
3 |
1 |
デッキリフレッシュ発生 |
| DRAW-04 |
2 |
7 |
3 |
hand=9, deck=0, refresh=1 |
| DRAW-05 |
10 |
0 |
10 |
hand=10, deck=0 |
O_DRAW_UNTIL テストマトリックス
| テストID |
デッキサイズ |
現在手札 |
目標枚数 |
ドロー数 |
期待結果 |
| DUNTIL-01 |
10 |
2 |
5 |
3 |
hand=5 |
| DUNTIL-02 |
10 |
7 |
5 |
0 |
hand=7(変更なし) |
| DUNTIL-03 |
2 |
3 |
7 |
2 |
hand=5, deck=0 |
| DUNTIL-04 |
0 |
3 |
5 |
refresh |
リフレッシュ後ドロー |
4.2 回復系オペコードテスト
O_RECOVER_MEMBER テストマトリックス
| テストID |
捨て札内容 |
フィルター |
期待結果 |
| RECM-01 |
[M1, M2, M3] |
なし |
いずれか1枚回復 |
| RECM-02 |
[M1(cost=3), M2(cost=5)] |
cost<=4 |
M1のみ選択可能 |
| RECM-03 |
[L1, L2] |
type=member |
選択不可 |
| RECM-04 |
[] |
なし |
効果なし |
| RECM-05 |
[M1(μ's), M2(Aqours)] |
group=μ's |
M1のみ選択可能 |
O_RECOVER_LIVE テストマトリックス
| テストID |
捨て札内容 |
フィルター |
期待結果 |
| RECL-01 |
[L1, L2] |
なし |
いずれか1枚回復 |
| RECL-02 |
[L1(μ's), L2(Aqours)] |
group=μ's |
L1のみ選択可能 |
| RECL-03 |
[M1, M2] |
type=live |
選択不可 |
| RECL-04 |
[L1(hearts=8)] |
hearts>=5 |
L1選択可能 |
4.3 検索・選択系オペコードテスト
O_LOOK_AND_CHOOSE テストマトリックス
| テストID |
デッキ内容 |
見る枚数 |
選択枚数 |
フィルター |
期待結果 |
| LAC-01 |
[M1, M2, M3, M4, M5] |
3 |
1 |
なし |
1枚handへ、2枚discard |
| LAC-02 |
[M1(cost=3), M2(cost=5), M3(cost=2)] |
3 |
1 |
cost>=4 |
M2のみ選択可能 |
| LAC-03 |
[L1, M1, M2] |
3 |
1 |
type=live |
L1のみ選択可能 |
| LAC-04 |
[M1, M2] |
5 |
1 |
なし |
デッキ不足で2枚のみ |
| LAC-05 |
[M1(μ's), M2(Aqours), M3(μ's)] |
3 |
2 |
group=μ's |
M1, M3選択可能 |
O_REVEAL_UNTIL テストマトリックス
| テストID |
デッキ内容 |
条件 |
期待結果 |
| REVU-01 |
[M1, M2, L1, M3] |
type=live |
L1をhandへ、M1,M2をdiscard |
| REVU-02 |
[M1, M2, M3] |
type=live |
全枚discard、条件不一致 |
| REVU-03 |
[M1(cost=2), M2(cost=5), M3] |
cost>=4 |
M2をhandへ、M1をdiscard |
| REVU-04 |
[L1, L2, L3] |
type=live |
L1をhandへ |
4.4 エネルギー系オペコードテスト
O_PAY_ENERGY テストマトリックス
| テストID |
エネルギー数 |
タップ済み |
支払い数 |
期待結果 |
| PAYE-01 |
3 |
0 |
1 |
tapped=1, energy=3 |
| PAYE-02 |
3 |
1 |
2 |
tapped=3, energy=3 |
| PAYE-03 |
2 |
0 |
3 |
支払い不可 |
| PAYE-04 |
5 |
2 |
3 |
tapped=5 |
| PAYE-05 |
0 |
0 |
1 |
支払い不可 |
O_ACTIVATE_ENERGY テストマトリックス
| テストID |
エネルギー数 |
活性化数 |
期待結果 |
| ACTE-01 |
3 |
2 |
tapped=2 |
| ACTE-02 |
3 |
5 |
全枚タップ |
| ACTE-03 |
0 |
1 |
効果なし |
4.5 タップ系オペコードテスト
O_TAP_OPPONENT テストマトリックス
| テストID |
相手ステージ |
フィルター |
タップ数 |
期待結果 |
| TAPO-01 |
[M1, M2, M3] |
なし |
1 |
1枚タップ |
| TAPO-02 |
[M1(cost=2), M2(cost=5)] |
cost<=3 |
1 |
M1のみタップ可能 |
| TAPO-03 |
[M1(tapped), M2] |
なし |
1 |
M2タップ |
| TAPO-04 |
[M1, M2] |
tapped=true |
1 |
既にタップ済みは対象外 |
| TAPO-05 |
[-1, -1, -1] |
なし |
1 |
効果なし |
O_SET_TAPPED テストマトリックス
| テストID |
対象 |
現在状態 |
設定値 |
期待結果 |
| SETT-01 |
stage[0] |
untapped |
1 |
tapped |
| SETT-02 |
stage[0] |
tapped |
0 |
untapped |
| SETT-03 |
stage[0] |
tapped |
1 |
tapped(変更なし) |
4.6 スコア・バフ系オペコードテスト
O_BOOST_SCORE テストマトリックス
| テストID |
現在スコア |
増加値 |
期待結果 |
| BOOS-01 |
0 |
3 |
score=3 |
| BOOS-02 |
1000 |
5 |
score=1005 |
| BOOS-03 |
0 |
0 |
score=0 |
O_ADD_BLADES テストマトリックス
| テストID |
現在ブレード |
追加数 |
対象 |
期待結果 |
| ADDB-01 |
0 |
2 |
player |
blades=2 |
| ADDB-02 |
3 |
1 |
member[0] |
blade_buffs[0]=1 |
| ADDB-03 |
0 |
0 |
player |
blades=0 |
O_ADD_HEARTS テストマトリックス
| テストID |
現在ハート |
追加数 |
色 |
期待結果 |
| ADDH-01 |
[0,0,0,0,0,0,0] |
2 |
pink |
heart_buffs[0]=2 |
| ADDH-02 |
[1,1,0,0,0,0,0] |
1 |
blue |
heart_buffs[2]=1 |
| ADDH-03 |
[0,0,0,0,0,0,0] |
0 |
pink |
変化なし |
4.7 条件分岐テスト
C_COUNT_HAND 条件テスト
| テストID |
手札枚数 |
閾値 |
比較 |
期待結果 |
| CCH-01 |
3 |
3 |
>= |
true |
| CCH-02 |
3 |
4 |
>= |
false |
| CCH-03 |
0 |
1 |
>= |
false |
| CCH-04 |
10 |
5 |
>= |
true |
C_COST_CHECK 条件テスト
| テストID |
カードコスト |
閾値 |
比較 |
期待結果 |
| CCOST-01 |
5 |
5 |
>= |
true |
| CCOST-02 |
5 |
5 |
<= |
true |
| CCOST-03 |
3 |
5 |
>= |
false |
| CCOST-04 |
7 |
5 |
<= |
false |
C_LIFE_LEAD 条件テスト
| テストID |
P0成功ライブ |
P1成功ライブ |
期待結果 |
| CLIF-01 |
2 |
1 |
true |
| CLIF-02 |
1 |
2 |
false |
| CLIF-03 |
1 |
1 |
false |
| CLIF-04 |
0 |
0 |
false |
5. 複合テストシナリオ
5.1 コスト支払い+効果の複合テスト
#[test]
fn test_cost_discard_hand_with_filter() {
let hand = vec![Ayumu, Kanon, Kaho, Other];
}
#[test]
fn test_cost_pay_energy_with_insufficient() {
}
5.2 連鎖効果テスト
#[test]
fn test_on_leaves_trigger_chain() {
}
#[test]
fn test_trigger_remote_chain() {
}
5.3 エッジケーステスト
#[test]
fn test_empty_zone_operations() {
}
#[test]
fn test_full_zone_operations() {
}
6. テスト実装構造
6.1 テストヘルパー関数
struct GameStateBuilder {
state: GameState,
}
impl GameStateBuilder {
fn new() -> Self;
fn with_hand(mut self, cards: Vec<i32>) -> Self;
fn with_deck(mut self, cards: Vec<i32>) -> Self;
fn with_discard(mut self, cards: Vec<i32>) -> Self;
fn with_energy(mut self, cards: Vec<i32>) -> Self;
fn with_stage(mut self, slot: usize, card_id: i32) -> Self;
fn with_success_lives(mut self, cards: Vec<i32>) -> Self;
fn with_tapped(mut self, slot: usize, tapped: bool) -> Self;
fn build(self) -> GameState;
}
fn assert_hand_size(state: &GameState, player: usize, expected: usize);
fn assert_deck_size(state: &GameState, player: usize, expected: usize);
fn assert_discard_size(state: &GameState, player: usize, expected: usize);
fn assert_score(state: &GameState, player: usize, expected: i32);
fn assert_blades(state: &GameState, player: usize, expected: i32);
fn assert_tapped(state: &GameState, player: usize, slot: usize, expected: bool);
6.2 テストファイル構成
engine_rust_src/src/
├── opcode_tests/
│ ├── mod.rs
│ ├── draw_tests.rs # O_DRAW, O_DRAW_UNTIL
│ ├── recover_tests.rs # O_RECOVER_MEMBER, O_RECOVER_LIVE
│ ├── search_tests.rs # O_LOOK_DECK, O_SEARCH_DECK, O_LOOK_AND_CHOOSE
│ ├── reveal_tests.rs # O_REVEAL_CARDS, O_REVEAL_UNTIL
│ ├── energy_tests.rs # O_PAY_ENERGY, O_ACTIVATE_ENERGY, O_ENERGY_CHARGE
│ ├── tap_tests.rs # O_TAP_OPPONENT, O_SET_TAPPED, O_TAP_MEMBER
│ ├── score_tests.rs # O_BOOST_SCORE, O_SET_SCORE
│ ├── buff_tests.rs # O_ADD_BLADES, O_ADD_HEARTS, O_BUFF_POWER
│ ├── move_tests.rs # O_MOVE_MEMBER, O_MOVE_TO_DECK, O_MOVE_TO_DISCARD
│ ├── select_tests.rs # O_SELECT_MODE, O_SELECT_MEMBER, O_SELECT_CARDS
│ └── condition_tests.rs # 全条件テスト
├── integration_tests/
│ ├── chain_effects.rs # 連鎖効果テスト
│ ├── edge_cases.rs # エッジケーステスト
│ └── full_game_flow.rs # ゲームフローテスト
└── test_helpers.rs
7. テスト実行戦略
7.1 ユニットテスト
- 各オペコード単体のテスト
- 各条件単体のテスト
- パラメータ化テストでバリエーションをカバー
7.2 統合テスト
- 複数オペコードの組み合わせ
- トリガー連鎖
- ゲームフェーズ遷移
7.3 プロパティベーステスト
use proptest::prelude::*;
proptest! {
#[test]
fn test_draw_never_exceeds_max(
deck_size in 0usize..50,
hand_size in 0usize..10,
draw_count in 1usize..5
) {
}
#[test]
fn test_energy_payment_never_negative(
energy in 0usize..10,
tapped in 0usize..10,
payment in 1usize..5
) {
}
}
8. 実カードを使用したテスト
8.1 実カードデータの活用
テストでは load_real_db() を使用して実際のカードデータベースを読み込みます:
use crate::test_helpers::load_real_db;
fn get_card_id(db: &CardDatabase, card_no: &str) -> i32 {
db.card_no_to_id.get(card_no).copied().expect("Card not found")
}
8.2 実カードテストケース
O_RECOVER_MEMBER テスト(実カード使用)
| テストID |
カード |
日本語テキスト |
テスト内容 |
| RECM-R01 |
PL!-sd1-001-SD |
登場:自分の控え室からライブカードを1枚手札に加える |
discard=[L1], handにL1追加 |
| RECM-R02 |
PL!-sd1-002-SD |
起動:控え室からメンバーカードを1枚手札に加える |
discard=[M1], handにM1追加 |
| RECM-R03 |
PL!-sd1-003-SD |
登場:控え室からコスト4以下のμ'sメンバーを1枚手札に加える |
フィルター条件確認 |
O_LOOK_AND_CHOOSE テスト(実カード使用)
| テストID |
カード |
日本語テキスト |
テスト内容 |
| LAC-R01 |
PL!-sd1-004-SD |
登場:デッキ上5枚を見てμ'sライブを1枚手札に加える |
フィルター: group=μ's, type=live |
| LAC-R02 |
PL!-sd1-005-SD |
登場:デッキ上3枚を見て1枚手札に加え、残りをデッキに戻す |
順序選択テスト |
O_PAY_ENERGY テスト(実カード使用)
| テストID |
カード |
日本語テキスト |
テスト内容 |
| PAYE-R01 |
LL-bp3-001-R+ |
ライブ開始時:エネルギー6支払い、ブレード+3 |
energy=6, blades+=3 |
| PAYE-R02 |
LL-bp3-001-R+ |
エネルギー不足時 |
energy=3, 効果発動不可 |
O_DISCARD_HAND(コスト)テスト(実カード使用)
| テストID |
カード |
日本語テキスト |
テスト内容 |
| DISC-R01 |
LL-bp1-001-R+ |
手札の「歩夢/かのん/花帆」を3枚捨ててスコア+3 |
フィルター条件確認 |
| DISC-R02 |
LL-bp1-001-R+ |
フィルター不一致 |
hand=[Other], 効果発動不可 |
8.3 実カードテストコード例
#[test]
fn test_real_card_pl_sd1_001_honoka() {
let db = load_real_db();
let card_id = get_card_id(&db, "PL!-sd1-001-SD");
let mut state = create_test_state();
state.ui.silent = true;
state.players[0].success_lives = vec![
get_card_id(&db, "PL!-sd1-020-SD"),
get_card_id(&db, "PL!-sd1-021-SD"),
];
let live_in_discard = get_card_id(&db, "PL!-sd1-022-SD");
state.players[0].discard = vec![live_in_discard];
let ctx = AbilityContext {
player_id: 0,
source_card_id: card_id,
..Default::default()
};
state.trigger_abilities(&db, TriggerType::OnPlay, &ctx);
assert!(state.players[0].hand.contains(&live_in_discard),
"ライブカードが手札に追加されるべき");
}
#[test]
fn test_real_card_ll_bp1_001_ayumu_kanon_kaho() {
let db = load_real_db();
let card_id = get_card_id(&db, "LL-bp1-001-R+");
let mut state = create_test_state();
state.ui.silent = true;
state.phase = Phase::PerformanceP1;
let ayumu = find_card_by_char_name(&db, "歩夢");
let kanon = find_card_by_char_name(&db, "かのん");
let kaho = find_card_by_char_name(&db, "花帆");
state.players[0].hand = vec![ayumu, kanon, kaho, 9999];
let ctx = AbilityContext {
player_id: 0,
source_card_id: card_id,
..Default::default()
};
state.trigger_abilities(&db, TriggerType::OnLiveStart, &ctx);
assert_eq!(state.players[0].live_score_bonus, 3,
"スコア+3されるべき");
}
8.4 実カードID参照テーブル
| カード番号 |
card_id |
名前 |
主なオペコード |
| PL!-sd1-001-SD |
1 |
高坂 穂乃果 |
O_RECOVER_LIVE, O_ADD_BLADES |
| PL!-sd1-002-SD |
2 |
絢瀬 絵里 |
O_RECOVER_MEMBER |
| PL!-sd1-003-SD |
3 |
南 ことり |
O_RECOVER_MEMBER, O_ADD_HEARTS |
| PL!-sd1-004-SD |
4 |
園田 海未 |
O_LOOK_AND_CHOOSE |
| PL!-sd1-005-SD |
5 |
星空 凛 |
O_LOOK_AND_CHOOSE |
| LL-bp1-001-R+ |
9 |
上原歩夢&澁谷かのん&日野下花帆 |
O_RECOVER_MEMBER, O_DISCARD_HAND, O_BOOST_SCORE |
9. 優先順位と実装順序
Phase 1: 基本オペコード(実カード使用) (高優先度)
- O_DRAW, O_ADD_BLADES, O_ADD_HEARTS
- O_RECOVER_MEMBER, O_RECOVER_LIVE
- O_PAY_ENERGY, O_ACTIVATE_ENERGY
- 実カード: PL!-sd1-001〜005
Phase 2: 選択・検索オペコード(実カード使用) (高優先度)
- O_LOOK_AND_CHOOSE, O_REVEAL_UNTIL
- O_SELECT_MODE, O_SELECT_MEMBER
- 実カード: PL!-sd1-004, PL!-sd1-005
Phase 3: 条件テスト(実カード使用) (中優先度)
- C_COUNT_*, C_COST_CHECK
- C_LIFE_LEAD, C_HAS_*
- 実カード: LL-bp1-001-R+
Phase 4: 複合・統合テスト (中優先度)
Phase 5: エッジケース (低優先度)