少し空いてしまったけど、前回の続き。
進み具合の分析
最後に実施したのが進み具体の分析。
次のようなコードで、スゴロクとしての進み具合がどうだったのかを分析した:
# 進み方の表を作る 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つであっても他の人の前に出る可能性が少なかったりするなら、あえてスタートから出さずに今出てるコマをまずはゴールに向かわせて安全にする方がよかったりするのかもしれない。 そういった戦術的なところもそのうち分析してみたいかな。
長く続いたけど、ルドー分析はこれで一旦オシマイ。
今日はここまで!