以下の内容はhttps://yamaimo.hatenablog.jp/entry/2025/08/30/220000より取得しました。


ルドー分析の裏側の話。(その3)

少し空いてしまったけど、前回の続き。

進み具合の分析

最後に実施したのが進み具体の分析。

次のようなコードで、スゴロクとしての進み具合がどうだったのかを分析した:

# 進み方の表を作る
def make_progress_tables(
    log_table: pd.DataFrame
) -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
    acc_pos = {player: [0] for player in Player}
    acc_move = {player: [0] for player in Player}
    acc_back = {player: [0] for player in Player}

    for i in log_table.index:
        turn_player = log_table.loc[i, "player"]
        back_player = log_table.loc[i, "back_player"]
        for player in Player:
            if player == turn_player:
                move_count = log_table.loc[i, "move_count"]
                next_pos = acc_pos[player][-1] + move_count
                next_move = acc_move[player][-1] + move_count
                new_back = acc_back[player][-1]
            elif player == back_player:
                back_count = log_table.loc[i, "back_count"]
                next_pos = acc_pos[player][-1] - back_count
                next_move = acc_move[player][-1]
                new_back = acc_back[player][-1] - back_count
            else:
                next_pos = acc_pos[player][-1]
                next_move = acc_move[player][-1]
                new_back = acc_back[player][-1]
            acc_pos[player].append(next_pos)
            acc_move[player].append(next_move)
            acc_back[player].append(new_back)

    return pd.DataFrame(acc_pos), pd.DataFrame(acc_move), pd.DataFrame(acc_back)

# 計算を実行
acc_pos, acc_move, acc_back = make_progress_tables(log_table)

ここではターンごとに、各プレイヤーについて「各駒のスタートからの距離の合計」「進んだ距離の累積」「戻った距離の累積」を求め、表を作っている。

そして、まずは「各駒のスタートからの距離の合計」について可視化:

# プレイヤー名、色
player_name_color = {
    Player.Y: ("ちは", "green"),
    Player.B: ("わためぇ", "orange"),
    Player.R: ("ばんちょー", "purple"),
    Player.G: ("ししろん", "black"),
}

# 進み具合の様子
fig, ax = plt.subplots(figsize=(12, 5))
ax.set_title("進み具合")
for player in Player:
    name, color = player_name_color[player]
    ax.plot(acc_pos[player], label=name, color=color)
ax.set_xlim(0, len(acc_pos))
ax.set_yticks([0, 44, 87, 129, 170])
ax.grid(True)
ax.legend();

こうして得られたのが次のグラフ:

進み具合

ちなみにy軸は44, 87, 129, 170とちょっと変なところに線を引いてるけど、一周してきてゴール手前のコマまで進むと40進んだことになってて、ゴールの一番奥まで1つコマを進めたときに44、次のコマを奥まで進めたときに87(44+43)、同様にして129(44+43+42)、そして全部ゴールさせたときに170(44+43+42+41)となるので、何個くらいコマがゴールしているかの目安になっている。

このグラフにすると、順位がどんな感じだったのかが一目で分かるのがいい。 普通に盤面を見るのだと、誰が一番なのかはちょっと分からないからねぇ。 実際の分析は元の記事を参照。

そして、この図だと結果としての進み具合は分かるけど、その内訳(前進と後退がどれくらいか)は分からないので、それを分けて可視化したのが次:

# 進んだ数と戻った数の様子
fig, ax = plt.subplots(figsize=(12, 8))
ax.set_title("前進と後退の累積")
for player in Player:
    name, color = player_name_color[player]
    ax.plot(acc_move[player], label=f"{name} (前進)", color=color)
    ax.plot(acc_back[player], label=f"{name} (後退)", color=color, linestyle="dashed")
ax.set_xlim(0, len(acc_pos))
ax.grid(True)
ax.legend();

前進と後退の累積

分析の内容は元の記事を参照してもらうとして、前進側でそれほど差が出てないというのは個人的には意外だった。 元の記事でも言及したとおり、冷静に考えてみれば納得できる結果なんだけど。 このことに気づけたのは、この可視化のおかげと言える。

で、勝敗の差を生んだのが、後退をどれだけしなかったのかということ。 それもこの可視化で明確になっている。

より進んだ考察

で、元の記事では「ちはバリア」と面白おかしく締めてしまったけど、さらに分析するなら、場に出ていたコマの数とかを分析してみてもよかったかもしれない。

場に出ているコマの数が多ければ多いほど、基本的には踏まれるリスクは高いはず。 その一方で、コマが1つしか出てないと選択の自由度がなく、他の人の前に出ないように別のコマを動かすことができないので、これもまた踏まれるリスクが増える可能性がありそう。

そのあたりを踏まえて、実際に場に出ていたコマの数がどうだったのか、そしてその状態がどれくらい長く続いていたのかとかを見ると、また何か発見があるかもしれない。

で、6が出たときには基本的にはスタートから出してたけど、コマがすでに2つ出てたり、あるいは1つであっても他の人の前に出る可能性が少なかったりするなら、あえてスタートから出さずに今出てるコマをまずはゴールに向かわせて安全にする方がよかったりするのかもしれない。 そういった戦術的なところもそのうち分析してみたいかな。

長く続いたけど、ルドー分析はこれで一旦オシマイ。

今日はここまで!




以上の内容はhttps://yamaimo.hatenablog.jp/entry/2025/08/30/220000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14