ごっこ遊び(シナリオの実装例)-2
2005年6月15日 SCENA仕様メモTimeStopが解決に入る直前のシナリオスタックは↓のような感じ。
[SP]=5 //スタックポインタ
[SENA_STK] //シナリオスタック
LV, SENA_NM
-----------------------------------
5, ’MTG_SENA_PRIOT’
4, ’MTG_SENA_PH_BGN_UPK’
3, ’MTG_SENA_PH_BGN’
2, ’MTG_SENA_APP_PHASE’
1, ’MTG_SENA_APP_PHASE_LOOP’
------------------------------------
で、5解決に入ってクリンナップしてるとき。
[SP]=7 //スタックポインタ
[SENA_STK] //シナリオスタック
LV, SENA_NM
-----------------------------------
7, ’MTG_SENA_PH_END_CUP’
6, ’MTG_CARD_Time_Stop_Effect0’
5, ’MTG_SENA_PRIOT’
:
(略)
------------------------------------
「残りのフェイズステップをすっとばして、フェイズ一式を終了させる」とき。
[SP]=6 //スタックポインタ
[SENA_STK] //シナリオスタック
LV, SENA_NM
-----------------------------------
6, ’MTG_CARD_Time_Stop_Effect0’
5, ’MTG_SENA_PRIOT’
4, ’MTG_SENA_PH_BGN_UPK’
3, ’MTG_SENA_PH_BGN’
2, ’MTG_SENA_APP_PHASE’
1, ’MTG_SENA_APP_PHASE_LOOP’
------------------------------------
DBのストアドでなにをしなきゃいけないかというと、
スタックを遡りながら
1.パラメタで示されたシナリオまでのシナリオスタックを全てDELETEする。
2.親シナリオで発生した一時的なスタックやヒープがあれば削除する。
T-SQLのストアドだと多分こんな感じ。
昔一回使ったきりだからよく覚えてないけど・・。
CREATE PROCEDURE MTG_APP_EXIT_TO (@argSNM VARCHAR(32))
AS
BEGIN
-- 引数のチェック
DECLARE @plv INT;
SET @plv = SELECT LV FROM SENA_STK WHERE SNM = @argSNM;
IF @plv IS NULL
BEGIN
RAISERROR(どいつが親じゃゴルア!)
END;
-- シナリオスタックのお掃除。
-- スタックだけなら一挙に削ってしまえるがわざわざループにしてるのは
-- シナリオごとに「スコープやオーナがそのシナリオである」
-- スタックとヒープの掃除を正しくしてまわらなくちゃいけないと思ってるから。
-- たとえばFinal Fortuneは遅延効果を特定のプレイヤーのターン終了時に
-- 発生させるため、ターン終了時以外のトリガーに加え、"最終(Final)ターン"が
-- 始まったことを記録するための情報をヒープに確保する。
-- (DBでそんなところまで実装すべきじゃないが手抜きのためなら何でもする)
-- シナリオスタックの関係で言えばストーム持ちのカードがデッキに入ってる場合
--「フェイズ一式300.1」のシナリオを上書きした「ストーム入りフェイズ一式」の
-- シナリオを作成する。しかしこれは永続的な上書きなので書き換えられちゃ困る。
-- (ぱっと聞いただけだと意味不明だと思うけど)
DECLARE @lv INT;
DECLARE @snm VARCHAR(32);
DECLARE c CURSOR LOCAL FORWARD_ONLY STATIC FOR
SELECT LV,SENA_NM
FROM SENA_STK
WHERE LV >= @plv
ORDER BY LV DESC;
OPEN c;
FETCH NEXT FROM c INTO @lv, @snm;
WHILE @@FETCH_STATUS = 0
BEGIN
-- シナリオの変数スタックを削除。
EXEC MTG_DELETE_SENA_HEAP, @snm;
-- シナリオスタックを削除。
EXEC MTG_DELETE_SENA_STAK, @snm;
FETCH NEXT FROM c INTO @lv, @snm;
END;
CLOSE c;
DEALLOCATE c;
END;
考えがまとまるまでもう少しかな・・・。
[SP]=5 //スタックポインタ
[SENA_STK] //シナリオスタック
LV, SENA_NM
-----------------------------------
5, ’MTG_SENA_PRIOT’
4, ’MTG_SENA_PH_BGN_UPK’
3, ’MTG_SENA_PH_BGN’
2, ’MTG_SENA_APP_PHASE’
1, ’MTG_SENA_APP_PHASE_LOOP’
------------------------------------
で、5解決に入ってクリンナップしてるとき。
[SP]=7 //スタックポインタ
[SENA_STK] //シナリオスタック
LV, SENA_NM
-----------------------------------
7, ’MTG_SENA_PH_END_CUP’
6, ’MTG_CARD_Time_Stop_Effect0’
5, ’MTG_SENA_PRIOT’
:
(略)
------------------------------------
「残りのフェイズステップをすっとばして、フェイズ一式を終了させる」とき。
[SP]=6 //スタックポインタ
[SENA_STK] //シナリオスタック
LV, SENA_NM
-----------------------------------
6, ’MTG_CARD_Time_Stop_Effect0’
5, ’MTG_SENA_PRIOT’
4, ’MTG_SENA_PH_BGN_UPK’
3, ’MTG_SENA_PH_BGN’
2, ’MTG_SENA_APP_PHASE’
1, ’MTG_SENA_APP_PHASE_LOOP’
------------------------------------
DBのストアドでなにをしなきゃいけないかというと、
スタックを遡りながら
1.パラメタで示されたシナリオまでのシナリオスタックを全てDELETEする。
2.親シナリオで発生した一時的なスタックやヒープがあれば削除する。
T-SQLのストアドだと多分こんな感じ。
昔一回使ったきりだからよく覚えてないけど・・。
CREATE PROCEDURE MTG_APP_EXIT_TO (@argSNM VARCHAR(32))
AS
BEGIN
-- 引数のチェック
DECLARE @plv INT;
SET @plv = SELECT LV FROM SENA_STK WHERE SNM = @argSNM;
IF @plv IS NULL
BEGIN
RAISERROR(どいつが親じゃゴルア!)
END;
-- シナリオスタックのお掃除。
-- スタックだけなら一挙に削ってしまえるがわざわざループにしてるのは
-- シナリオごとに「スコープやオーナがそのシナリオである」
-- スタックとヒープの掃除を正しくしてまわらなくちゃいけないと思ってるから。
-- たとえばFinal Fortuneは遅延効果を特定のプレイヤーのターン終了時に
-- 発生させるため、ターン終了時以外のトリガーに加え、"最終(Final)ターン"が
-- 始まったことを記録するための情報をヒープに確保する。
-- (DBでそんなところまで実装すべきじゃないが手抜きのためなら何でもする)
-- シナリオスタックの関係で言えばストーム持ちのカードがデッキに入ってる場合
--「フェイズ一式300.1」のシナリオを上書きした「ストーム入りフェイズ一式」の
-- シナリオを作成する。しかしこれは永続的な上書きなので書き換えられちゃ困る。
-- (ぱっと聞いただけだと意味不明だと思うけど)
DECLARE @lv INT;
DECLARE @snm VARCHAR(32);
DECLARE c CURSOR LOCAL FORWARD_ONLY STATIC FOR
SELECT LV,SENA_NM
FROM SENA_STK
WHERE LV >= @plv
ORDER BY LV DESC;
OPEN c;
FETCH NEXT FROM c INTO @lv, @snm;
WHILE @@FETCH_STATUS = 0
BEGIN
-- シナリオの変数スタックを削除。
EXEC MTG_DELETE_SENA_HEAP, @snm;
-- シナリオスタックを削除。
EXEC MTG_DELETE_SENA_STAK, @snm;
FETCH NEXT FROM c INTO @lv, @snm;
END;
CLOSE c;
DEALLOCATE c;
END;
考えがまとまるまでもう少しかな・・・。
コメント