おすすめ記事

R言語で迷路生成!棒倒し法のコードを初心者向けに解説!

シェアする

R言語を使って生成させた迷路
この記事の所要時間: 353
更新履歴
2017/04/03 コード解説追加(途中まで)
2017/03/17 タイトル変更。コード解説(途中まで)作成中。
2017/03/15 初版公開

みなさんこんにちは。

今日、R言語(Wikipedia)を使ってみようと思い立ちました。サンプルとして、迷路を作ってみましたのでコードを公開します。

スポンサーリンク

R言語って何だろう

詳しい説明はWikipediaの説明を見て頂くとして、

私なりに解説すると、

データを用意して、解析・処理し、それを表示するのに適した言語

だと感じました。

データを用意する際に、既にあるデータを読み込んで使うことも、強力なデータ生成機能を使ってそれを使うこともできます。

解析において、通常の言語(C/C#/Java/etc)と比べて、中間的な値を記憶させる変数を用いる機会が少なりそうだと感じています。

採用した迷路を生成アルゴリズム

迷路を生成するには代表的な4つのアルゴリズムがあります。

今回は一番簡単な「棒倒し法」を採用しました。

※ 棒倒し法は今後解説予定です。

ソースコード

今回作成したソースコードを以下に示します。


#迷路の大きさは横幅(w)・縦幅(h)が11
w <- h <- 11

# 道(road)と壁(wall)を定義
road <- 0
wall <- 1

# 迷路の基礎を作成(全てを道にして外壁を作る)
matrix(road,h,w)->maze;
wall -> maze[1,] -> maze[,1] -> maze[h,] -> maze[,w];

# 棒倒し処理 ------------------------------------------------------
# 引数:y=迷路のY座標
direction <- function(y) {
  # 1~4の乱数を生成
  # ※迷路のY座標が3なら4方向(上の方向含む)、それ以外は3方向(上禁止)
  r <- floor(runif(1, 1, ifelse(y == 3, 5, 4)));

  # 乱数で得た1~4の値を、Y座標とX座標の増分(方向)へ変換
  dy <- switch(r,"1"=1,"2"=0,"3"=0,"4"=-1);
  dx <- (r %% 3) - 1;

  # Y座標とX座標の増分(方向)を返却
  return(list(x = dx, y = dy));
}

# 迷路生成処理 ----------------------------------------------------
# X座標繰り返し(2つ飛ばし)
for(x in seq(3, w - 2, 2)) {
  # Y座標繰り返し(2つ飛ばし)
  for(y in seq(3, h - 2, 2)) {
    # 壁を作る
    maze[y, x] <- wall;
    # 壁の無い方向を探しだす
    d <- direction(y);
    while(maze[y + d$y, x + d$x] == wall) d <- direction(y);
    # その方向へ壁を作る
    maze[y + d$y, x + d$x] <- wall;
  }
}

# 迷路をプロット ----------------------------------------------------
s <- 1; # size
plot(1:ifelse(w>h,w,h) * s);
for(x in 1:w) {
  for(y in 1:h) {
    rect(x * s - s / 2, y * s - s / 2,
         x * s + s / 2, y * s + s / 2,
         col = ifelse(maze[y, x] == wall, "red", "black"));
  }
}

コード解説

サンプルコードの概要

まず、今回のサンプルの概要を解説します。

R言語は行末に「;」(セミコロン)を付ける必要はありませんが、私はメインとしてC#を利用しているため付けています。

また、R言語では、

変数 <- 値(処理結果)

または

値(処理結果) -> 変数

で代入を表します。

どちらの記述でも、別段違いはありません。

迷路の実体(以降、迷路空間として解説します)は「maze(迷路)」という変数です。行列(matrix)で定義されています。

また、迷路空間は、格子状に(≒縦横に)区切られたマスで作られています。
このマスの内容は、「wall(壁)」と、「road(道)」で定義されます。

迷路の大きさは「w(width、横幅)」と「h(height、縦幅)」であらわされています。

プログラムの根幹は「迷路生成処理」と書かれた処理です。

サンプルコードの詳細解説

それでは、より詳細にプログラムの内容を解説していきます。

定数定義

以下の記述で迷路空間の大きさを定義しています。
※本来は定数の意味合いで定義していますが、このサンプルでは変数を定数的に使用しています。

#迷路の大きさは横幅(w)・縦幅(h)が11
w <- h <- 11

また、以下の記述で道(road)、と壁(wall)の実態を定義しています。

# 道(road)と壁(wall)を定義
road <- 0
wall <- 1

迷路初期化処理

以下の記述で迷路空間を作っています。この時の迷路空間は、全て道だけとなっています。

matrix(road,h,w)->maze;
最初に、迷路空間「maze」を作る。この時、全て道だけの状態で作られる。
最初に、迷路空間「maze」を作る。この時、全て道だけの状態で作られる。

最初に、迷路空間「maze」を作る。この時、全て道だけの状態で作られる。

続けて、以下の記述で最外壁(外側の壁)を作っています。

wall -> maze[1,] -> maze[,1] -> maze[h,] -> maze[,w];
続けて、迷路空間の最外壁(外側の壁)を作ります。
続けて、迷路空間の最外壁(外側の壁)を作ります。

続けて、迷路空間の最外壁(外側の壁)を作ります。

迷路空間に壁を作るのは、迷路空間「maze」の特定の座標に、壁を代入することで実現しています。

例えば、

wall -> maze[6,6]

という処理を記述すると、

真ん中に壁が作られるといった具合です。

これは、例えば「Y座標6・X座標6」の位置(この例では真ん中)に壁を作る場合の解説です。(クリックで拡大)
これは、例えば「Y座標6・X座標6」の位置(この例では真ん中)に壁を作る場合の解説です。(クリックで拡大)

これは、例えば「Y座標6・X座標6」の位置(この例では真ん中)に壁を作る場合の解説です。(クリックで拡大)

迷路を実際に作り出す

実際に迷路を生み出すからくりは、コードの中で「棒倒し処理」と書かれている部分と、「迷路生成処理」と書かれている部分です。

中心的な処理(≒実際に迷路生成を行っている処理)は、「迷路生成処理」です。迷路生成処理から棒倒し処理を何度も何度も呼び出すことで、迷路を作っています。

迷路を作り出しているソースコード。「迷路生成処理」から「棒倒し処理(関数:direction)」を何度も呼び出すことで迷路が作られる。(クリックして拡大)
迷路を作り出しているソースコード。「迷路生成処理」から「棒倒し処理(関数:direction)」を何度も呼び出すことで迷路が作られる。(クリックして拡大)

迷路を作り出しているソースコード。「迷路生成処理」から「棒倒し処理(関数:direction)」を何度も呼び出すことで迷路が作られる。(クリックして拡大)

(解説途中)

実行結果例

実行結果の例を以下に示します。

R言語で迷路を生成させた例。クリックで拡大。
R言語で迷路を生成させた例。クリックで拡大。

R言語で迷路を生成させた例。クリックで拡大。

考察

このサンプル自体は、正直R言語でやる必要はありません。

R言語の良さを何一つ使っていないサンプルだからです。

ただし、

通常の手続き型言語と同じような着想でプログラムを書くことができる

と実感することができました。

また、

R言語はデータ(リスト・行列等)を強力に生成させ、それをグラフへプロットする機能が充実しています。

今回は単に矩形を描画させて描きましたが、

迷路生成をツリー構造を用いて作成したり、描画をポリラインで描いたり、

色々な応用ができるかもしれません。

最後に

大量のデータを解析し、それを分かりやすくプロット(表示)できる言語であるR言語はとても魅力的です。現在盛んに取りざたされている「ビッグデータ」の解析や、人工知能開発の躍進に恩恵をもたらしてくれそうだと感じています。

また、今回の内容は「Escape from the Grand Maze ― 巨大迷路からの脱出」に関係したものです。今後、この物語を進めるにつれて、どのように関係しているのか語られていくでしょう。

次回の更新をお待ちいただければ幸いです。

Escape from the Grand Maze - 巨大迷路からの脱出
更新履歴 2017/04/19 START編公開。 2017/03/18 PROLOGUEの漫画版公開 2017/03/14 公開開始。PROLOGUE公開。 これは当サイトの管理者である「ガノー」が書いている、 オリジナルのウェブ小説(/漫画)です。ジャンルは異世界転送系の、ローファンタジーです。実験的に、ライトノベルを、「ウェブのリッチな表現を用いて書き、それを公開するものです。また随時、漫画画像(ネームレベル≒棒人間レベル)を作成し掲載してい...
PROLOGUE ― Escape from the Grand Maze
これは「Escape from the Grand Maze - 巨大迷路からの脱出」のコンテンツ(小説)です。

Copy Protected by Chetan's WP-Copyprotect. >