Elin:解析/共通処理: Difference between revisions

From Ylvapedia
(新規作成。)
 
mNo edit summary
Tags: Mobile edit Mobile web edit Visual edit
 
(4 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{解析}}
{{DISPLAYTITLE:{{SUBPAGENAME}}}}
{{バージョン|23.106}}このページではElinのプログラム中で頻出する共通の処理について記載します。
{{バージョン|23.106}}このページではElinのプログラム中で頻出する共通の処理について記載します。


== CURVE関数 ==
==CURVE関数==
[[File:Function curve as of EA23.46.png|thumb|upright=3.0|バージョン EA23.46 のCURVE 関数の入力(オレンジ色)と出力(藍)です。Output = Curve(Input, 50, 25, 75) ]]
[[File:Function curve as of EA23.46.png|thumb|upright=3.0|バージョン EA23.46 のCURVE 関数の入力(オレンジ色)と出力(藍)です。Output = Curve(Input, 50, 25, 75) ]]
CURVE関数とはElinにて、値の有効性を段階的に抑制する処理です。
CURVE関数とはElinにて、値の有効性を段階的に抑制する処理です。
Line 25: Line 28:
</syntaxhighlight>「a」はCURVE関数で抑制を行う値(以下、<code>入力値</code> )です。
</syntaxhighlight>「a」はCURVE関数で抑制を行う値(以下、<code>入力値</code> )です。


「start」はCURVE関数で抑制がかかりはじめるまでの閾値(以下、<code>抑制閾値</code> )です。例えばstart=150の場合、aが151以上であればCURVE関数による抑制が働きます。
「start」はCURVE関数で抑制がかかりはじめるまでの閾値(以下、<code>抑制閾値</code> )です。例えば抑制閾値=150の場合、入力値が151以上であればCURVE関数による抑制が働きます。


「rate」は抑制の比率を百分率で表した数値(以下、<code>抑制比率</code> )です。抑制対象の数値はこの%分の値になるように計算されます。
「rate」は抑制の比率を百分率で表した数値(以下、<code>抑制比率</code> )です。抑制対象の数値はこの%分の値になるように計算されます。
Line 44: Line 47:
4. 抑制値 <= 抑制段階 か 抑制回数 == 10 のどちらかを満たす場合、以下の式で算出される抑制結果を返却して終了します。
4. 抑制値 <= 抑制段階 か 抑制回数 == 10 のどちらかを満たす場合、以下の式で算出される抑制結果を返却して終了します。
  抑制結果 = 抑制値 + 抑制閾値 + 抑制段階 × (抑制回数 - 1)
  抑制結果 = 抑制値 + 抑制閾値 + 抑制段階 × (抑制回数 - 1)
5. 抑制対象値に以下の式の値を代入します。
5. 抑制対象値と抑制回数に以下の式の値を代入します。
  抑制対象値 = 抑制値 - 抑制閾値
  抑制対象値 = 抑制値 - 抑制段階
抑制回数 = 抑制回数 + 1
6. 値が返却されるまで3~5を繰り返します。
6. 値が返却されるまで3~5を繰り返します。




関数の曲線の傾きは徐々に小さくなり、最終的には<code>(抑制比率 / 100)^10</code> となります。
関数の曲線の傾きは徐々に小さくなり、最終的には<code>(抑制比率 / 100)^10</code> となります。
==ダイスロールなど==
{{EA 23.109 Stable Patch 2}}
public class Dice
{
    public static Dice Null = new Dice();
    public int num;
ダイスの数量です。
    public int sides;
日本語で言うとダイスの面数です。
    public int bonus;
おそらくダイスロール結果に定数を加算するものです。
    public Card card;
ここから、メインのRollの定義が述べられます。
    public static int Roll(int num, int sides, int bonus = 0, Card card = null)
    {
        int a = 1;
        bool flag = true;
        int num2 = 0;
        if (card != null)
        {
            int num3 = card.Evalue(78);
            flag = num3 >= 0;
            a = 1 + Mathf.Abs(num3 / 100) + ((Mathf.Abs(num3 % 100) > rnd(100)) ? 1 : 0);
        }
Evalue(78)は運であり、flagは運が0より大きいことを示す役割のようです。
aはリロール回数を示す整数で、基本的には、初期値1に、運を100で割った絶対値を足したものですが、(運を100で割ったあまり)%の確率でそれにさらに1が足されます。
       
        for (int i = 0; i < Mathf.Min(a, 20); i++)
        {
            int num4 = Roll();
            if (i == 0 || (flag && num4 > num2) || (!flag && num4 < num2))
            {
                num2 = num4;
            }
        }
        return num2;
ここでは実際にダイスが振られます。
まず、ダイスロールが繰り返される回数はiが0からa-1もしくは20-1<ref>整数なので、i<20のときi=20は認められない。</ref>まで増えていくまでなので、
'''a回、ただし上限20'''です。
後述する関数であるroll()で出た値は、条件を満たせばnum2として記憶されます。
その条件は、繰り返し回数0の初のロールであるとき、もしくは運が正かつ、前のnum2より大きい値が出たとき、もしくは運が負かつ、前のnum2より小さい値が出てしまったときです。
最後に、運が正であれば繰り返した中で最大のものを表し、運が負のときでは繰り返した中で最小のものを表すnum2が提示されます。
       
        int Roll()
        {
            int num5 = 0;
            for (int j = 0; j < num; j++)
            {
                num5 += rnd(sides) + 1;
            }
            return num5 + bonus;
        }
    }
これはnumの回数だけ、num5にrnd(sides) + 1を加えるというプログラムなので、
言い換えると個数numで、面数がsidesのサイコロを投げて出た目の総和です。
なお、この結果にbonusが足し算されてrollの値が決まります。
    public static int RollMax(int num, int sides, int bonus = 0)
    {
        return num * sides + bonus;
    }
これは複数のサイコロを投げて出る目の総和の最大値にbonusを足したものです。
    public static int rnd(int a)
    {
        return Rand.Range(0, a);
    }
Elinの解析で頻出の、rnd(a)= ”0からa-1までのランダムな値”
となる関数です。
{{DEFAULTSORT:カイセキ,キョウツウショリ}}
[[Category: Elin Spoiler]]
[[Category: JA]]

Latest revision as of 18:20, 21 March 2025


バージョン EA23.106: この記事は、Elin最新の安定版リリースに、少なくとも20のマイナーバージョンが遅れています。ページの更新をお願いします。

このページではElinのプログラム中で頻出する共通の処理について記載します。

CURVE関数

バージョン EA23.46 のCURVE 関数の入力(オレンジ色)と出力(藍)です。Output = Curve(Input, 50, 25, 75)

CURVE関数とはElinにて、値の有効性を段階的に抑制する処理です。

EClass.cs内で以下のように定義されています。

public static int curve(int a, int start, int step, int rate = 75)
{
	if (a <= start)
	{
		return a;
	}
	for (int i = 0; i < 10; i++)
	{
		int num = start + i * step;
		if (a > num)
		{
			a = num + (a - num) * rate / 100;
			continue;
		}
		return a;
	}
	return a;
}

「a」はCURVE関数で抑制を行う値(以下、入力値 )です。

「start」はCURVE関数で抑制がかかりはじめるまでの閾値(以下、抑制閾値 )です。例えば抑制閾値=150の場合、入力値が151以上であればCURVE関数による抑制が働きます。

「rate」は抑制の比率を百分率で表した数値(以下、抑制比率 )です。抑制対象の数値はこの%分の値になるように計算されます。

「step」は次の抑制までの閾値(以下、抑制段階 )です。


以下はCURVE関数についての解説です。(わかりやすさの為Elinのプログラムと同じではありませんが、等価です)

0. 抑制回数の変数(以下、抑制回数 )に1を代入します。

1. まずは抑制対象となる値を算出します。

抑制対象値 = 入力値 - 抑制閾値

2. 抑制対象値 <= 0の場合、入力値を返却して終了します。

3. 抑制値を算出します。

抑制値 = 抑制対象値 × 抑制比率 / 100

4. 抑制値 <= 抑制段階 か 抑制回数 == 10 のどちらかを満たす場合、以下の式で算出される抑制結果を返却して終了します。

抑制結果 = 抑制値 + 抑制閾値 + 抑制段階 × (抑制回数 - 1)

5. 抑制対象値と抑制回数に以下の式の値を代入します。

抑制対象値 = 抑制値 - 抑制段階
抑制回数 = 抑制回数 + 1

6. 値が返却されるまで3~5を繰り返します。


関数の曲線の傾きは徐々に小さくなり、最終的には(抑制比率 / 100)^10 となります。

ダイスロールなど

Template:EA 23.109 Stable Patch 2

public class Dice
{
   public static Dice Null = new Dice();


   public int num;

ダイスの数量です。


   public int sides;

日本語で言うとダイスの面数です。


   public int bonus;

おそらくダイスロール結果に定数を加算するものです。

   public Card card;

ここから、メインのRollの定義が述べられます。

   public static int Roll(int num, int sides, int bonus = 0, Card card = null)
   {
       int a = 1;
       bool flag = true;
       int num2 = 0;
       if (card != null)
       {
           int num3 = card.Evalue(78);
           flag = num3 >= 0;
           a = 1 + Mathf.Abs(num3 / 100) + ((Mathf.Abs(num3 % 100) > rnd(100)) ? 1 : 0);
       }

Evalue(78)は運であり、flagは運が0より大きいことを示す役割のようです。

aはリロール回数を示す整数で、基本的には、初期値1に、運を100で割った絶対値を足したものですが、(運を100で割ったあまり)%の確率でそれにさらに1が足されます。


       for (int i = 0; i < Mathf.Min(a, 20); i++)
       {
           int num4 = Roll();
           if (i == 0 || (flag && num4 > num2) || (!flag && num4 < num2))
           {
               num2 = num4;
           }
       }
       return num2;

ここでは実際にダイスが振られます。

まず、ダイスロールが繰り返される回数はiが0からa-1もしくは20-1[1]まで増えていくまでなので、

a回、ただし上限20です。

後述する関数であるroll()で出た値は、条件を満たせばnum2として記憶されます。

その条件は、繰り返し回数0の初のロールであるとき、もしくは運が正かつ、前のnum2より大きい値が出たとき、もしくは運が負かつ、前のnum2より小さい値が出てしまったときです。

最後に、運が正であれば繰り返した中で最大のものを表し、運が負のときでは繰り返した中で最小のものを表すnum2が提示されます。

       int Roll()
       {
           int num5 = 0;
           for (int j = 0; j < num; j++)
           {
               num5 += rnd(sides) + 1;
           }
           return num5 + bonus;
       }
   }

これはnumの回数だけ、num5にrnd(sides) + 1を加えるというプログラムなので、

言い換えると個数numで、面数がsidesのサイコロを投げて出た目の総和です。

なお、この結果にbonusが足し算されてrollの値が決まります。

   public static int RollMax(int num, int sides, int bonus = 0)
   {
       return num * sides + bonus;
   }

これは複数のサイコロを投げて出る目の総和の最大値にbonusを足したものです。

   public static int rnd(int a)
   {
       return Rand.Range(0, a);
   }

Elinの解析で頻出の、rnd(a)= ”0からa-1までのランダムな値” となる関数です。

  1. 整数なので、i<20のときi=20は認められない。