Sランクが取れない

 今日もアーマードコアのリプレイミッションを進めていたのだが、
BAWS第2工廠調査のミッションで苦戦している。Sランクが取れない。。。
前のデータでもここはなかなかSランクが取れなくて相当やり込んだものだが、
どうやらまぐれだったらしい。
チャプター2に行く前にSランクを取っておきたいものだ。

BAWS第二工廠調査
ARMORED CORE™ VI FIRES OF RUBICON™_20251113172304

気分転換にOutwardを

 アーマードコアが行き詰ったので、Outward をプレイして気分転換を行う。
私が好きなゲームの一つだ。いつかこういうゲームを自分の手で作りたい。
かなり人を選ぶゲームだが、私のように凝り性な人間にはかなりぶっ刺さると思う。
 DLCを含めれば6つのマップを旅しながら、
ジョブを3つ組み合わせて一人前の冒険者に育て上げるようなゲームだ。
おまけに魔法は単品では機能せず、スキルを組み合わせて初めて有効な効果を発揮する。
海外のゲームは軒並み近接ジョブが強いものだがこれも同様で、
魔法職はクエストで準備もなしに戦闘させられ苦戦を強いられることも多い。
やり込んだデータでも魔法職は準備もなしに戦えば簡単に死ねる。
それでも私は魔法と近接の汎用キャラばかり作って使っている。
まあ、当然ながら序盤は近接オンリーなので、属性武器でぶん殴るだけなのだが。。。

 メインのデータはPC版なので、PS5版のデータはやり込んでおらず序盤で止まっている。
再序盤のマップで既にゴールドリッチの剣と出血付与の盾、一番容量のある鞄、
耐性が優秀な製作防具の青い砂の鎧とブーツという序盤にあるまじき装備構成のため、
序盤の敵なら適当に戦っても勝てる。(それでも油断するとすぐ死ぬのが面白いところだ)

 次にプレイするときは次のマップである「エンメルカルの森」に行き金策をする。
最終盤でも1回の稼ぎでいえば最高効率の金策だろう。再序盤で出来るのもポイントが高い。

【C++】中央値の計算(ソートなし)

 先日、中央値を求めるコードを書いたのだが、
ソートせずに求めるアルゴリズムがあるようなので調査してみた。
どうやら、クイックソートで使用されている選択アルゴリズムによって求めることができるらしい。
Copilotが提示したコードはC言語だったのでC++風にアレンジして添付する。
一応vector型とarray型の2パターン作成した。
恐らくイテレータでわちゃわちゃすれば、より汎用的に作れるだろうが今日のところはやめておく。
中央値を求める関数だけ値渡しで元データに変更が加えられるのを防止し、
他は参照渡しで変更が引き継がれるようになっている。

#include <iostream>
#include <algorithm>
#include <vector>
#include <array>

// 選択アルゴリズムはクイックソートの分割処理部分

// パーティション分割(Lomuto方式)
template<typename T>
size_t partition(std::vector<T>& vec, size_t left, size_t right)
{
    T pivot = vec[right];
    size_t i = left;
    for (size_t j = left; j < right; ++j)
    {
        if (vec[j] < pivot)
        {
            std::swap(vec[i], vec[j]);
            ++i;
        }
    }
    std::swap(vec[i], vec[right]);
    return i;
}

// パーティション分割(Lomuto方式)
template<typename T, size_t N>
size_t partition(std::array<T, N>& arr, size_t left, size_t right)
{
    T pivot = arr[right];
    size_t i = left;
    for (size_t j = left; j < right; ++j)
    {
        if (arr[j] < pivot)
        {
            std::swap(arr[i], arr[j]);
            ++i;
        }
    }
    std::swap(arr[i], arr[right]);
    return i;
}

// Quickselect で k 番目の要素を取得
template<typename T>
T quickSelect(std::vector<T>& vec, size_t left, size_t right, size_t k)
{
    if (left == right) return vec[left];

    size_t pivotIndex = partition(vec, left, right);

    if (k == pivotIndex)     return vec[k];
    else if (k < pivotIndex) return quickSelect(vec, left, pivotIndex - 1, k);
    return quickSelect(vec, pivotIndex + 1, right, k);
}

// Quickselect で k 番目の要素を取得
template<typename T, size_t N>
T quickSelect(std::array<T, N>& arr, size_t left, size_t right, size_t k)
{
    if (left == right) return arr[left];

    size_t pivotIndex = partition(arr, left, right);

    if (k == pivotIndex)     return arr[k];
    else if (k < pivotIndex) return quickSelect(arr, left, pivotIndex - 1, k);
    return quickSelect(arr, pivotIndex + 1, right, k);
}

// 中央値を求める関数(ソートなし)
template<typename T>
double median(std::vector<T> vec)
{
    size_t n = vec.size();

    // 奇数個 → 中央の1要素
    if (n % 2) return quickSelect(vec, 0, n - 1, n * 0.5);
    
    // 偶数個 → 中央の2要素の平均
    T leftMid = quickSelect(vec, 0, n - 1, n * 0.5 - 1);
    T rightMid = quickSelect(vec, 0, n - 1, n * 0.5);
    return (leftMid + rightMid) * 0.5;
}

// 中央値を求める関数(ソートなし)
template<typename T, size_t N>
double median(std::array<T, N> arr)
{
    // 奇数個 → 中央の1要素
    if (N % 2) return quickSelect(arr, 0, N - 1, N * 0.5);
    
    // 偶数個 → 中央の2要素の平均
    T leftMid = quickSelect(arr, 0, N - 1, N * 0.5 - 1);
    T rightMid = quickSelect(arr, 0, N - 1, N * 0.5);
    return (leftMid + rightMid) * 0.5;
}

using namespace std;

int main()
{
    // 整数の偶数で中央値を求める
    vector<int> vec1 = { 3, 6, 12, 2, 15, 9, 8, 1 };
    array<int, 8> arr1 = { 3, 6, 12, 2, 15, 9, 8, 1 };

    cout << "中央値(vector): " << median(vec1) << endl;
    cout << "中央値(array) : " << median(arr1) << endl;

    // 浮動小数の偶数で中央値を求める
    vector<double> vec2 = { 3.5, 6.7, 12.12, 2.6, 15.0, 9.1, 8.7, 1.9 };
    array<double, 8> arr2 = { 3.5, 6.7, 12.12, 2.6, 15.0, 9.1, 8.7, 1.9 };

    cout << "中央値(vector): " << median(vec2) << endl;
    cout << "中央値(array) : " << median(arr2) << endl;

    // 整数の奇数で中央値を求める
    vector<int> vec3 = { 3, 6, 12, 2, 15, 9, 8 };
    array<int, 7> arr3 = { 3, 6, 12, 2, 15, 9, 8 };

    cout << "中央値(vector): " << median(vec3) << endl;
    cout << "中央値(array) : " << median(arr3) << endl;

    // 浮動小数の奇数で中央値を求める
    vector<double> vec4 = { 3.5, 6.7, 12.12, 2.6, 15.0, 9.1, 8.7 };
    array<double, 7> arr4 = { 3.5, 6.7, 12.12, 2.6, 15.0, 9.1, 8.7 };

    cout << "中央値(vector): " << median(vec4) << endl;
    cout << "中央値(array) : " << median(arr4) << endl;

    return 0;
}
実行結果

By ta-boss

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です