/* リネージュにおける防具や武器の強化について, jnethackから学んでみよう */
/* 実際にjnethackのコードを覗いて考えましょう */
/* !防具 */
/* !read.c の777行目〜942行目まで. JP版に関係ない部分がコメントになっていたが,
不要なので削除した */
case SCR_ENCHANT_ARMOR:
{
register schar s;
boolean special_armor;
boolean same_color;
// !some_armorは, 装備されている防具から一つを適当に選ぶ関数
// !従ってotmpは装備品へのポインタと考えてよい
otmp = some_armor(&youmonst);
// !防具の装備がない場合は, 特定のメッセージが出るが関係ないので削除
// !混乱している時の処理が入るが関係ないので削除
/* elven armor vibrates warningly when enchanted beyond a limit */
/* !エルフの防具は, 限界を超えて強化されると警告を発して震える */
// !special_armorは選択された防具がエルフ防具か,
// !自分が魔法使いかつとんがり帽子の場合にセットされる
special_armor = is_elven_armor(otmp) ||
(Role_if(PM_WIZARD) && otmp->otyp == CORNUTHAUM);
// !same_colorは,
// !巻物が呪われている場合は, 黒色ドラゴンの鱗鎧か黒色ドラゴンの鱗
// !巻物が呪われていない場合は, 銀色ドラゴンの鱗鎧か銀色ドラゴンの鱗か
// !リフレクションシールドの場合にセットされる
// !ただし, 盲目の場合はセットされない
if (sobj->cursed)
same_color =
(otmp->otyp == BLACK_DRAGON_SCALE_MAIL ||
otmp->otyp == BLACK_DRAGON_SCALES);
else
same_color =
(otmp->otyp == SILVER_DRAGON_SCALE_MAIL ||
otmp->otyp == SILVER_DRAGON_SCALES ||
otmp->otyp == SHIELD_OF_REFLECTION);
if (Blind) same_color = FALSE;
/* KMH -- catch underflow */
// !sは巻物が呪われている場合は, -防具の強化値
// !巻物が呪われていない場合は, 防具の強化値を示す
s = sobj->cursed ? -otmp->spe : otmp->spe;
// !rn2(x)は,0〜x-1の値をランダムに返す関数
// !従って, 次の条件文の意味は
// !s(防具強化値が), special_armorが真(エルフ防具等)の時は5より大きく,
// !それ以外(通常の防具)の時は3より大きい,
// !かつ, 0〜s(防具強化値)-1の範囲の乱数値が0以外の場合真になる
if (s > (special_armor ? 5 : 3) && rn2(s)) {
// !真になった場合は蒸発する(OE失敗)
Your("%sはしばらくの間激しく%s%s,蒸発した.",
xname(otmp),
Blind ? nul : jconj_adj(hcolor(sobj->cursed ? NH_BLACK : NH_SILVER)),
Blind ? "振動し" : "輝き");
if(is_cloak(otmp)) (void) Cloak_off();
if(is_boots(otmp)) (void) Boots_off();
if(is_helmet(otmp)) (void) Helmet_off();
if(is_gloves(otmp)) (void) Gloves_off();
if(is_shield(otmp)) (void) Shield_off();
if(otmp == uarm) (void) Armor_gone();
useup(otmp);
break;
}
// ! 次の文は非常に複雑である
// ! sの値は以下のようにして決まる
// ! 巻物が呪われている場合は -1
// ! 巻物が呪われていない場合,
// ! 防具強化値が9以上の場合, 0〜防具強化値-1の一様乱数が0を取った場合1
// 取らない場合は0
// ! 防具強化値が9より小さい場合
// ! 巻物が祝福されている場合, 1〜(3-防具強化値/3)の一様乱数
// ! 巻物が祝福されていない場合は 1
s = sobj->cursed ? -1 :
otmp->spe >= 9 ? (rn2(otmp->spe) == 0) :
sobj->blessed ? rnd(3-otmp->spe/3) : 1;
// ! ドラゴンの鱗の場合, ドラゴンの鱗鎧になるのだが, 関係ないので削除
// ! メッセージは重要な項目ではないのでコメント無し
Your("%sは%s%s%s%s.",
xname(otmp),
(s*s>1) ? "しばらくの間" : "一瞬",
s == 0 ? "激しく" : nul,
Blind ? nul :
jconj_adj(hcolor(sobj->cursed ? NH_BLACK : NH_SILVER)),
Blind ? "振動した" : "輝いた");
// nethackでは, 巻物が呪われていると防具も呪われる
otmp->cursed = sobj->cursed;
// !nethackでは, 巻物が祝福されていると防具も祝福される
if (!otmp->blessed || sobj->cursed)
otmp->blessed = sobj->blessed;
// !sの値分強化される
if (s) {
otmp->spe += s;
adj_abon(otmp, s);
known = otmp->known;
}
// !エルフ防具ならば5より大きく強化されると必ず,
// !通常防具ならば3より大きく強化されると1/6の確率で, 振動する
if ((otmp->spe > (special_armor ? 5 : 3)) &&
(special_armor || !rn2(7)))
Your("%sは突然%s振動した.",
xname(otmp),
Blind ? "また" : "思いもよらず");
break;
}
/*
さて, 重要なのは
・蒸発するかどうかを決める部分
・今回の強化値を決めている部分
になる.
1. 蒸発するかどうかを決める部分
これは簡単で, 強化値が3より大きい場合に, (強化値-1)/強化値の確率で蒸発する.
即ち, +4ならば3/4, +5ならば4/5, ….
これは強化値がいくつでも変わらない.
エルフ防具の場合は5より大きい場合となっているので,
+6ならば5/6, +7ならば6/7, ….
となるが, 基本は通常防具と変わらない.
蒸発するかしないかは, 巻物や防具の祝福, 呪いの如何に関わらない.
ただし, 呪われている場合は正負が逆になる.
即ち, 通常の防具の場合は-3より小さい場合に,
-(-強化値-1)/強化値の確率で蒸発する. 分かりにくいので例を示すと
-4ならば3/4, -5ならば4/5 ….
である. エルフ防具の場合は-5より小さい場合となる.
2. 今回の強化値を決めている部分.
こちらは少々複雑である. プログラムは効率よく(分かりにくく)かかれている
が, ここでは巻物の祝福の如何別に書いてみる.
2-1. 巻物が祝福も呪われもしていない場合.
強化値が+9より小さければ絶対に+1である.
強化値が+9以上の場合1/防具強化値の確率で+1になる.
(防具強化値-1)/防具強化値の確率で+0になる(強化されない).
通常防具
+0〜+3: 100% で+1
+4: 25% で+1 75% で蒸発
+5: 20% で+1 80% で蒸発
+6: 16.6%で+1 83.3%で蒸発
+7: 14.3%で+1 85.7%で蒸発
+8: 12.5%で+1 87.5%で蒸発
+9: 1.23%で+1 9.88%で+0 88.9%で蒸発
+10: 1% で+1 9% で+0 90% で蒸発
エルフ防具など
+0〜+5: 100% で+1
+6〜: 通常防具と同じ
2-2. 巻物が祝福されている場合
強化値が+0〜+2の場合 +1〜+3の間でランダムに決まる
強化値が+3〜+5の場合 +1〜+2の間でランダムに決まる
強化値が+6〜+8の場合 必ず+1である
強化値が+9以上の場合は, 2-1.と同様である.
(ちなみに, -2〜+0の場合 +1〜+3の間でランダムに決まり,
-5〜-3の場合 +1〜+4の間でランダムに決まり…
というように, 小さければ小さいほど大きい数字が出る可能性がある)
通常防具
+0〜+2: 33.3%で+1 33.3%で+2 33.3%で+3
+3: 50% で+1 50% で+2
+4: 12.5%で+1 12.5%で+2 75%で蒸発
+5: 10% で+1 10% で+2 80%で蒸発
+6〜: 2-1.と同じ
エルフ防具など
+0〜+2: 33.3%で+1 33.3%で+2 33.3%で+3
+3〜+5: 50% で+1 50%で+2
+6〜: 通常防具と同じ
2-3. 巻物が呪われている場合
強化値がいくつであろうと必ず-1になる.
通常防具
-3〜: 100% で-1
-4: 25% で-1 75%で蒸発
-5: 20% で-1 80%で蒸発
-6: 16.7%で-1 83.3%で蒸発
エルフ防具
-5〜: 100% で-1
〜-6: 通常防具と同じ
考察
前から言われているのと同様の結果となっていると思う.
ただ, c-zelを貼る場合は通常防具で-6まで安全だという噂を聞いたことがある.
これが事実だとすると今回の結果と反する.
(通常の防具は-4までが安全である)
では次に武器の方にいってみよう
*/
/* !read.cの1201行目〜1244行目 */
case SCR_ENCHANT_WEAPON:
// !混乱している時の処理ですが関係ない
if(uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))
&& confused) {
// …ずーっと続いて…
} else return !chwepon(sobj,
sobj->cursed ? -1 :
!uwep ? 1 :
uwep->spe >= 9 ? (rn2(uwep->spe) == 0) :
sobj->blessed ? rnd(3-uwep->spe/3) : 1);
// ! 結局chweaponという関数が関係するようだが, 第2引数が重要そうなので
// ! 見てみよう
// ! 巻物が呪われている場合は -1
// ! 巻物が呪われていない場合
// ! 装備している武器がなければ1
// ! 武器強化値が9以上の場合, 0〜武器強化値-1の一様乱数が0なら1, それ以外は0
// ! 武器強化値が9より小さい場合
// ! 巻物が祝福されていれば, 1〜(3-武器強化値/3)の一様乱数
// ! 巻物が祝福されていなければ 1
// ! これは防具の後半のsと同じ
break;
/* !wield.cの892行目〜1022行目 */
int
chwepon(otmp, amount)
register struct obj *otmp;
register int amount;
{
const char *color = hcolor((amount < 0) ? NH_BLACK : NH_BLUE);
const char *xtime;
int otyp = STRANGE_OBJECT;
// ! 装備している武器がなかったり, 強化できないものだった場合の処理
// ! 関係ないので削除
// ! ワームの歯というもので, さらに強化値が0以上だったら
// ! クリスナイフになるという処理だが全く関係ないので削除
// ! クリスナイフで強化値が負だったらワームの歯に戻るという処理だが
// ! やっぱり関係ないので削除
// ! 強化値が負の場合, 武器がアーティファクトなら助かるという処理だが
// ! 関係ないので削除
/* there is a (soft) upper and lower limit to uwep->spe */
/* ! 強化値には(柔らかい)上限と下限が存在する */
// ! 「柔らかい」の意味するところは, OEに成功すれば超えられるという
// ! ことだろうが, 失敗すると蒸発するので我々にとってはhardである ;-)
// ! 武器強化値が5より大きく強化値が0より大きい
// ! もしくは武器強化値が-5より小さく強化値が負,
// ! かつ
// ! 0〜2の一様乱数が0以外を取った場合
// ! 武器は蒸発する
if(((uwep->spe > 5 && amount >= 0) || (uwep->spe < -5 && amount < 0))
&& rn2(3)) {
if (!Blind)
Your("%sはしばらく激しく%s輝き,蒸発した.",
xname(uwep), jconj_adj(color));
else
Your("%sは蒸発した.", xname(uwep));
useupall(uwep); /* let all of them disappear */
return(1);
}
// ! メッセージは重要でないのでコメント無し
if (!Blind) {
xtime = (amount*amount == 1) ? "一瞬" : "しばらくの間";
Your("%sは%s%s%s輝いた.",
xname(uwep), xtime, jconj_adj(color),
amount == 0 ? "激しく" : "");
if (otyp != STRANGE_OBJECT && uwep->known &&
(amount > 0 || (amount < 0 && otmp->bknown)))
makeknown(otyp);
}
uwep->spe += amount;
if(amount > 0) uwep->cursed = 0;
// ! マジックベーンという特殊な武器に関する処理だが関係ないので削除
// ! エルフの武器かアーティファクトの場合は5を超えると必ず,
// ! 通常武器は5を超えると1/7の確率で, 振動する
/* elven weapons vibrate warningly when enchanted beyond a limit */
if ((uwep->spe > 5)
&& (is_elven_weapon(uwep) || uwep->oartifact || !rn2(7)))
Your("%sは突然震えだした.",
xname(uwep));
return(1);
}
/*
武器の場合は, まずはじめに今回の強化値を決める.
この決め方は防具の方と全く同じである.
次に蒸発の条件をきめるが,
強化値が+5より大きく今回の強化値が0以上の場合2/3の確率で蒸発する.
強化値が-5より小さく今回の強化値が-1以下の場合は2/3の確率で蒸発する.
ということである. 即ち, 蒸発の確率は武器の強化値に依存しない.
しかしながら, 今回の強化値が0の場合でも2/3の確率で蒸発するため,
+9の武器を強化するのは得策とは言えない.
巻物の祝福如何別に強化の確率を計算してみよう.
1. 巻物が祝福も呪われもされていない場合
+0〜+5: 100% で+1
+6〜+8: 33.3% で+1 66.6%で蒸発
+9: 3.7% で+1 29.6%で+0 66.6%で蒸発
+10: 3.3% で+1 30%で+0 66.6%で蒸発
+11: 3.03% で+1 30.3%で+0 66.6%で蒸発
2. 巻物が祝福されている場合
+0〜+2: 33.3% で+1 33.3%で+2 33.3%で+3
+3〜+5: 50% で+1 50% で+2
+6〜: 1.と同じ
3. 巻物が呪われている場合
-5〜: 100%で-1
〜-6: 33.3%で-1 66.6%で蒸発
考察
これも今まで考えられていたのと同じと言えるだろう.
注目すべきは +9 以上の武器の強化は, それまでの強化値に依存するものの
成功率はあまり変わらないということである.
3%程度というのは余りにも低い確率ではあるが….
*/