<?xml version="1.0" encoding="UTF-8" ?><rdf:RDF 
  xmlns="http://purl.org/rss/1.0/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xml:lang="ja">
  <channel rdf:about="http://w.atwiki.jp/ntetool/">
    <title>nte計算サイト</title>
    <link>http://w.atwiki.jp/ntetool/</link>
    <atom:link href="https://w.atwiki.jp/ntetool/rss10.xml" rel="self" type="application/rss+xml" />
    <atom:link rel="hub" href="https://pubsubhubbub.appspot.com" />
    <description>nte計算サイト</description>

    <dc:language>ja</dc:language>
    <dc:date>2026-06-09T16:15:51+09:00</dc:date>
    <utime>1780989351</utime>

    <items>
      <rdf:Seq>
                <rdf:li rdf:resource="https://w.atwiki.jp/ntetool/pages/15.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/ntetool/pages/1.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/ntetool/pages/14.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/ntetool/pages/12.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/ntetool/pages/13.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/ntetool/pages/11.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/ntetool/pages/10.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/ntetool/pages/2.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/ntetool/pages/3.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/ntetool/pages/4.html" />
              </rdf:Seq>
    </items>
	
		
    
  </channel>
    <item rdf:about="https://w.atwiki.jp/ntetool/pages/15.html">
    <title>駆動コア・ブロックガチャシミュレータ</title>
    <link>https://w.atwiki.jp/ntetool/pages/15.html</link>
    <description>
          </description>
    <dc:date>2026-06-09T16:15:51+09:00</dc:date>
    <utime>1780989351</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/ntetool/pages/1.html">
    <title>トップページ</title>
    <link>https://w.atwiki.jp/ntetool/pages/1.html</link>
    <description>
      [[ハンターレベル計算機]]

[[キャラレベル計算機]]
[[弧盤レベル計算機]]

[[好感度計算機]]

[[ガチャシミュレータ]]
[[駆動コア・ブロックガチャシミュレータ]]    </description>
    <dc:date>2026-06-09T15:41:57+09:00</dc:date>
    <utime>1780987317</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/ntetool/pages/14.html">
    <title>ガチャシミュレータ</title>
    <link>https://w.atwiki.jp/ntetool/pages/14.html</link>
    <description>
      #javascript(){

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ja&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;title&gt;Porsche 918 Spider ガチャシミュレーター (完全版)&lt;/title&gt;
    &lt;style&gt;
        body { font-family: sans-serif; background: #f4f4f9; padding: 20px; color: #333; }
        
        /* パスワード入力画面 */
        #password-screen {
            max-width: 400px; margin: 100px auto; background: #fff; padding: 30px; 
            border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); text-align: center;
        }
        #password-screen input { width: 80%; padding: 10px; margin-bottom: 15px; font-size: 1.1em; text-align: center; }
        
        /* シミュレーター本体 */
        #simulator-content { display: none; max-width: 750px; margin: 0 auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
        
        h2 { border-bottom: 2px solid #4a90e2; padding-bottom: 10px; color: #1F385C; }
        h3 { color: #1F385C; margin-top: 25px; border-left: 4px solid #4a90e2; padding-left: 8px; font-size: 1.1em; }
        .row { display: flex; align-items: flex-end; margin-bottom: 15px; gap: 15px; flex-wrap: wrap; }
        .input-group { display: flex; flex-direction: column; gap: 5px; }
        label { font-size: 0.85em; color: #666; font-weight: bold; }
        select, input { padding: 8px; border: 1px solid #ccc; border-radius: 4px; background: #fff; font-size: 1em; }
        input[type=&quot;number&quot;] { width: 140px; }
        
        /* チェックボックスエリア */
        .checkbox-group { display: flex; flex-direction: column; gap: 6px; background: #f8f9fa; padding: 12px; border-radius: 4px; border: 1px solid #eee; width: 100%; box-sizing: border-box; }
        .checkbox-item { display: flex; align-items: center; gap: 8px; font-size: 0.95em; cursor: pointer; }
        .checkbox-item input { cursor: pointer; }

        /* ボタン */
        .btn-container { display: flex; gap: 10px; margin-top: 10px; }
        button { flex: 1; padding: 12px; background: #4a90e2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1em; font-weight: bold; }
        button:hover { background: #357abd; }
        button.reset { background: #9e9e9e; max-width: 150px; }
        button.reset:hover { background: #757575; }
        
        /* 結果表示エリア */
        #single-result, #loop-result, #multi-result { margin-top: 20px; padding: 15px; border-left: 5px solid #4a90e2; background: #f0f7ff; display: none; line-height: 1.6; }
        
        .important { color: #d0021b; font-weight: bold; }
        .pickup { color: #2a64ad; font-weight: bold; }
        hr { border: 0; border-top: 1px solid #ccc; margin: 15px 0; }
        .note { font-size: 0.8em; color: #777; margin-top: 5px; }
        
        /* 統計テーブル */
        table { width: 100%; border-collapse: collapse; margin-top: 15px; background: white; }
        th, td { border: 1px solid #ddd; padding: 10px; text-align: center; }
        th { background: #f8f9fa; font-size: 0.9em; color: #555; }
        tr:nth-child(even) { background-color: #fafafa; }
        .hit-row { background-color: #f0f7ff !important; font-weight: bold; }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;div id=&quot;password-screen&quot;&gt;
    &lt;h3 style=&quot;border: none; padding: 0;&quot;&gt;パスワードを入力してください&lt;/h3&gt;
    &lt;input type=&quot;password&quot; id=&quot;password-input&quot; placeholder=&quot;Password&quot; onkeydown=&quot;if(event.key===&#039;Enter&#039;) checkPassword()&quot;&gt;
    &lt;br&gt;
    &lt;button onclick=&quot;checkPassword()&quot;&gt;解除&lt;/button&gt;
&lt;/div&gt;

&lt;div id=&quot;simulator-content&quot;&gt;
    &lt;h2&gt;Porsche 918 Spider ガチャシミュレーター&lt;/h2&gt;
    
    &lt;div class=&quot;row&quot; style=&quot;background: #eef5ff; padding: 15px; border-radius: 8px; border: 1px solid #d0e3ff; margin-bottom: 25px;&quot;&gt;
        &lt;div class=&quot;input-group&quot; style=&quot;width: 100%;&quot;&gt;
            &lt;label style=&quot;color: #1F385C; font-size: 1em;&quot;&gt;【共通設定】円石消費への切り替えタイミング&lt;/label&gt;
            &lt;div style=&quot;font-size: 0.85em; margin-bottom: 8px; color: #555;&quot;&gt;何回目から「円石」を消費するか選択してください。（設定した回数未満はファンスを消費します）&lt;/div&gt;
            &lt;select id=&quot;stone-start-pull&quot; onchange=&quot;updateSingleCostDisplay()&quot; style=&quot;max-width: 300px;&quot;&gt;
                &lt;option value=&quot;1&quot;&gt;1回目から (すべて円石)&lt;/option&gt;
                &lt;option value=&quot;2&quot;&gt;2回目から&lt;/option&gt;
                &lt;option value=&quot;3&quot;&gt;3回目から&lt;/option&gt;
                &lt;option value=&quot;4&quot;&gt;4回目から&lt;/option&gt;
                &lt;option value=&quot;5&quot;&gt;5回目から&lt;/option&gt;
                &lt;option value=&quot;6&quot;&gt;6回目から&lt;/option&gt;
                &lt;option value=&quot;7&quot;&gt;7回目から&lt;/option&gt;
                &lt;option value=&quot;8&quot;&gt;8回目から&lt;/option&gt;
                &lt;option value=&quot;9&quot;&gt;9回目から&lt;/option&gt;
                &lt;option value=&quot;10&quot;&gt;10回目から&lt;/option&gt;
                &lt;option value=&quot;11&quot; selected&gt;11回目から&lt;/option&gt;
                &lt;option value=&quot;12&quot;&gt;12回目から&lt;/option&gt;
                &lt;option value=&quot;13&quot;&gt;13回目から&lt;/option&gt;
                &lt;option value=&quot;14&quot;&gt;14回目から&lt;/option&gt;
                &lt;option value=&quot;15&quot;&gt;15回目から&lt;/option&gt;
                &lt;option value=&quot;16&quot;&gt;使用しない (すべてファンス)&lt;/option&gt;
            &lt;/select&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;h3&gt;【モード1】単発ずつ引く&lt;/h3&gt;
    &lt;p class=&quot;note&quot;&gt;※ボックス残量に応じて確率がリアルタイムに変動します。15回引ききると自動で箱がリセットされ、次の1回目を引く時に履歴がクリアされます。&lt;/p&gt;
    &lt;div class=&quot;row&quot;&gt;
        &lt;div class=&quot;input-group&quot;&gt;
            &lt;label&gt;現在の状態&lt;/label&gt;
            &lt;div style=&quot;padding: 8px 0; font-size: 1.05em;&quot;&gt;
                次を引くと &lt;strong id=&quot;current-pull-count&quot; class=&quot;important&quot;&gt;1&lt;/strong&gt; 回目のベース比率が適用されます
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class=&quot;btn-container&quot;&gt;
        &lt;button onclick=&quot;pullSingle()&quot;&gt;1回引く&lt;/button&gt;
        &lt;button class=&quot;reset&quot; onclick=&quot;resetSingle()&quot;&gt;ボックスリセット&lt;/button&gt;
    &lt;/div&gt;
    &lt;div id=&quot;single-result&quot;&gt;&lt;/div&gt;

    &lt;hr style=&quot;margin: 30px 0; border-top: 2px dashed #ddd;&quot;&gt;

    &lt;h3&gt;【モード2】特定アイテムが出るまで周回シミュレーション&lt;/h3&gt;
    &lt;p class=&quot;note&quot;&gt;※各周ごとに中身が減るボックス式の挙動で、お目当ての1種が出るまでの回数を集計します。&lt;/p&gt;
    &lt;div class=&quot;row&quot;&gt;
        &lt;div class=&quot;input-group&quot;&gt;
            &lt;label&gt;狙うターゲットアイテム&lt;/label&gt;
            &lt;select id=&quot;target-item&quot;&gt;
                &lt;option value=&quot;918 Spider&quot;&gt;918 Spider&lt;/option&gt;
                &lt;option value=&quot;主人公スキン&quot;&gt;主人公スキン&lt;/option&gt;
                &lt;option value=&quot;虚質サイコロ*10&quot;&gt;虚質サイコロ*10&lt;/option&gt;
                &lt;option value=&quot;手書きの手紙*3&quot;&gt;手書きの手紙*3&lt;/option&gt;
                &lt;option value=&quot;ファンス*50万&quot;&gt;ファンス*50万&lt;/option&gt;
                &lt;option value=&quot;アイコン枠&quot;&gt;アイコン枠&lt;/option&gt;
                &lt;option value=&quot;プロフテーマ&quot;&gt;プロフテーマ&lt;/option&gt;
            &lt;/select&gt;
        &lt;/div&gt;
        &lt;div class=&quot;input-group&quot;&gt;
            &lt;label&gt;シミュレーション周回数&lt;/label&gt;
            &lt;input type=&quot;number&quot; id=&quot;sim-loops&quot; value=&quot;1000&quot; min=&quot;1&quot; max=&quot;1000000&quot;&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div class=&quot;btn-container&quot;&gt;
        &lt;button onclick=&quot;runLoopSimulation()&quot;&gt;シミュレーションを実行して表にまとめる&lt;/button&gt;
    &lt;/div&gt;
    
    &lt;div id=&quot;loop-result&quot;&gt;&lt;/div&gt;

    &lt;hr style=&quot;margin: 30px 0; border-top: 2px dashed #ddd;&quot;&gt;

    &lt;h3&gt;【モード3】選択したターゲットを全て引くまでの周回シミュレーション&lt;/h3&gt;
    &lt;p class=&quot;note&quot;&gt;※チェックを入れた対象がすべてボックスから消えるまでにかかる回数を集計します。&lt;/p&gt;
    &lt;div class=&quot;row&quot; style=&quot;flex-direction: column; align-items: flex-start; gap: 10px;&quot;&gt;
        &lt;label&gt;狙うターゲット&lt;/label&gt;
        &lt;div class=&quot;checkbox-group&quot;&gt;
            &lt;label class=&quot;checkbox-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;target-cb&quot; value=&quot;918 Spider&quot; checked&gt; 918 Spider&lt;/label&gt;
            &lt;label class=&quot;checkbox-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;target-cb&quot; value=&quot;主人公スキン&quot; checked&gt; 主人公スキン&lt;/label&gt;
            &lt;label class=&quot;checkbox-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;target-cb&quot; value=&quot;虚質サイコロ*10&quot; checked&gt; 虚質サイコロ*10&lt;/label&gt;
            &lt;label class=&quot;checkbox-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;target-cb&quot; value=&quot;手書きの手紙*3&quot; checked&gt; 手書きの手紙*3&lt;/label&gt;
            &lt;label class=&quot;checkbox-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;target-cb&quot; value=&quot;ファンス*50万&quot; checked&gt; ファンス*50万&lt;/label&gt;
            &lt;label class=&quot;checkbox-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;target-cb&quot; value=&quot;アイコン枠&quot;&gt; アイコン枠&lt;/label&gt;
            &lt;label class=&quot;checkbox-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;target-cb&quot; value=&quot;プロフテーマ&quot;&gt; プロフテーマ&lt;/label&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class=&quot;row&quot; style=&quot;margin-top: 10px;&quot;&gt;
        &lt;div class=&quot;input-group&quot;&gt;
            &lt;label&gt;シミュレーション周回数&lt;/label&gt;
            &lt;input type=&quot;number&quot; id=&quot;multi-sim-loops&quot; value=&quot;1000&quot; min=&quot;1&quot; max=&quot;1000000&quot;&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div class=&quot;btn-container&quot;&gt;
        &lt;button style=&quot;background: #3a5f8f;&quot; onclick=&quot;runMultiSimulation()&quot;&gt;シミュレーションを実行して表にまとめる&lt;/button&gt;
    &lt;/div&gt;
    
    &lt;div id=&quot;multi-result&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;script&gt;
// パスワードチェック
function checkPassword() {
    const pw = document.getElementById(&quot;password-input&quot;).value;
    if (pw === &quot;1021&quot;) {
        document.getElementById(&quot;password-screen&quot;).style.display = &quot;none&quot;;
        document.getElementById(&quot;simulator-content&quot;).style.display = &quot;block&quot;;
    } else {
        alert(&quot;パスワードが正しくありません。&quot;);
    }
}

// 確率マッピングデータ
const gachaRates = [
    { pull: 1,  &quot;918 Spider&quot;: 0.00,  &quot;主人公スキン&quot;: 0.29, &quot;虚質サイコロ*10&quot;: 0.49, &quot;手書きの手紙*3&quot;: 0.98, &quot;ファンス*50万&quot;: 0.98, &quot;その他&quot;: 97.20 },
    { pull: 2,  &quot;918 Spider&quot;: 0.00,  &quot;主人公スキン&quot;: 0.32, &quot;虚質サイコロ*10&quot;: 0.54, &quot;手書きの手紙*3&quot;: 1.08, &quot;ファンス*50万&quot;: 1.08, &quot;その他&quot;: 97.00 },
    { pull: 3,  &quot;918 Spider&quot;: 0.00,  &quot;主人公スキン&quot;: 0.36, &quot;虚質サイコロ*10&quot;: 0.60, &quot;手書きの手紙*3&quot;: 1.19, &quot;ファンス*50万&quot;: 1.19, &quot;その他&quot;: 96.70 },
    { pull: 4,  &quot;918 Spider&quot;: 0.00,  &quot;主人公スキン&quot;: 0.41, &quot;虚質サイコロ*10&quot;: 0.68, &quot;手書きの手紙*3&quot;: 1.33, &quot;ファンス*50万&quot;: 1.33, &quot;その他&quot;: 96.20 },
    { pull: 5,  &quot;918 Spider&quot;: 0.00,  &quot;主人公スキン&quot;: 0.47, &quot;虚質サイコロ*10&quot;: 0.77, &quot;手書きの手紙*3&quot;: 1.52, &quot;ファンス*50万&quot;: 1.52, &quot;その他&quot;: 95.70 },
    { pull: 6,  &quot;918 Spider&quot;: 0.19,  &quot;主人公スキン&quot;: 0.55, &quot;虚質サイコロ*10&quot;: 0.91, &quot;手書きの手紙*3&quot;: 1.76, &quot;ファンス*50万&quot;: 1.76, &quot;その他&quot;: 94.80 },
    { pull: 7,  &quot;918 Spider&quot;: 0.23,  &quot;主人公スキン&quot;: 0.67, &quot;虚質サイコロ*10&quot;: 1.09, &quot;手書きの手紙*3&quot;: 2.11, &quot;ファンス*50万&quot;: 2.11, &quot;その他&quot;: 93.80 },
    { pull: 8,  &quot;918 Spider&quot;: 0.29,  &quot;主人公スキン&quot;: 0.84, &quot;虚質サイコロ*10&quot;: 1.38, &quot;手書きの手紙*3&quot;: 2.65, &quot;ファンス*50万&quot;: 2.65, &quot;その他&quot;: 92.20 },
    { pull: 9,  &quot;918 Spider&quot;: 0.39,  &quot;主人公スキン&quot;: 1.16, &quot;虚質サイコロ*10&quot;: 1.89, &quot;手書きの手紙*3&quot;: 3.58, &quot;ファンス*50万&quot;: 3.58, &quot;その他&quot;: 89.40 },
    { pull: 10, &quot;918 Spider&quot;: 0.64,  &quot;主人公スキン&quot;: 1.86, &quot;虚質サイコロ*10&quot;: 3.02, &quot;手書きの手紙*3&quot;: 5.70, &quot;ファンス*50万&quot;: 5.70, &quot;その他&quot;: 83.10 },
    { pull: 11, &quot;918 Spider&quot;: 1.97,  &quot;主人公スキン&quot;: 5.81, &quot;虚質サイコロ*10&quot;: 9.53, &quot;手書きの手紙*3&quot;: 18.21, &quot;ファンス*50万&quot;: 18.21, &quot;その他&quot;: 46.30 },
    { pull: 12, &quot;918 Spider&quot;: 4.12,  &quot;主人公スキン&quot;: 11.58, &quot;虚質サイコロ*10&quot;: 17.87, &quot;手書きの手紙*3&quot;: 25.85, &quot;ファンス*50万&quot;: 25.85, &quot;その他&quot;: 14.70 },
    { pull: 13, &quot;918 Spider&quot;: 7.60,  &quot;主人公スキン&quot;: 19.86, &quot;虚質サイコロ*10&quot;: 27.34, &quot;手書きの手紙*3&quot;: 21.30, &quot;ファンス*50万&quot;: 21.30, &quot;その他&quot;: 2.60 },
    { pull: 14, &quot;918 Spider&quot;: 16.43, &quot;主人公スキン&quot;: 36.55, &quot;虚質サイコロ*10&quot;: 25.38, &quot;手書きの手紙*3&quot;: 10.70, &quot;ファンス*50万&quot;: 10.70, &quot;その他&quot;: 0.20 },
    { pull: 15, &quot;918 Spider&quot;: 68.14, &quot;主人公スキン&quot;: 19.26, &quot;虚質サイコロ*10&quot;: 8.51, &quot;手書きの手紙*3&quot;: 2.04, &quot;ファンス*50万&quot;: 2.04, &quot;その他&quot;: 0.00 }
];

// アイテムの分類定義
const mainItems = [&quot;918 Spider&quot;, &quot;主人公スキン&quot;, &quot;虚質サイコロ*10&quot;, &quot;手書きの手紙*3&quot;, &quot;ファンス*50万&quot;];
const subItems = [
    &quot;アイコン枠&quot;, &quot;プロフテーマ&quot;, &quot;虚質サイコロ*3&quot;, &quot;浮氷映画チケット*3&quot;, 
    &quot;ファンス*10万&quot;, &quot;特急ハンター攻略*10&quot;, &quot;夢なき果核*10&quot;, &quot;甲虫コイン*10万&quot;
];

// ボックス初期状態生成関数
function getInitialBoxState() {
    return {
        &quot;918 Spider&quot;: 1,
        &quot;主人公スキン&quot;: 1,
        &quot;虚質サイコロ*10&quot;: 1,
        &quot;手書きの手紙*3&quot;: 1,
        &quot;ファンス*50万&quot;: 1,
        // はずれ10枠
        &quot;アイコン枠&quot;: 1,
        &quot;プロフテーマ&quot;: 1,
        &quot;虚質サイコロ*3&quot;: 1,
        &quot;浮氷映画チケット*3&quot;: 1,
        &quot;ファンス*10万&quot;: 1,
        &quot;特急ハンター攻略*10&quot;: 2, // 2枠
        &quot;夢なき果核*10&quot;: 1,
        &quot;甲虫コイン*10万&quot;: 2  // 2枠
    };
}

// コスト計算用データ
const costTable = [
    { stone: 50, fans: 50000 },
    { stone: 80, fans: 80000 },
    { stone: 100, fans: 100000 },
    { stone: 150, fans: 150000 },
    { stone: 200, fans: 200000 },
    { stone: 300, fans: 300000 },
    { stone: 500, fans: 500000 },
    { stone: 600, fans: 800000 },
    { stone: 800, fans: 1000000 },
    { stone: 1200, fans: 1500000 },
    { stone: 1400, fans: 2000000 },
    { stone: 1600, fans: 2500000 },
    { stone: 1800, fans: 3000000 },
    { stone: 2000, fans: 3500000 },
    { stone: 2200, fans: 4200000 }
];

function getCumulativeCost(pullCount) {
    let stoneStart = parseInt(document.getElementById(&quot;stone-start-pull&quot;).value);
    let totalFans = 0;
    let totalStone = 0;
    for (let i = 1; i &lt;= pullCount; i++) {
        if (i &gt;= stoneStart) {
            totalStone += costTable[i - 1].stone;
        } else {
            totalFans += costTable[i - 1].fans;
        }
    }
    return { fans: totalFans, stone: totalStone };
}

// ボックス残量に応じた確率計算＆抽選関数
function drawFromBox(pullCount, boxState) {
    const rateIdx = Math.min(pullCount, 15) - 1;
    const baseRates = gachaRates[rateIdx];
    
    // 現在残っているはずれ枠の総数を数える
    let currentSubTotal = 0;
    for (let sub of subItems) {
        currentSubTotal += boxState[sub];
    }
    
    // 有効な重みの総和を算出
    let validWeightSum = 0;
    for (let item of mainItems) {
        if (boxState[item] &gt; 0) {
            validWeightSum += baseRates[item];
        }
    }
    // はずれ枠が残っている場合のみ「その他」の比率を加算
    if (currentSubTotal &gt; 0) {
        validWeightSum += baseRates[&quot;その他&quot;];
    }
    
    let rand = Math.random() * validWeightSum;
    let cumulativeWeight = 0;
    
    // 1. 当たり枠(メイン)の抽選
    for (let item of mainItems) {
        if (boxState[item] &gt; 0) {
            cumulativeWeight += baseRates[item];
            if (rand &lt;= cumulativeWeight) {
                boxState[item]--;
                return item;
            }
        }
    }
    
    // 2. 「その他(はずれ)」枠が当選、またはフォールバック時の処理
    if (currentSubTotal &gt; 0) {
        let subRand = Math.random() * currentSubTotal;
        let subCumulative = 0;
        
        for (let sub of subItems) {
            if (boxState[sub] &gt; 0) {
                subCumulative += boxState[sub];
                if (subRand &lt;= subCumulative) {
                    boxState[sub]--;
                    return sub;
                }
            }
        }
    }
    
    // セーフティ
    const allItems = mainItems.concat(subItems);
    for (let item of allItems) {
        if (boxState[item] &gt; 0) {
            boxState[item]--;
            return item;
        }
    }
    
    return &quot;アイコン枠&quot;; 
}

// ================= モード1: 単発処理 =================
let singlePullCount = 1;
let singleBoxState = getInitialBoxState();
let historyHTML = &quot;&quot;;
let lastSinglePullCount = 0;

function updateSingleCostDisplay() {
    const costDiv = document.getElementById(&quot;single-cost&quot;);
    if (!costDiv) return;
    if (lastSinglePullCount === 0) {
        costDiv.innerHTML = &quot;&quot;;
    } else {
        let cost = getCumulativeCost(lastSinglePullCount);
        costDiv.innerHTML = `&lt;div style=&quot;margin-top: 15px; padding: 12px; background: #fff; border: 2px solid #4a90e2; border-radius: 6px; text-align: center; font-size: 1.1em;&quot;&gt;
            &lt;strong&gt;【現在の累計消費】&lt;/strong&gt;&lt;br&gt;
            ファンス: &lt;strong style=&quot;color:#d0021b;&quot;&gt;${cost.fans.toLocaleString()}&lt;/strong&gt; / 円石: &lt;strong style=&quot;color:#d0021b;&quot;&gt;${cost.stone.toLocaleString()}&lt;/strong&gt;
        &lt;/div&gt;`;
    }
}

function pullSingle() {
    const resDiv = document.getElementById(&quot;single-result&quot;);
    resDiv.style.display = &quot;block&quot;;
    
    if (singlePullCount === 1) {
        historyHTML = &quot;&quot;;
    }
    
    lastSinglePullCount = singlePullCount;
    const result = drawFromBox(singlePullCount, singleBoxState);
    const isMain = mainItems.includes(result);
    
    historyHTML += `&lt;div&gt;&lt;strong&gt;${singlePullCount}回目:&lt;/strong&gt; &lt;span class=&quot;${isMain ? &#039;pickup&#039; : &#039;&#039;}&quot;&gt;${result}&lt;/span&gt;&lt;/div&gt;`;
    
    if (singlePullCount === 15) {
        singleBoxState = getInitialBoxState();
        singlePullCount = 1;
    } else {
        singlePullCount++;
    }
    
    resDiv.innerHTML = `&lt;strong&gt;【獲得履歴】&lt;/strong&gt;&lt;br&gt;${historyHTML}&lt;div id=&quot;single-cost&quot;&gt;&lt;/div&gt;`;
    updateSingleCostDisplay();
    
    document.getElementById(&quot;current-pull-count&quot;).innerText = singlePullCount;
}

function resetSingle() {
    singlePullCount = 1;
    singleBoxState = getInitialBoxState();
    historyHTML = &quot;&quot;;
    lastSinglePullCount = 0;
    const resDiv = document.getElementById(&quot;single-result&quot;);
    resDiv.style.display = &quot;none&quot;;
    resDiv.innerHTML = &quot;&quot;;
    document.getElementById(&quot;current-pull-count&quot;).innerText = singlePullCount;
}

// ================= モード2: 周回処理 =================
function runLoopSimulation() {
    const target = document.getElementById(&quot;target-item&quot;).value;
    const loops = parseInt(document.getElementById(&quot;sim-loops&quot;).value) || 0;
    
    if (loops &lt;= 0) {
        alert(&quot;有効な周回数を入力してください。&quot;);
        return;
    }
    
    let hitCounts = new Array(15).fill(0);
    let totalPulls = 0;
    
    for (let i = 0; i &lt; loops; i++) {
        let loopBoxState = getInitialBoxState();
        let currentPull = 1;
        
        while (currentPull &lt;= 15) {
            let result = drawFromBox(currentPull, loopBoxState);
            if (result === target) {
                break;
            }
            currentPull++;
        }
        
        hitCounts[currentPull - 1]++;
        totalPulls += currentPull;
    }
    
    let tableRows = &quot;&quot;;
    let cumulativeHits = 0;
    for (let h = 0; h &lt; 15; h++) {
        let count = hitCounts[h];
        cumulativeHits += count;
        
        let percentage = ((count / loops) * 100).toFixed(2);
        let cumulativePercentage = ((cumulativeHits / loops) * 100).toFixed(2);
        let cost = getCumulativeCost(h + 1);
        
        tableRows += `
            &lt;tr class=&quot;${count &gt; 0 ? &#039;hit-row&#039; : &#039;&#039;}&quot;&gt;
                &lt;td&gt;&lt;strong&gt;${h + 1} 回目&lt;/strong&gt;&lt;/td&gt;
                &lt;td&gt;${count.toLocaleString()} 回&lt;/td&gt;
                &lt;td class=&quot;important&quot;&gt;${percentage} %&lt;/td&gt;
                &lt;td class=&quot;pickup&quot;&gt;${cumulativePercentage} %&lt;/td&gt;
                &lt;td&gt;${cost.fans.toLocaleString()}&lt;/td&gt;
                &lt;td&gt;${cost.stone.toLocaleString()}&lt;/td&gt;
            &lt;/tr&gt;
        `;
    }
    
    const avgPulls = (totalPulls / loops).toFixed(2);
    const resDiv = document.getElementById(&quot;loop-result&quot;);
    resDiv.style.display = &quot;block&quot;;
    
    resDiv.innerHTML = `
        &lt;strong&gt;【シミュレーション結果】&lt;/strong&gt;&lt;br&gt;
        ターゲットアイテム: &lt;strong class=&quot;pickup&quot;&gt;${target}&lt;/strong&gt;&lt;br&gt;
        総シミュレーション周回数: &lt;strong&gt;${loops.toLocaleString()} 周&lt;/strong&gt;&lt;br&gt;
        ターゲット獲得に要した平均回数: &lt;strong class=&quot;important&quot;&gt;${avgPulls} 回 / 周&lt;/strong&gt;
        &lt;hr&gt;
        &lt;table&gt;
            &lt;thead&gt;
                &lt;tr&gt;
                    &lt;th&gt;獲得したタイミング&lt;/th&gt;
                    &lt;th&gt;周回内での検出数&lt;/th&gt;
                    &lt;th&gt;出現割合&lt;/th&gt;
                    &lt;th&gt;累計割合&lt;/th&gt;
                    &lt;th&gt;消費ファンス&lt;/th&gt;
                    &lt;th&gt;消費円石&lt;/th&gt;
                &lt;/tr&gt;
            &lt;/thead&gt;
            &lt;tbody&gt;
                ${tableRows}
            &lt;/tbody&gt;
        &lt;/table&gt;
    `;
}

// ================= モード3: 複数当たり引ききり周回処理 =================
function runMultiSimulation() {
    const loops = parseInt(document.getElementById(&quot;multi-sim-loops&quot;).value) || 0;
    if (loops &lt;= 0) {
        alert(&quot;有効な周回数を入力してください。&quot;);
        return;
    }

    const checkboxes = document.querySelectorAll(&quot;.target-cb:checked&quot;);
    let targets = [];
    checkboxes.forEach(cb =&gt; targets.push(cb.value));

    if (targets.length === 0) {
        alert(&quot;ターゲットアイテムを最低1つ以上チェックしてください。&quot;);
        return;
    }

    let hitCounts = new Array(15).fill(0);
    let totalPulls = 0;

    for (let i = 0; i &lt; loops; i++) {
        let loopBoxState = getInitialBoxState();
        let currentPull = 1;

        while (currentPull &lt;= 15) {
            drawFromBox(currentPull, loopBoxState);

            let isAllCleared = true;
            for (let t of targets) {
                if (loopBoxState[t] &gt; 0) {
                    isAllCleared = false;
                    break;
                }
            }

            if (isAllCleared) {
                break;
            }
            currentPull++;
        }

        hitCounts[currentPull - 1]++;
        totalPulls += currentPull;
    }

    let tableRows = &quot;&quot;;
    let cumulativeHits = 0;
    for (let h = 0; h &lt; 15; h++) {
        let count = hitCounts[h];
        cumulativeHits += count;
        
        let percentage = ((count / loops) * 100).toFixed(2);
        let cumulativePercentage = ((cumulativeHits / loops) * 100).toFixed(2);
        let cost = getCumulativeCost(h + 1);
        
        tableRows += `
            &lt;tr class=&quot;${count &gt; 0 ? &#039;hit-row&#039; : &#039;&#039;}&quot;&gt;
                &lt;td&gt;&lt;strong&gt;${h + 1} 回目までに完了&lt;/strong&gt;&lt;/td&gt;
                &lt;td&gt;${count.toLocaleString()} 回&lt;/td&gt;
                &lt;td class=&quot;important&quot;&gt;${percentage} %&lt;/td&gt;
                &lt;td class=&quot;pickup&quot;&gt;${cumulativePercentage} %&lt;/td&gt;
                &lt;td&gt;${cost.fans.toLocaleString()}&lt;/td&gt;
                &lt;td&gt;${cost.stone.toLocaleString()}&lt;/td&gt;
            &lt;/tr&gt;
        `;
    }

    const avgPulls = (totalPulls / loops).toFixed(2);
    const resDiv = document.getElementById(&quot;multi-result&quot;);
    resDiv.style.display = &quot;block&quot;;

    resDiv.innerHTML = `
        &lt;strong&gt;【シミュレーション結果】&lt;/strong&gt;&lt;br&gt;
        対象ターゲット: &lt;strong class=&quot;pickup&quot;&gt;${targets.join(&quot; , &quot;)}&lt;/strong&gt;&lt;br&gt;
        総シミュレーション周回数: &lt;strong&gt;${loops.toLocaleString()} 周&lt;/strong&gt;&lt;br&gt;
        全条件達成に要した平均回数: &lt;strong class=&quot;important&quot;&gt;${avgPulls} 回 / 周&lt;/strong&gt;
        &lt;hr&gt;
        &lt;table&gt;
            &lt;thead&gt;
                &lt;tr&gt;
                    &lt;th&gt;条件達成した回数&lt;/th&gt;
                    &lt;th&gt;周回内での検出数&lt;/th&gt;
                    &lt;th&gt;出現割合&lt;/th&gt;
                    &lt;th&gt;累計割合&lt;/th&gt;
                    &lt;th&gt;消費ファンス&lt;/th&gt;
                    &lt;th&gt;消費円石&lt;/th&gt;
                &lt;/tr&gt;
            &lt;/thead&gt;
            &lt;tbody&gt;
                ${tableRows}
            &lt;/tbody&gt;
        &lt;/table&gt;
    `;
}
&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;

}

**その他の計算機
[[トップページ]]    </description>
    <dc:date>2026-05-31T17:26:07+09:00</dc:date>
    <utime>1780215967</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/ntetool/pages/12.html">
    <title>ハンターレベル計算機</title>
    <link>https://w.atwiki.jp/ntetool/pages/12.html</link>
    <description>
      #javascript(){

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ja&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;title&gt;ハンターレベル計算機&lt;/title&gt;
    &lt;style&gt;
        body { font-family: sans-serif; background: #f4f4f9; padding: 20px; color: #333; }
        .container { max-width: 750px; margin: 0 auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
        h2 { border-bottom: 2px solid #ddd; padding-bottom: 10px; }
        .row { display: flex; align-items: flex-end; margin-bottom: 15px; gap: 15px; flex-wrap: wrap; }
        .input-group { display: flex; flex-direction: column; gap: 5px; }
        label { font-size: 0.85em; color: #666; font-weight: bold; }
        select, input { padding: 8px; border: 1px solid #ccc; border-radius: 4px; background: #fff; }
        input[type=&quot;number&quot;] { width: 120px; }
        button { width: 100%; padding: 12px; background: #4a90e2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1.1em; margin-top: 10px; }
        button:hover { background: #357abd; }
        #result { margin-top: 20px; padding: 15px; border-left: 5px solid #4a90e2; background: #f0f7ff; display: none; line-height: 1.6; }
        .important { color: #d0021b; font-weight: bold; }
        hr { border: 0; border-top: 1px solid #ccc; margin: 10px 0; }
        .note { font-size: 0.8em; color: #777; margin-top: 5px; }
        
        table { width: 100%; border-collapse: collapse; margin-top: 15px; background: white; }
        th, td { border: 1px solid #ddd; padding: 10px; text-align: center; }
        th { background: #f8f9fa; font-size: 0.9em; color: #555; }
        .stone-count { color: #d0021b; font-weight: bold; }
        tr:nth-child(even) { background-color: #fafafa; }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class=&quot;container&quot;&gt;
    &lt;h2&gt;ハンターレベル計算機&lt;/h2&gt;
    
    &lt;div class=&quot;row&quot;&gt;
        &lt;div class=&quot;input-group&quot;&gt;
            &lt;label&gt;現在のレベル&lt;/label&gt;
            &lt;select id=&quot;current-lv&quot; onchange=&quot;updateTargetOptions()&quot;&gt;
                &lt;option value=&quot;1&quot;&gt;Lv.1&lt;/option&gt;&lt;option value=&quot;2&quot;&gt;Lv.2&lt;/option&gt;&lt;option value=&quot;3&quot;&gt;Lv.3&lt;/option&gt;&lt;option value=&quot;4&quot;&gt;Lv.4&lt;/option&gt;&lt;option value=&quot;5&quot;&gt;Lv.5&lt;/option&gt;
                &lt;option value=&quot;6&quot;&gt;Lv.6&lt;/option&gt;&lt;option value=&quot;7&quot;&gt;Lv.7&lt;/option&gt;&lt;option value=&quot;8&quot;&gt;Lv.8&lt;/option&gt;&lt;option value=&quot;9&quot;&gt;Lv.9&lt;/option&gt;&lt;option value=&quot;10&quot;&gt;Lv.10&lt;/option&gt;
                &lt;option value=&quot;11&quot;&gt;Lv.11&lt;/option&gt;&lt;option value=&quot;12&quot;&gt;Lv.12&lt;/option&gt;&lt;option value=&quot;13&quot;&gt;Lv.13&lt;/option&gt;&lt;option value=&quot;14&quot;&gt;Lv.14&lt;/option&gt;&lt;option value=&quot;15&quot;&gt;Lv.15&lt;/option&gt;
                &lt;option value=&quot;16&quot;&gt;Lv.16&lt;/option&gt;&lt;option value=&quot;17&quot;&gt;Lv.17&lt;/option&gt;&lt;option value=&quot;18&quot;&gt;Lv.18&lt;/option&gt;&lt;option value=&quot;19&quot;&gt;Lv.19&lt;/option&gt;&lt;option value=&quot;20&quot;&gt;Lv.20&lt;/option&gt;
                &lt;option value=&quot;21&quot;&gt;Lv.21&lt;/option&gt;&lt;option value=&quot;22&quot;&gt;Lv.22&lt;/option&gt;&lt;option value=&quot;23&quot;&gt;Lv.23&lt;/option&gt;&lt;option value=&quot;24&quot;&gt;Lv.24&lt;/option&gt;&lt;option value=&quot;25&quot;&gt;Lv.25&lt;/option&gt;
                &lt;option value=&quot;26&quot;&gt;Lv.26&lt;/option&gt;&lt;option value=&quot;27&quot;&gt;Lv.27&lt;/option&gt;&lt;option value=&quot;28&quot;&gt;Lv.28&lt;/option&gt;&lt;option value=&quot;29&quot;&gt;Lv.29&lt;/option&gt;&lt;option value=&quot;30&quot;&gt;Lv.30&lt;/option&gt;
                &lt;option value=&quot;31&quot;&gt;Lv.31&lt;/option&gt;&lt;option value=&quot;32&quot;&gt;Lv.32&lt;/option&gt;&lt;option value=&quot;33&quot;&gt;Lv.33&lt;/option&gt;&lt;option value=&quot;34&quot;&gt;Lv.34&lt;/option&gt;&lt;option value=&quot;35&quot;&gt;Lv.35&lt;/option&gt;
                &lt;option value=&quot;36&quot;&gt;Lv.36&lt;/option&gt;&lt;option value=&quot;37&quot;&gt;Lv.37&lt;/option&gt;&lt;option value=&quot;38&quot;&gt;Lv.38&lt;/option&gt;&lt;option value=&quot;39&quot;&gt;Lv.39&lt;/option&gt;&lt;option value=&quot;40&quot;&gt;Lv.40&lt;/option&gt;
                &lt;option value=&quot;41&quot;&gt;Lv.41&lt;/option&gt;&lt;option value=&quot;42&quot;&gt;Lv.42&lt;/option&gt;&lt;option value=&quot;43&quot;&gt;Lv.43&lt;/option&gt;&lt;option value=&quot;44&quot;&gt;Lv.44&lt;/option&gt;&lt;option value=&quot;45&quot;&gt;Lv.45&lt;/option&gt;
                &lt;option value=&quot;46&quot;&gt;Lv.46&lt;/option&gt;&lt;option value=&quot;47&quot;&gt;Lv.47&lt;/option&gt;&lt;option value=&quot;48&quot;&gt;Lv.48&lt;/option&gt;&lt;option value=&quot;49&quot;&gt;Lv.49&lt;/option&gt;
            &lt;/select&gt;
        &lt;/div&gt;
        &lt;div class=&quot;input-group&quot;&gt;
            &lt;label&gt;現在の経験値量&lt;/label&gt;
            &lt;input type=&quot;number&quot; id=&quot;current-xp&quot; value=&quot;0&quot; min=&quot;0&quot; placeholder=&quot;0&quot;&gt;
        &lt;/div&gt;
        &lt;div class=&quot;input-group&quot;&gt;
            &lt;label&gt;消費ノイキャン液数&lt;/label&gt;
            &lt;input type=&quot;number&quot; id=&quot;liquid-count&quot; value=&quot;0&quot; min=&quot;0&quot; placeholder=&quot;0&quot;&gt;
        &lt;/div&gt;
        &lt;span&gt;→&lt;/span&gt;
        &lt;div class=&quot;input-group&quot;&gt;
            &lt;label&gt;目標のレベル&lt;/label&gt;
            &lt;select id=&quot;target-lv&quot;&gt;
                &lt;!-- JSで動的に生成 --&gt;
            &lt;/select&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;button onclick=&quot;calculate()&quot;&gt;必要日数を一括計算する&lt;/button&gt;
    &lt;div id=&quot;result&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;script&gt;
const LV_XP = {
    1:0, 2:100, 3:200, 4:450, 5:600, 6:700, 7:1150, 8:1350, 9:1450, 10:1700,
    11:1780, 12:1860, 13:1940, 14:2020, 15:2110, 16:2200, 17:2290, 18:2380, 19:2470, 20:2560,
    21:3300, 22:3380, 23:3460, 24:3540, 25:3620, 26:3680, 27:3740, 28:3800, 29:3860, 30:3920,
    31:4000, 32:4050, 33:4100, 34:4150, 35:4200, 36:4260, 37:4320, 38:4380, 39:4440, 40:4500,
    41:8800, 42:9800, 43:10880, 44:12050, 45:13310, 46:14670, 47:16140, 48:17730, 49:19450, 50:21310
};
window.addEventListener(&#039;load&#039;, () =&gt; {
    updateTargetOptions();
});
function updateTargetOptions() {
    const currentLvSelect = document.getElementById(&#039;current-lv&#039;);
    const targetLvSelect = document.getElementById(&#039;target-lv&#039;);
    if (!currentLvSelect || !targetLvSelect) return;
    const currentVal = parseInt(currentLvSelect.value);
    const oldTarget = parseInt(targetLvSelect.value);
    targetLvSelect.innerHTML = &#039;&#039;;
    for (let i = currentVal + 1; i &lt;= 50; i++) {
        let opt = document.createElement(&#039;option&#039;);
        opt.value = i;
        opt.textContent = &#039;Lv.&#039; + i;
        if (i === oldTarget || (isNaN(oldTarget) &amp;&amp; i === 50)) {
            opt.selected = true;
        }
        targetLvSelect.appendChild(opt);
    }
}
function calculate() {
    const currentLv = parseInt(document.getElementById(&#039;current-lv&#039;).value);
    const targetLv = parseInt(document.getElementById(&#039;target-lv&#039;).value);
    const currentXP = parseInt(document.getElementById(&#039;current-xp&#039;).value) || 0;
    const liquidCount = parseInt(document.getElementById(&#039;liquid-count&#039;).value) || 0;
    if (currentLv &gt;= targetLv) {
        alert(&#039;目標レベルを正しく設定してください。&#039;);
        return;
    }
    let totalXPNeededFromLvs = 0;
    for (let i = currentLv + 1; i &lt;= targetLv; i++) {
        totalXPNeededFromLvs += LV_XP[i];
    }
    const liquidXP = liquidCount * 300;
    const netXPToEarn = totalXPNeededFromLvs - currentXP - liquidXP;
    const resDiv = document.getElementById(&#039;result&#039;);
    
    if (netXPToEarn &lt;= 0) {
        resDiv.style.display = &#039;block&#039;;
        resDiv.innerHTML = &#039;既に対象のレベルに到達しています！ (ノイキャン液の使用を含みます)&#039;;
        return;
    }
    let tableRows = &quot;&quot;;
    for (let count = 0; count &lt;= 6; count++) {
        let remainingXP = netXPToEarn;
        let days = 0;
        let totalStones = 0;
        while (remainingXP &gt; 0) {
            days++;
            remainingXP -= 2700; 
            if (remainingXP &gt; 0) {
                for (let i = 1; i &lt;= count; i++) {
                    remainingXP -= 300;
                    totalStones += (i &lt;= 3) ? 60 : 120;
                    if (remainingXP &lt;= 0) break;
                }
            }
        }
        
        tableRows += `
            &lt;tr&gt;
                &lt;td&gt;毎日 &lt;strong&gt;${count}&lt;/strong&gt; 回&lt;/td&gt;
                &lt;td class=&quot;important&quot;&gt;${days.toLocaleString()} 日&lt;/td&gt;
                &lt;td class=&quot;stone-count&quot;&gt;${totalStones.toLocaleString()} 個&lt;/td&gt;
            &lt;/tr&gt;
        `;
    }
    resDiv.style.display = &#039;block&#039;;
    resDiv.innerHTML = `
        &lt;strong&gt;【シミュレーション結果】&lt;/strong&gt;&lt;br&gt;
        目標までの実質必要経験値: &lt;strong&gt;${netXPToEarn.toLocaleString()} XP&lt;/strong&gt;
        &lt;div class=&quot;note&quot;&gt;
            (累計 ${totalXPNeededFromLvs.toLocaleString()} - 所持 ${currentXP.toLocaleString()} - 液分 ${liquidXP.toLocaleString()})
        &lt;/div&gt;
        &lt;hr&gt;
        &lt;table&gt;
            &lt;thead&gt;
                &lt;tr&gt;
                    &lt;th&gt;毎日の石割り&lt;/th&gt;
                    &lt;th&gt;到達日数&lt;/th&gt;
                    &lt;th&gt;合計消費石&lt;/th&gt;
                &lt;/tr&gt;
            &lt;/thead&gt;
            &lt;tbody&gt;
                ${tableRows}
            &lt;/tbody&gt;
        &lt;/table&gt;
        &lt;div class=&quot;note&quot; style=&quot;margin-top:12px;&quot;&gt;
            ※最終日に基本の 2700 XP だけ、または設定した回数より少ない石割りで足りる場合、その日の石代は別途計算（節約）されます。&lt;br&gt;
            ※ノイキャン液 ${liquidCount.toLocaleString()} 本をすべて使用した前提で計算しています。&lt;br&gt;
        &lt;/div&gt;
    `;
}
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;


}

**その他の計算機
[[トップページ]]    </description>
    <dc:date>2026-05-25T12:54:30+09:00</dc:date>
    <utime>1779681270</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/ntetool/pages/13.html">
    <title>好感度計算機</title>
    <link>https://w.atwiki.jp/ntetool/pages/13.html</link>
    <description>
      #javascript(){
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ja&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;title&gt;好感度・絆レベル日数計算機&lt;/title&gt;
    &lt;style&gt;
        /* 以前の計算機と統一したデザイン */
        body { font-family: sans-serif; background: #f4f4f9; padding: 20px; color: #333; }
        .container { max-width: 750px; margin: 0 auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
        h2 { border-bottom: 2px solid #ddd; padding-bottom: 10px; }
        .config-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; margin-bottom: 15px; }
        .config-item { display: flex; flex-direction: column; font-size: 0.9em; }
        select, input { padding: 8px; border: 1px solid #ccc; border-radius: 4px; margin-top: 4px; }
        .input-highlight { background: #fffdf0; border-color: #f39c12; }
        button { width: 100%; padding: 12px; background: #4a90e2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1.1em; margin-top: 20px; }
        button:hover { background: #357abd; }
        #result { margin-top: 20px; padding: 15px; border-left: 5px solid #4a90e2; background: #f0f7ff; display: none; line-height: 1.6; }
        hr { border: 0; border-top: 1px solid #ccc; margin: 15px 0; }
        
        /* テーブル用スタイル */
        table { width: 100%; border-collapse: collapse; margin-top: 10px; background: #fff; }
        th, td { border: 1px solid #ddd; padding: 10px; text-align: center; }
        th { background-color: #4a90e2; color: white; }
        tr:nth-child(even) { background-color: #f9f9f9; }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;div class=&quot;container&quot;&gt;
    &lt;h2&gt;好感度・絆レベル日数計算&lt;/h2&gt;
    
    &lt;div class=&quot;config-grid&quot;&gt;
        &lt;!-- 現在のステータス --&gt;
        &lt;div class=&quot;config-item&quot;&gt;
            &lt;label&gt;現在の絆レベル:&lt;/label&gt;
            &lt;select id=&quot;current-lv&quot;&gt;
                &lt;option value=&quot;1&quot;&gt;Lv 1&lt;/option&gt;
                &lt;option value=&quot;2&quot;&gt;Lv 2&lt;/option&gt;
                &lt;option value=&quot;3&quot;&gt;Lv 3&lt;/option&gt;
                &lt;option value=&quot;4&quot;&gt;Lv 4&lt;/option&gt;
                &lt;option value=&quot;5&quot; selected&gt;Lv 5&lt;/option&gt;
                &lt;option value=&quot;6&quot;&gt;Lv 6&lt;/option&gt;
                &lt;option value=&quot;7&quot;&gt;Lv 7&lt;/option&gt;
                &lt;option value=&quot;8&quot;&gt;Lv 8&lt;/option&gt;
                &lt;option value=&quot;9&quot;&gt;Lv 9&lt;/option&gt;
            &lt;/select&gt;
        &lt;/div&gt;
        &lt;div class=&quot;config-item&quot;&gt;
            &lt;label&gt;現在の好感度 (現在貯まっている分):&lt;/label&gt;
            &lt;input type=&quot;number&quot; id=&quot;current-exp&quot; placeholder=&quot;例: 200&quot; min=&quot;0&quot;&gt;
        &lt;/div&gt;

        &lt;!-- 日常ルーティン設定 --&gt;
        &lt;div class=&quot;config-item&quot;&gt;
            &lt;label&gt;プレゼントの好感度種類:&lt;/label&gt;
            &lt;select id=&quot;present-type&quot;&gt;
                &lt;option value=&quot;50&quot;&gt;50&lt;/option&gt;
                &lt;option value=&quot;100&quot;&gt;100&lt;/option&gt;
                &lt;option value=&quot;200&quot;&gt;200&lt;/option&gt;
                &lt;option value=&quot;400&quot; selected&gt;400&lt;/option&gt;
            &lt;/select&gt;
        &lt;/div&gt;
        &lt;div class=&quot;config-item&quot;&gt;
            &lt;label&gt;毎日のプレゼント回数:&lt;/label&gt;
            &lt;select id=&quot;present-count&quot;&gt;
                &lt;option value=&quot;1&quot;&gt;1回&lt;/option&gt;
                &lt;option value=&quot;2&quot;&gt;2回&lt;/option&gt;
                &lt;option value=&quot;3&quot; selected&gt;3回&lt;/option&gt;
            &lt;/select&gt;
        &lt;/div&gt;
        &lt;div class=&quot;config-item&quot;&gt;
            &lt;label&gt;デートの頻度:&lt;/label&gt;
            &lt;select id=&quot;date-frequency&quot;&gt;
                &lt;option value=&quot;1&quot; selected&gt;毎日&lt;/option&gt;
                &lt;option value=&quot;2&quot;&gt;2日に1回&lt;/option&gt;
                &lt;option value=&quot;3&quot;&gt;3日に1回&lt;/option&gt;
                &lt;option value=&quot;0&quot;&gt;しない&lt;/option&gt;
            &lt;/select&gt;
        &lt;/div&gt;

        &lt;!-- スキル・その他ブースト --&gt;
        &lt;div class=&quot;config-item&quot;&gt;
            &lt;label&gt;主人公のシティスキル Lv (0〜5):&lt;/label&gt;
            &lt;select id=&quot;city-skill&quot; class=&quot;input-highlight&quot;&gt;
                &lt;option value=&quot;0&quot;&gt;0 (補正なし)&lt;/option&gt;
                &lt;option value=&quot;1&quot;&gt;1 (絆4以下で+5%)&lt;/option&gt;
                &lt;option value=&quot;2&quot;&gt;2 (絆5以下で+5%)&lt;/option&gt;
                &lt;option value=&quot;3&quot;&gt;3 (絆6以下で+5%)&lt;/option&gt;
                &lt;option value=&quot;4&quot;&gt;4 (絆7以下で+5%)&lt;/option&gt;
                &lt;option value=&quot;5&quot; selected&gt;5 (絆8以下で+5%)&lt;/option&gt;
            &lt;/select&gt;
        &lt;/div&gt;
        &lt;div class=&quot;config-item&quot;&gt;
            &lt;label&gt;手書きの手紙 使用数 (1枚ごとに+2000):&lt;/label&gt;
            &lt;input type=&quot;number&quot; id=&quot;letter-count&quot; placeholder=&quot;枚数を入力&quot; min=&quot;0&quot;&gt;
        &lt;/div&gt;
        &lt;div class=&quot;config-item&quot;&gt;
            &lt;label&gt;プレゼント1個あたりの価格 (任意):&lt;/label&gt;
            &lt;input type=&quot;number&quot; id=&quot;present-price&quot; placeholder=&quot;価格を入力&quot; min=&quot;0&quot;&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;button onclick=&quot;calculate()&quot;&gt;必要日数を計算する&lt;/button&gt;

    &lt;div id=&quot;result&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;script&gt;
// 各レベルに「到達する」ために、そのレベル単体で必要な値
const LV_REQUIREMENTS = {
    1: 0,
    2: 500,
    3: 1000,
    4: 2000,
    5: 3500,
    6: 5000,
    7: 7000,
    8: 9000,
    9: 12000,
    10: 16000
};

// 累積必要好感度（0から数えた合計値）を計算
const CUMULATIVE_XP = {};
let acc = 0;
for (let lv = 1; lv &lt;= 10; lv++) {
    acc += LV_REQUIREMENTS[lv];
    CUMULATIVE_XP[lv] = acc;
}

function calculate() {
    // 入力値の取得
    const startLv = parseInt(document.getElementById(&#039;current-lv&#039;).value);
    const currentExp = parseInt(document.getElementById(&#039;current-exp&#039;).value) || 0;
    const presentXpBase = parseInt(document.getElementById(&#039;present-type&#039;).value);
    const dailyPresentCount = parseInt(document.getElementById(&#039;present-count&#039;).value);
    const dateFreq = parseInt(document.getElementById(&#039;date-frequency&#039;).value);
    const citySkill = parseInt(document.getElementById(&#039;city-skill&#039;).value);
    const letterCount = parseInt(document.getElementById(&#039;letter-count&#039;).value) || 0;
    const presentPrice = parseInt(document.getElementById(&#039;present-price&#039;).value) || 0;

    // 現在の初期総経験値を算出
    let initialTotalXp = CUMULATIVE_XP[startLv] + currentExp;
    
    // 手書きの手紙による即座の上乗せ
    initialTotalXp += letterCount * 2000;

    // スキルが適用される最大レベルの判定
    const maxSkillLv = citySkill === 0 ? 0 : citySkill + 3;

    // 総経験値から現在の絆レベルを逆引きする関数
    function getLevelFromXp(xp) {
        for (let lv = 10; lv &gt;= 1; lv--) {
            if (xp &gt;= CUMULATIVE_XP[lv]) return lv;
        }
        return 1;
    }

    let tableRowsHtml = &#039;&#039;;

    // 選んだ絆レベルの次のレベルから10までをループ処理
    for (let targetLv = startLv + 1; targetLv &lt;= 10; targetLv++) {
        const targetXp = CUMULATIVE_XP[targetLv];
        
        let day = 0;
        let totalPresentsGiven = 0;
        let loopXp = initialTotalXp;

        // 目標の経験値に届くまで1日ずつループ
        while (loopXp &lt; targetXp) {
            day++;

            // 1. プレゼントを1回ずつ渡す処理（途中でスキルが切れるのを検知するため）
            for (let p = 0; p &lt; dailyPresentCount; p++) {
                if (loopXp &gt;= targetXp) break;

                let currentLv = getLevelFromXp(loopXp);
                let bonus = 1.0;
                if (citySkill &gt; 0 &amp;&amp; currentLv &lt;= maxSkillLv) {
                    bonus = 1.05;
                }
                
                loopXp += Math.floor(presentXpBase * bonus);
                totalPresentsGiven++;
            }

            // 2. デートによる好感度加算
            if (loopXp &gt;= targetXp) break;
            if (dateFreq &gt; 0) {
                if ((day - 1) % dateFreq === 0) {
                    loopXp += 200;
                }
            }
        }

        // 必要価格の計算
        const totalPrice = totalPresentsGiven * presentPrice;
        const priceDisplay = presentPrice &gt; 0 ? `${totalPrice.toLocaleString()} ファンス` : &#039;---&#039;;

        tableRowsHtml += `
            &lt;tr&gt;
                &lt;td&gt;&lt;strong&gt;Lv ${targetLv}&lt;/strong&gt;&lt;/td&gt;
                &lt;td&gt;${day} 日&lt;/td&gt;
                &lt;td&gt;${priceDisplay}&lt;/td&gt;
            &lt;/tr&gt;
        `;
    }

    // 結果を出力
    const resDiv = document.getElementById(&#039;result&#039;);
    resDiv.style.display = &#039;block&#039;;

    resDiv.innerHTML = `
        &lt;strong&gt;【シミュレーション結果】&lt;/strong&gt;&lt;br&gt;
        手紙による即時獲得: ${(letterCount * 2000).toLocaleString()} XP&lt;br&gt;
        &lt;small&gt;※プレゼントを1回渡すたびにリアルタイムでレベルアップ判定とスキル補正（+5%）の有無を計算しています。&lt;/small&gt;
        &lt;hr&gt;
        &lt;table&gt;
            &lt;thead&gt;
                &lt;tr&gt;
                    &lt;th&gt;目標絆レベル&lt;/th&gt;
                    &lt;th&gt;必要日数&lt;/th&gt;
                    &lt;th&gt;必要価格&lt;/th&gt;
                &lt;/tr&gt;
            &lt;/thead&gt;
            &lt;tbody&gt;
                ${tableRowsHtml}
            &lt;/tbody&gt;
        &lt;/table&gt;
    `;
}
&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;

}    </description>
    <dc:date>2026-05-23T12:18:37+09:00</dc:date>
    <utime>1779506317</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/ntetool/pages/11.html">
    <title>弧盤レベル計算機</title>
    <link>https://w.atwiki.jp/ntetool/pages/11.html</link>
    <description>
      #javascript(){

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ja&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;title&gt;弧盤(武器) 育成コスト計算機&lt;/title&gt;
    &lt;style&gt;
        /* キャラ計算機と統一したデザイン */
        body { font-family: sans-serif; background: #f4f4f9; padding: 20px; color: #333; }
        .container { max-width: 750px; margin: 0 auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
        h2 { border-bottom: 2px solid #ddd; padding-bottom: 10px; }
        .row { display: flex; align-items: center; margin-bottom: 10px; gap: 8px; flex-wrap: wrap; }
        .row-num { width: 25px; font-size: 0.8em; color: #666; }
        select, input { padding: 8px; border: 1px solid #ccc; border-radius: 4px; }
        .multiplier-select { background: #fffdf0; border-color: #f39c12; }
        .inventory { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 20px; padding: 15px; background: #eee; border-radius: 8px; }
        .inventory label { display: flex; flex-direction: column; font-size: 0.9em; }
        button { width: 100%; padding: 12px; background: #4a90e2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1.1em; margin-top: 20px; }
        button:hover { background: #357abd; }
        #result { margin-top: 20px; padding: 15px; border-left: 5px solid #4a90e2; background: #f0f7ff; display: none; line-height: 1.6; }
        .shortage { color: #d0021b; font-weight: bold; }
        hr { border: 0; border-top: 1px solid #ccc; margin: 10px 0; }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;div class=&quot;container&quot;&gt;
    &lt;h2&gt;弧盤(武器) 育成コスト計算&lt;/h2&gt;
    
    &lt;div id=&quot;level-rows&quot;&gt;
        &lt;!-- JSで動的に追加 --&gt;
    &lt;/div&gt;

    &lt;div class=&quot;inventory&quot;&gt;
        &lt;label&gt;緑 (500XP): &lt;input type=&quot;number&quot; id=&quot;inv-green&quot; value=&quot;0&quot; min=&quot;0&quot;&gt;&lt;/label&gt;
        &lt;label&gt;青 (2500XP): &lt;input type=&quot;number&quot; id=&quot;inv-blue&quot; value=&quot;0&quot; min=&quot;0&quot;&gt;&lt;/label&gt;
        &lt;label&gt;紫 (10000XP): &lt;input type=&quot;number&quot; id=&quot;inv-purple&quot; value=&quot;0&quot; min=&quot;0&quot;&gt;&lt;/label&gt;
        &lt;label&gt;甲虫コイン: &lt;input type=&quot;number&quot; id=&quot;inv-coin&quot; value=&quot;0&quot; min=&quot;0&quot;&gt;&lt;/label&gt;
    &lt;/div&gt;

    &lt;button onclick=&quot;calculate()&quot;&gt;計算する&lt;/button&gt;

    &lt;div id=&quot;result&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;script&gt;
// 武器用データ定義
const XP_COSTS = {
    1: 40000, 20: 100000, 30: 212500, 40: 327500, 50: 612500, 60: 860000, 70: 1490000
};

const COIN_COSTS = {
    &#039;青&#039;: { 1: 12000, 20: 42000, 30: 84000, 40: 134000, 50: 220000, 60: 333750, 70: 519000 },
    &#039;紫&#039;: { 1: 12000, 20: 46000, 30: 92000, 40: 150000, 50: 232000, 60: 353750, 70: 543000 },
    &#039;金&#039;: { 1: 12000, 20: 54000, 30: 108000, 40: 162000, 50: 252000, 60: 360000, 70: 564750 }
};

let rowCount = 0;

// DOM読み込み完了後に実行
window.addEventListener(&#039;DOMContentLoaded&#039;, () =&gt; {
    createRow();
});

function createRow() {
    const rowContainer = document.getElementById(&#039;level-rows&#039;);
    if (!rowContainer || rowCount &gt;= 20) return;
    
    rowCount++;
    const div = document.createElement(&#039;div&#039;);
    div.className = &#039;row&#039;;
    
    let multOptions = &#039;&#039;;
    for(let i=1; i&lt;=20; i++) {
        multOptions += `&lt;option value=&quot;${i}&quot;&gt;${i}&lt;/option&gt;`;
    }

    div.innerHTML = `
        &lt;span class=&quot;row-num&quot;&gt;${rowCount}.&lt;/span&gt;
        &lt;select class=&quot;rarity-select&quot;&gt;
            &lt;option value=&quot;青&quot;&gt;青&lt;/option&gt;
            &lt;option value=&quot;紫&quot;&gt;紫&lt;/option&gt;
            &lt;option value=&quot;金&quot;&gt;金&lt;/option&gt;
        &lt;/select&gt;
        &lt;select class=&quot;from-lv&quot; onchange=&quot;updateToOptions(this)&quot;&gt;
            &lt;option value=&quot;&quot;&gt;選択&lt;/option&gt;
            ${[1, 20, 30, 40, 50, 60, 70].map(v =&gt; `&lt;option value=&quot;${v}&quot;&gt;${v}&lt;/option&gt;`).join(&#039;&#039;)}
        &lt;/select&gt;
        &lt;span&gt;→&lt;/span&gt;
        &lt;select class=&quot;to-lv&quot;&gt;
            &lt;option value=&quot;80&quot;&gt;80&lt;/option&gt;
        &lt;/select&gt;
        &lt;span&gt; × &lt;/span&gt;
        &lt;select class=&quot;multiplier-select&quot;&gt;
            ${multOptions}
        &lt;/select&gt;
        &lt;span&gt;個&lt;/span&gt;
    `;
    rowContainer.appendChild(div);

    const fromSelect = div.querySelector(&#039;.from-lv&#039;);
    fromSelect.addEventListener(&#039;change&#039;, function() {
        if (this.value &amp;&amp; div === rowContainer.lastElementChild) {
            createRow();
        }
    }, { once: true });
}

function updateToOptions(el) {
    const fromVal = parseInt(el.value);
    const toSelect = el.parentElement.querySelector(&#039;.to-lv&#039;);
    if (!fromVal) return;

    let options = &#039;&#039;;
    const startTo = (fromVal === 1) ? 20 : fromVal + 10;

    for (let v = startTo; v &lt;= 80; v += 10) {
        options += `&lt;option value=&quot;${v}&quot; ${v === 80 ? &#039;selected&#039; : &#039;&#039;}&gt;${v}&lt;/option&gt;`;
    }
    toSelect.innerHTML = options;
}

function calculate() {
    let totalNeededXP = 0;
    let totalNeededCoin = 0;

    document.querySelectorAll(&#039;.row&#039;).forEach(row =&gt; {
        const rarity = row.querySelector(&#039;.rarity-select&#039;).value;
        const fromVal = row.querySelector(&#039;.from-lv&#039;).value;
        const toVal = row.querySelector(&#039;.to-lv&#039;).value;
        const multiplier = parseInt(row.querySelector(&#039;.multiplier-select&#039;).value) || 1;
        
        if (fromVal !== &quot;&quot; &amp;&amp; toVal !== &quot;&quot;) {
            let from = parseInt(fromVal);
            let to = parseInt(toVal);
            let subXP = 0;
            let subCoin = 0;

            let curr = from;
            while (curr &lt; to) {
                if (!XP_COSTS[curr]) break;
                subXP += XP_COSTS[curr];
                subCoin += COIN_COSTS[rarity][curr];
                curr = (curr === 1) ? 20 : curr + 10;
            }
            totalNeededXP += (subXP * multiplier);
            totalNeededCoin += (subCoin * multiplier);
        }
    });

    const invGreen = parseInt(document.getElementById(&#039;inv-green&#039;).value) || 0;
    const invBlue = parseInt(document.getElementById(&#039;inv-blue&#039;).value) || 0;
    const invPurple = parseInt(document.getElementById(&#039;inv-purple&#039;).value) || 0;
    const invCoin = parseInt(document.getElementById(&#039;inv-coin&#039;).value) || 0;

    const currentTotalXP = (invGreen * 500) + (invBlue * 2500) + (invPurple * 10000);
    
    let shortageXP = Math.max(0, totalNeededXP - currentTotalXP);
    let shortageCoin = Math.max(0, totalNeededCoin - invCoin);

    let remainXP = shortageXP;
    const needPurple = Math.floor(remainXP / 10000);
    remainXP %= 10000;
    const needBlue = Math.floor(remainXP / 2500);
    remainXP %= 2500;
    const needGreen = Math.ceil(remainXP / 500);

    // フディニVの周回計算 (武器用: 1回あたり計113,500 XP、40ピクセル消費)
    const foudiniXP = 3500 + 20000 + 90000;
    const needFoudini = Math.ceil(shortageXP / foudiniXP);
    const needPixels = needFoudini * 40;

    // フディニVIの周回計算 (武器用: 1回あたり計125,000 XP、40ピクセル消費)
    const foudini6XP = 125000;
    const needFoudini6 = Math.ceil(shortageXP / foudini6XP);
    const needPixels6 = needFoudini6 * 40;

    const resDiv = document.getElementById(&#039;result&#039;);
    resDiv.style.display = &#039;block&#039;;
    
    if (totalNeededXP === 0) {
        resDiv.innerHTML = &#039;レベルを選択してください。&#039;;
        return;
    }

    resDiv.innerHTML = `
        &lt;strong&gt;【合計必要量】&lt;/strong&gt;&lt;br&gt;
        合計経験値: ${totalNeededXP.toLocaleString()} XP&lt;br&gt;
        合計コイン: ${totalNeededCoin.toLocaleString()} 枚&lt;br&gt;
        &lt;hr&gt;
        &lt;strong&gt;【不足分】&lt;/strong&gt;&lt;br&gt;
        経験値: &lt;span class=&quot;shortage&quot;&gt;${shortageXP.toLocaleString()} XP&lt;/span&gt;&lt;br&gt;
        コイン: &lt;span class=&quot;shortage&quot;&gt;${shortageCoin.toLocaleString()} 枚&lt;/span&gt;&lt;br&gt;
        &lt;br&gt;
        &lt;strong&gt;【必要なアイテム (紫から優先)】&lt;/strong&gt;&lt;br&gt;
        ・&lt;strong&gt;紫 (10000 XP)&lt;/strong&gt;: ${needPurple.toLocaleString()} 個&lt;br&gt;
        ・&lt;strong&gt;青 (2500 XP)&lt;/strong&gt;: ${needBlue.toLocaleString()} 個&lt;br&gt;
        ・&lt;strong&gt;緑 (500 XP)&lt;/strong&gt;: ${needGreen.toLocaleString()} 個&lt;br&gt;
        &lt;hr&gt;
        不足経験値:フディニV ${needFoudini.toLocaleString()}回分 必要ピクセル:${needPixels.toLocaleString()}&lt;br&gt;
        不足経験値:フディニVI ${needFoudini6.toLocaleString()}回分 必要ピクセル:${needPixels6.toLocaleString()}
    `;
}
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;


}

**その他の計算機
[[トップページ]]    </description>
    <dc:date>2026-05-22T14:38:16+09:00</dc:date>
    <utime>1779428296</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/ntetool/pages/10.html">
    <title>キャラレベル計算機</title>
    <link>https://w.atwiki.jp/ntetool/pages/10.html</link>
    <description>
      #javascript(){

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ja&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;title&gt;キャラ育成コスト計算機&lt;/title&gt;
    &lt;style&gt;
        body { font-family: sans-serif; background: #f4f4f9; padding: 20px; color: #333; }
        .container { max-width: 750px; margin: 0 auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
        h2 { border-bottom: 2px solid #ddd; padding-bottom: 10px; }
        .row { display: flex; align-items: center; margin-bottom: 10px; gap: 8px; flex-wrap: wrap; }
        .row-num { width: 25px; font-size: 0.8em; color: #666; }
        select, input { padding: 8px; border: 1px solid #ccc; border-radius: 4px; }
        .multiplier-select { background: #fffdf0; border-color: #f39c12; }
        .inventory { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 20px; padding: 15px; background: #eee; border-radius: 8px; }
        .inventory label { display: flex; flex-direction: column; font-size: 0.9em; }
        button { width: 100%; padding: 12px; background: #4a90e2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1.1em; margin-top: 20px; }
        button:hover { background: #357abd; }
        #result { margin-top: 20px; padding: 15px; border-left: 5px solid #4a90e2; background: #f0f7ff; display: none; line-height: 1.6; }
        .shortage { color: #d0021b; font-weight: bold; }
        hr { border: 0; border-top: 1px solid #ccc; margin: 10px 0; }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;div class=&quot;container&quot;&gt;
    &lt;h2&gt;育成コスト計算&lt;/h2&gt;
    
    &lt;div id=&quot;level-rows&quot;&gt;
        &lt;/div&gt;

    &lt;div class=&quot;inventory&quot;&gt;
        &lt;label&gt;緑 (新鋭: 1000XP): &lt;input type=&quot;number&quot; id=&quot;inv-green&quot; value=&quot;0&quot; min=&quot;0&quot;&gt;&lt;/label&gt;
        &lt;label&gt;青 (熟練: 5000XP): &lt;input type=&quot;number&quot; id=&quot;inv-blue&quot; value=&quot;0&quot; min=&quot;0&quot;&gt;&lt;/label&gt;
        &lt;label&gt;紫 (特急: 20000XP): &lt;input type=&quot;number&quot; id=&quot;inv-purple&quot; value=&quot;0&quot; min=&quot;0&quot;&gt;&lt;/label&gt;
        &lt;label&gt;甲虫コイン: &lt;input type=&quot;number&quot; id=&quot;inv-coin&quot; value=&quot;0&quot; min=&quot;0&quot;&gt;&lt;/label&gt;
    &lt;/div&gt;

    &lt;button onclick=&quot;calculate()&quot;&gt;計算する&lt;/button&gt;

    &lt;div id=&quot;result&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;script&gt;
// データ定義
const COSTS = {
    1:  { xp: 101000,  coin: 25250 },  // 1→20
    20: { xp: 216000,  coin: 54000 },  // 20→30
    30: { xp: 375000,  coin: 143750 },
    40: { xp: 600000,  coin: 225000 },
    50: { xp: 1000000, coin: 350000 },
    60: { xp: 1600000, coin: 525000 },
    70: { xp: 2604000, coin: 801000 }
};

let rowCount = 0;

// DOMの読み込みが完了してから初期行を作成する
window.addEventListener(&#039;DOMContentLoaded&#039;, () =&gt; {
    createRow();
});

function createRow() {
    const rowContainer = document.getElementById(&#039;level-rows&#039;);
    if (!rowContainer || rowCount &gt;= 20) return;
    
    rowCount++;
    const div = document.createElement(&#039;div&#039;);
    div.className = &#039;row&#039;;
    
    let multOptions = &#039;&#039;;
    for(let i=1; i&lt;=20; i++) {
        multOptions += `&lt;option value=&quot;${i}&quot;&gt;${i}&lt;/option&gt;`;
    }

    div.innerHTML = `
        &lt;span class=&quot;row-num&quot;&gt;${rowCount}.&lt;/span&gt;
        &lt;select class=&quot;from-lv&quot; onchange=&quot;updateToOptions(this)&quot;&gt;
            &lt;option value=&quot;&quot;&gt;選択&lt;/option&gt;
            ${[1, 20, 30, 40, 50, 60, 70].map(v =&gt; `&lt;option value=&quot;${v}&quot;&gt;${v}&lt;/option&gt;`).join(&#039;&#039;)}
        &lt;/select&gt;
        &lt;span&gt;→&lt;/span&gt;
        &lt;select class=&quot;to-lv&quot;&gt;
            &lt;option value=&quot;80&quot;&gt;80&lt;/option&gt;
        &lt;/select&gt;
        &lt;span&gt; × &lt;/span&gt;
        &lt;select class=&quot;multiplier-select&quot;&gt;
            ${multOptions}
        &lt;/select&gt;
        &lt;span&gt;体&lt;/span&gt;
    `;
    rowContainer.appendChild(div);

    // 最初の選択が行われたときに次の行を生成するリスナー
    const fromSelect = div.querySelector(&#039;.from-lv&#039;);
    fromSelect.addEventListener(&#039;change&#039;, function() {
        if (this.value &amp;&amp; div === rowContainer.lastElementChild) {
            createRow();
        }
    }, { once: true });
}

function updateToOptions(el) {
    const fromVal = parseInt(el.value);
    const toSelect = el.parentElement.querySelector(&#039;.to-lv&#039;);
    if (!fromVal) return;

    let options = &#039;&#039;;
    // 1が選ばれたら次は20から、それ以外は+10から
    const startTo = (fromVal === 1) ? 20 : fromVal + 10;

    for (let v = startTo; v &lt;= 80; v += 10) {
        options += `&lt;option value=&quot;${v}&quot; ${v === 80 ? &#039;selected&#039; : &#039;&#039;}&gt;${v}&lt;/option&gt;`;
    }
    toSelect.innerHTML = options;
}

function calculate() {
    let totalNeededXP = 0;
    let totalNeededCoin = 0;

    document.querySelectorAll(&#039;.row&#039;).forEach(row =&gt; {
        const fromVal = row.querySelector(&#039;.from-lv&#039;).value;
        const toVal = row.querySelector(&#039;.to-lv&#039;).value;
        const multiplier = parseInt(row.querySelector(&#039;.multiplier-select&#039;).value) || 1;
        
        if (fromVal !== &quot;&quot; &amp;&amp; toVal !== &quot;&quot;) {
            let from = parseInt(fromVal);
            let to = parseInt(toVal);
            let subTotalXP = 0;
            let subTotalCoin = 0;

            let current = from;
            while (current &lt; to) {
                if (!COSTS[current]) break;
                subTotalXP += COSTS[current].xp;
                subTotalCoin += COSTS[current].coin;
                
                if (current === 1) current = 20;
                else current += 10;
            }

            totalNeededXP += (subTotalXP * multiplier);
            totalNeededCoin += (subTotalCoin * multiplier);
        }
    });

    const invGreen = parseInt(document.getElementById(&#039;inv-green&#039;).value) || 0;
    const invBlue = parseInt(document.getElementById(&#039;inv-blue&#039;).value) || 0;
    const invPurple = parseInt(document.getElementById(&#039;inv-purple&#039;).value) || 0;
    const invCoin = parseInt(document.getElementById(&#039;inv-coin&#039;).value) || 0;

    const currentTotalXP = (invGreen * 1000) + (invBlue * 5000) + (invPurple * 20000);
    
    let shortageXP = Math.max(0, totalNeededXP - currentTotalXP);
    let shortageCoin = Math.max(0, totalNeededCoin - invCoin);

    let remainXP = shortageXP;
    const needPurple = Math.floor(remainXP / 20000);
    remainXP %= 20000;
    
    const needBlue = Math.floor(remainXP / 5000);
    remainXP %= 5000;
    
    const needGreen = Math.ceil(remainXP / 1000);

    // フディニVの周回計算 (1回あたり計202,000 XP、40ピクセル消費)
    const foudiniXP = 7000 + 35000 + 160000;
    const needFoudini = Math.ceil(shortageXP / foudiniXP);
    const needPixels = needFoudini * 40;

    // フディニVIの周回計算 (1回あたり計225,000 XP、40ピクセル消費)
    const foudini6XP = 225000;
    const needFoudini6 = Math.ceil(shortageXP / foudini6XP);
    const needPixels6 = needFoudini6 * 40;

    const resDiv = document.getElementById(&#039;result&#039;);
    resDiv.style.display = &#039;block&#039;;
    
    if (totalNeededXP === 0) {
        resDiv.innerHTML = &#039;レベルを選択してください。&#039;;
        return;
    }

    resDiv.innerHTML = `
        &lt;strong&gt;【合計必要量】&lt;/strong&gt;&lt;br&gt;
        合計経験値: ${totalNeededXP.toLocaleString()} XP&lt;br&gt;
        合計コイン: ${totalNeededCoin.toLocaleString()} 枚&lt;br&gt;
        &lt;hr&gt;
        &lt;strong&gt;【不足分】&lt;/strong&gt;&lt;br&gt;
        経験値: &lt;span class=&quot;shortage&quot;&gt;${shortageXP.toLocaleString()} XP&lt;/span&gt;&lt;br&gt;
        コイン: &lt;span class=&quot;shortage&quot;&gt;${shortageCoin.toLocaleString()} 枚&lt;/span&gt;&lt;br&gt;
        &lt;br&gt;
        &lt;strong&gt;【必要な本 (紫から優先)】&lt;/strong&gt;&lt;br&gt;
        ・&lt;strong&gt;紫 (特急: 20000)&lt;/strong&gt;: ${needPurple.toLocaleString()} 個&lt;br&gt;
        ・&lt;strong&gt;青 (熟練: 5000)&lt;/strong&gt;: ${needBlue.toLocaleString()} 個&lt;br&gt;
        ・&lt;strong&gt;緑 (新鋭: 1000)&lt;/strong&gt;: ${needGreen.toLocaleString()} 個&lt;br&gt;
        &lt;hr&gt;
        不足経験値:フディニV ${needFoudini.toLocaleString()}回分 必要ピクセル:${needPixels.toLocaleString()}&lt;br&gt;
        不足経験値:フディニVI ${needFoudini6.toLocaleString()}回分 必要ピクセル:${needPixels6.toLocaleString()}
    `;
}
&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;

}

**その他の計算機
[[トップページ]]    </description>
    <dc:date>2026-05-22T14:34:17+09:00</dc:date>
    <utime>1779428057</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/ntetool/pages/2.html">
    <title>メニュー</title>
    <link>https://w.atwiki.jp/ntetool/pages/2.html</link>
    <description>
      **メニュー
-[[トップページ]]
-[[プラグイン紹介&gt;プラグイン]]
-[[メニュー]]
-[[右メニュー]]

----

**リンク
-[[@wiki&gt;&gt;http://atwiki.jp]]
-[[@wikiご利用ガイド&gt;&gt;http://atwiki.jp/guide/]]

// リンクを張るには &quot;[&quot; 2つで文字列を括ります。
// &quot;&gt;&quot; の左側に文字、右側にURLを記述するとリンクになります


//**更新履歴
//#recent(20)

&amp;link_editmenu(text=ここを編集)
    </description>
    <dc:date>2026-05-12T12:30:06+09:00</dc:date>
    <utime>1778556606</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/ntetool/pages/3.html">
    <title>右メニュー</title>
    <link>https://w.atwiki.jp/ntetool/pages/3.html</link>
    <description>
      **更新履歴
#recent(20)


&amp;link_editmenu2(text=ここを編集)
    </description>
    <dc:date>2026-05-12T12:30:06+09:00</dc:date>
    <utime>1778556606</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/ntetool/pages/4.html">
    <title>プラグイン/ニュース</title>
    <link>https://w.atwiki.jp/ntetool/pages/4.html</link>
    <description>
      * ニュース
@wikiのwikiモードでは
 #news(興味のある単語)
と入力することで、あるキーワードに関連するニュース一覧を表示することができます
詳しくはこちらをご覧ください。
＝＞http://www1.atwiki.jp/guide/pages/266.html#id_542badf7


-----


たとえば、#news(ゲーム)と入力すると以下のように表示されます。


#news(ゲーム)
    </description>
    <dc:date>2026-05-12T12:30:06+09:00</dc:date>
    <utime>1778556606</utime>
  </item>
  </rdf:RDF>
