C基礎9 ローグライクゲーム(再帰呼出し)
C基礎9 ローグライクゲーム(再帰呼出し)
本章では「ローグライクゲーム」を作ります。迷路を、2次元配列を使って作成します。プレイヤーは迷路の中にあるアイテムを取得しながらゴールを目指します。プレイヤーを動かすためのキー入力は、前の章で勉強したコンソール入力を使います。
ゲームを作るにあたり、オープニング画面では、ゲームタイトルをスクロールで表示します。エスケープシーケンスの中に、スクロール表示するのに便利なものがあるので、それを使います。
ローグライクゲームの迷路は、最初は配列の初期化で作成しますが、再帰呼出しと呼ばれるプログラミングテクニック使ったランダムな迷路の自動生成を行うようにプログラムを書き換えていきます。
動画は、Windows10とVisualStudio2019を使った説明になっていますが、WIndows11とVisualStudio2022を使った場合の操作方法と同じです。
ゲームタイトルをスクロール表示するにあたり、スクロールをどの様に実現するのかを説明します。スクロールを実現する方法は色々ありますが、ここではエスケープシーケンスを使ったプログラムを紹介します。
上下スクロールは、上下スクロール用のエスケープシーケンスがあり、スクロールする範囲を設定することも出来ます。
左右スクロールは、スクロール用のエスケープシーケンスはなく、文字削除と文字挿入のエスケープシーケンスを使って左右スクロールを実現します。また、スクロールする文字の表示は、文字列中の文字を1文字ずつ表示することになります。まだ詳しく説明していないポインタを使う記述になっていますので、今回も「この様に書く」と、そのまま真似てください。
スクロールのプログラムの動きを、上下スクロール、左右スクロールで説明しています。
サンプルプログラムは、エスケープシーケンスを使ったものになっています。
・上下スクロールはエスケープシーケンスがある
指定した行数のスクロールアップとスクロールダウンをさせる事ができます。
・左右スクロールはエスケープシーケンスがない
文字挿入と文字削除のエスケープシーケンスを使って左右スクロールを実現します。
・上下スクロールの範囲を指定できる
上下スクロールは、スクロールさせる範囲を設定できます。
・上下スクロールは一重ループ
スクロールアップは、スクロールする範囲の最下行に、新たに表示させる文字列を表示する処理を繰返すことで実現します。目に見える動きにするため、少し待たせるSleep関数を使います。
・左右スクロールは二重ループ
スクロールレフトは、1つスクロールする毎に、スクロールする範囲分だけ文字削除しなければならないので、スクロール処理は二重ループになります。また、文字列配列中の全角文字を1つ表示させるため「&文字列配列名[i][j]」という特殊な文字列指定を行い、「%.2s」という書式指定をします。
これからローグライクゲームを作っていきますが、ここでは、そのゲームのオープニング画面を表示するプログラムを作成します。
ゲームタイトルを、アスキーアートの文字列配列で初期化し、スクロールアップ表示するプログラムを作成しましょう。
また、ゲームを説明する説明文も文字列配列で初期化し、説明文については、スクロールせずに固定表示させてみましょう。このためには、ゲームタイトルを表示する部分だけをスクロール範囲設定します。これにより、スクロール表示させる部分と、固定表示させる部分を分けて表示することができます。
以前作ったエスケープシーケンスのマクロと関数、それとオープニング画面で表示するアスキーアートとゲーム説明の文字列配列は用意してあります。右下の動画をYouTubeを使って見てください。YouTubeの動画説明の中にURLを記載していますので、そこからダウンロードして使ってください。
練習問題42は、ゲームタイトルをスクロールアップ表示させましたが、今回はスクロールレフト表示するようにしてみましょう。
ローグライクゲームを少しずつ作っていきます。今回は迷路を二次元配列を使って、初期化で作成し、それを表示します。前の練習問題で作成したオープニング画面は、ローグライクゲームが完成した後に組み込みます。
迷路の二次元配列などが入ったファイルが用意してあります。右下の動画をYouTubeを使って見てください。YouTubeの動画説明の中にURLを記載していますので、そこからダウンロードして使ってください。
前回の練習問題で作成したマップの中を、プレイヤーが移動するようにします。
アイテムと重なった場合、プレイヤーを表示し、次の位置にプレイヤーが移動した時に、元のアイテムを再表示するようにします。
迷路の中にあるアイテムが、何を意味するのかが分かりません。このため、プレイヤーがアイテムの上にのった時、そのアイテムの意味を説明するメッセージを表示(ヒント表示)するようにします。
但し、このヒント表示は、ヒントキーを押したヒントモードの時だけ行われるもので、ヒントキーを再打鍵するとヒントモードは解除され、ヒント表示しないようにします。
プレイヤーがアイテムの上にのった状態でスペースキーが押されたならば、各アイテムに応じた処理を行います。また、プレイヤーは移動する度に体力が減り、体力が0になった時点でゲームオーバーにします。
修正量が多いため、以下の5つのステップに分けて修正していきます。
ステップ1:プレイヤーが歩くと体力が減り、体力が0になるとゲームオーバー
ステップ2:盾と剣と食料を取得、食料を取得した場合は体力がアップ
ステップ3:盾と剣を取得した場合は取得アイテムとして画面に表示
ステップ4:敵とバトル
ステップ5:敵ボスとバトル、敵ボスが倒れていたらゴール位置でゲームクリア
ステップ2:盾と剣と食料を取得、食料を取得した場合は体力がアップ
ステップ3:盾と剣を取得した場合は取得アイテムとして画面に表示
ステップ4:敵とバトル
ステップ5:敵ボスとバトル、敵ボスが倒れていたらゴール位置でゲームクリア
再帰関数は、自分自身を呼び出す関数です。
for文で書いていたプログラムは、再帰関数にするとfor文が無くなります。プログラムの動きが複雑になるため、無理に再帰関数にする必要はありません。再帰呼出しは、迷路の自動生成プログラムでよく使われるテクニックになります。
1から指定した数までの合計を求める関数を再帰関数にして、再帰関数が、どの様に動くのかを説明しています。再帰関数の練習問題として、よく使われるユークリッドの互除法のサンプルプログラムも紹介しています。
・再帰関数は自分自身を呼び出す関数
自分自身を呼び出す関数呼出しのことを、再帰呼び出し(リカーシブコール:recursive call)と言います。デバッグが難しいので、プログラミングに慣れてから使う様にしましょう。
練習問題47では二次元配列の初期化で迷路のマップとアイテム情報を定義していましたが、これを、配列の初期化ではなく、乱数を使って自動生成します。
また、繰返しゲームが出来る様に、ゲームクリア、ゲームオーバーになった後、ゲーム再開するかを問い合わせ、ゲーム再開時には、新なた迷路マップを表示するようにします。
修正量が多いため、以下の4つのステップに分けて修正していきます。
ステップ1:ゲームを再開できる様にする
ステップ2:部屋の自動生成
ステップ3:通路の自動生成
ステップ4:アイテムの自動生成
ステップ2:部屋の自動生成
ステップ2を使った再帰呼出し解説
ステップ3:通路の自動生成
ステップ4:アイテムの自動生成
練習問題48の修正で、迷路を自動生成するようにしたので、大きなマップも簡単に作れるようになります。ただし、現状のプログラムだと、画面の大きさより大きなマップを作れません。
今回は、マップ表示の方法を変え、表示するのは、大きなマップの一部で、プレイヤーがなるべく中央に表示されるように調整します。
練習問題49で迷路の一部を表示する様にしたため、何処にどういうアイテムがあるのか探し回らないといけなくなりました。迷路を自動生成した後、マップ全体をスクロール表示してからゲームを開始するようにします。また、練習問題42または43で作成したゲームタイトルスクロールのプログラムを取り入れ、ローグライクゲームを完成させます。
テスト実施フォーム ← テストチャレンジできます
上記テストの解説と解答