ブループロトコル スターレゾナンス(スタレゾ)のレイド蝕花の残影のパスワード処理

ゲーム

スタレゾのレイドである、幻花沈む地の蝕花の残影ことロボの途中にある装置のプログラムを素早く解読するというか二手に分かれて4桁の数字を2桁ずつ入力して当てるという仕組みですが、単純ながら時間に追われる状況と責任がのしかかり中々うまく行かない事もあるでしょう。

以下のJavaScriptで作ったツールを使ってもらえれば多少なりとも成功率向上に貢献できるのではないかと思いますので是非ご活用下さい。

以下のコードをたとえば、p.html としてファイルに保存しダブルクリックでブラウザで開くと動きますのでおためしあれ。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>4桁連係推理シミュレーター</title>
    <style>
        body {
            font-family: sans-serif;
            max-width: 650px;
            margin: 20px auto;
            padding: 0 20px;
            line-height: 1.6;
            background-color: #f8f9fa;
        }
        .box {
            background-color: #ffffff;
            padding: 25px;
            border-radius: 12px;
            margin-bottom: 20px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.05);
            border: 1px solid #e9ecef;
        }
        /* 数字の視覚表示(前2桁・後ろ2桁を色分け) */
        .digit-container {
            display: inline-flex;
            font-size: 36px;
            font-weight: bold;
            letter-spacing: 4px;
            margin: 10px 0 20px 0;
            border: 2px solid #dee2e6;
            border-radius: 8px;
            overflow: hidden;
        }
        .digit-part {
            padding: 5px 15px;
        }
        .part-front {
            background-color: #e3f2fd;
            color: #0d47a1;
        }
        .part-back {
            background-color: #fff3e0;
            color: #e65100;
        }
        
        button {
            font-size: 16px;
            padding: 12px 20px;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-weight: bold;
            transition: all 0.2s;
        }
        /* 間違い個数選択用の青ボタン */
        .mismatch-btn {
            background-color: #007bff;
            color: white;
            box-shadow: 0 2px 4px rgba(0,123,255,0.2);
        }
        .mismatch-btn:hover {
            background-color: #0056b3;
        }
        /* 正解(0個)用の緑ボタン */
        .correct-btn {
            background-color: #28a745;
            color: white;
            box-shadow: 0 2px 4px rgba(40,167,69,0.2);
        }
        .correct-btn:hover {
            background-color: #218838;
        }
        /* 候補数字用のボタン。前後の色分けをミニマルに表現 */
        .code-btn {
            background-color: #ffffff;
            color: #333;
            border: 2px solid #ced4da;
            letter-spacing: 1px;
        }
        .code-btn:hover {
            background-color: #e9ecef;
            border-color: #adb5bd;
        }
        .btn-container {
            margin-top: 15px;
            display: flex;
            flex-wrap: wrap;
            gap: 12px;
        }
        .history {
            border-top: 2px solid #dee2e6;
            padding-top: 15px;
        }
        .history-row {
            padding: 6px 0;
            border-bottom: 1px dashed #dee2e6;
        }
        .success {
            color: #28a745;
            font-weight: bold;
            font-size: 20px;
        }
        .count-badge {
            background-color: #e9ecef;
            padding: 4px 8px;
            border-radius: 6px;
            font-size: 14px;
            color: #495057;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <div class="box" id="game-zone">
        <div id="step-info"><strong>ステップ 1</strong></div>
        <div id="interactive-area">
            <!-- 動的コンテンツ -->
        </div>
    </div>

    <div class="history">
        <h3>これまでの絞り込み履歴</h3>
        <div id="log"></div>
    </div>

    <script>
        // 全16通りの組み合わせを作成
        const ALL_COMBINATIONS = [];
        for (let a of ['1', '2']) {
            for (let b of ['1', '2']) {
                for (let c of ['1', '2']) {
                    for (let d of ['1', '2']) {
                        ALL_COMBINATIONS.push(a + b + c + d);
                    }
                }
            }
        }

        let currentStep = 1;
        let possiblePool = [];       // 残っている候補のプール
        let chosenCodes = new Set();  // すでに選ばれた数字
        let currentProposal = "1111"; // 現在判定対象になっている数字

        // 不一致数を数える関数
        function countMismatches(str1, str2) {
            let mismatches = 0;
            for (let i = 0; i < 4; i++) {
                if (str1[i] !== str2[i]) {
                    mismatches++;
                }
            }
            return mismatches;
        }

        // ゲーム初期化
        function initGame() {
            currentStep = 1;
            possiblePool = [...ALL_COMBINATIONS];
            chosenCodes.clear();
            currentProposal = "1111";
            
            document.getElementById('log').innerHTML = "";
            renderMismatchPhase();
        }

        // 視覚的に前2桁と後ろ2桁を色分けしたHTMLを返す関数
        function getColoredDigitsHtml(code) {
            const front = code.substring(0, 2);
            const back = code.substring(2, 4);
            return `
                <div class="digit-container">
                    <div class="digit-part part-front" title="前2桁">${front}</div>
                    <div class="digit-part part-back" title="後ろ2桁">${back}</div>
                </div>
            `;
        }

        // 状態1: 間違いの個数を選択する画面
        function renderMismatchPhase() {
            document.getElementById('step-info').innerHTML = `<strong>ステップ ${currentStep} : 間違い個数の入力</strong> <span class="count-badge">残り候補: ${possiblePool.length}通り</span>`;
            const area = document.getElementById('interactive-area');

            // 現在の残りのプールから、発生し得る間違い個数を調査
            const validMismatches = new Set();
            possiblePool.forEach(code => {
                validMismatches.add(countMismatches(currentProposal, code));
            });

            let html = `<p>現在の対象数字:</p>`;
            html += getColoredDigitsHtml(currentProposal);
            html += `<p><strong>この数字に対する「全体の間違いの個数」ボタンを押してください:</strong></p>`;
            html += `<div class="btn-container">`;
            
            for (let i = 0; i <= 4; i++) {
                if (validMismatches.has(i)) {
                    if (i === 0) {
                        html += `<button class="correct-btn" onclick="submitMismatch(0)">0個 (正解!)</button>`;
                    } else {
                        html += `<button class="mismatch-btn" onclick="submitMismatch(${i})">${i}</button>`;
                    }
                }
            }
            html += `</div>`;
            
            area.innerHTML = html;
        }

        // 間違いの個数が選択されたときの処理
        function submitMismatch(selectedMismatch) {
            chosenCodes.add(currentProposal);

            // 履歴にログを追加(前後の見やすさを維持)
            const logEl = document.getElementById('log');
            const frontPart = currentProposal.substring(0,2);
            const backPart = currentProposal.substring(2,4);
            logEl.innerHTML += `
                <div class="history-row">
                    <strong>ステップ ${currentStep}:</strong> 
                    <span style="background:#e3f2fd; padding:2px 4px; border-radius:3px; color:#0d47a1;">${frontPart}</span><span style="background:#fff3e0; padding:2px 4px; border-radius:3px; color:#e65100;">${backPart}</span> 
                    ➔ 間違い: <strong>${selectedMismatch}</strong>
                </div>`;

            // 過去のすべての履歴(蓄積されたフィルター条件)に矛盾しないものだけを残す
            possiblePool = possiblePool.filter(code => {
                return !chosenCodes.has(code) && countMismatches(currentProposal, code) === selectedMismatch;
            });

            // 終了条件の判定(0個が選ばれた、または候補が1つになった)
            if (selectedMismatch === 0 || possiblePool.length === 1) {
                let finalAnswer = selectedMismatch === 0 ? currentProposal : possiblePool[0];
                endGame(finalAnswer);
                return;
            }

            // 状態2へ移行:次の数字をボタンで選択させる
            renderNextCodeSelectionPhase();
        }

        // 状態2: 絞り込まれた数字をボタンで選択させる画面
        function renderNextCodeSelectionPhase() {
            document.getElementById('step-info').innerHTML = `<strong>ステップ ${currentStep} : 次の数字を選択</strong> <span class="count-badge">残り候補: ${possiblePool.length}通り</span>`;
            const area = document.getElementById('interactive-area');

            let html = `<p>これまでの条件をすべて満たす、可能性のある数字一覧です。</p>`;
            html += `<p><strong>次に検証したい数字のボタンを押してください:</strong></p>`;
            html += `<div class="btn-container">`;
            possiblePool.forEach(code => {
                html += `<button class="code-btn" onclick="submitNextCode('${code}')">${code}</button>`;
            });
            html += `</div>`;
            
            area.innerHTML = html;
        }

        // ユーザーが数字ボタンを押したときの処理
        function submitNextCode(selectedCode) {
            currentProposal = selectedCode;
            currentStep++;
            renderMismatchPhase();
        }

        // ゲーム終了処理
        function endGame(finalAnswer) {
            document.getElementById('step-info').innerHTML = `<strong>完了!</strong>`;
            document.getElementById('interactive-area').innerHTML = `
                <p class="success">正解は <span style="font-size:28px; letter-spacing:2px; border-bottom:3px double #28a745; padding-bottom:2px;">${finalAnswer}</span> ですね!</p>
                <p class="success">良くかんばりました。</p>
                <p style="color: #666; font-size: 14px; margin-top:15px;">※ 5秒後に自動的に最初から再スタートします。</p>
            `;
            
            setTimeout(initGame, 5000);
        }

        // 起動時にゲームを開始
        window.onload = initGame;
    </script>
</body>
</html>

こちらにに作ったものをご用意いたしました。お試し頂けますので保存が面倒な方はどうぞ。

タイトルとURLをコピーしました