C基礎3 テキストアドベンチャーゲーム1
C基礎3 テキストアドベンチャーゲーム1
この章の最後に、「テキストアドベンチャー」と呼ばれるプログラムを作成します。ゲームを作る前に、コンピュータの基本操作や今まで学んできたことを、文法に照らし合わせて復習していきます。また、ゲームの中でプレイヤーの名前を入力する場面を作ります。この名前を入力するプログラムを作る時に必要な知識である、文字と文字列について勉強します。
「3.1 プログラムの実行方法」は、パソコンの操作法も含まれているため、Windows10(Visual Studio 2019)の動画と、windows11(Visual Studio 2022)の動画を用意しています。その他のプログラミングの説明動画は、Windows10とVisualStudio2019を使った説明になっていますが、WIndows11とVisualStudio2022を使った場合の操作方法と同じです。
Visual Studioがなくてもプログラムは実行することが出来ます。代表的なプログラムの実行方法は、以下の2つです。
エクスプローラー実行
コマンド実行
どの様なプログラム実行をしても、同じ結果にするためには、プログラム作成時に気を付けなければならないことが2点あります。
プログラム終了前にEnterキーの入力待ちを作る
プログラムの最初に画面クリアする
2つのプログラム実行の方法を説明しますが、Windows10とWIndows11では、若干操作方法が異なりますので、動画を2種類用意しています。
・「エクスプローラー実行」と「コマンド実行」がある
実行ファイルをエクスプローラーで表示し、ダブルクリックで実行させる方法と、コマンドプロンプトを起動してから、実行ファイル名をコマンドとして実行させる方法があります。どちらの方法でも同じ結果になるようにプログラムを書くポイントが2点あります。
・Enterキーの入力待ちを作る
「エクスプローラー実行」した場合、「return 0;」すると、直ぐに画面が消えてしまいます。「return 0;」する前に、Enterキー入力待ちの状態にしましょう。
・画面クリアしてから表示する
「コマンド実行」した場合、コマンド実行した次の行からプログラム実行した結果が表示されるため、プログラムの実行結果が何行目から表示されるかは、実行する毎に変わってしまいます。プログラムの最初に画面クリアすると、必ず1行目から表示される様になります。
整数はint型、小数点の付いた数はdoubel型と説明してきましたが、C言語の文法としては、int型やdoube型以外のデータ型が用意されています。ただ、データ型の種類としては整数型と浮動小数点型の2種類があるだけです。
整数型の場合は、データ型のサイズの違いや符号の有無によってデータ型が異なります。データ型のサイズは符号の有無により、扱えるデータの範囲が違ってきます。
浮動小数点型の場合は、精度の違いによってデータ型が異なります。
データ型の違いが、コンピュータの中で、どの様な違いになっているかを説明しています。コンピュータの中の様子を表わすのには16進数が使われますが、16進数がどういうものかについても説明しています。
全てのデータ型を覚える必要はありませんが、データ型には色々なものがあり「データ型を意識してプログラム書かなければならない」という事は覚えておいてください。
・データにはデータ型がある
プログラムで扱うデータにはデータ型があります。プログラムにデータそのものを記述した場合、それは文法的には「定数」と呼ばれるもので、定数はデータ型を持つことになります。データを入れる箱である「変数」も、変数宣言した時のデータ型を持ちます。
・データ型は整数型と浮動小数点型の2種類がある
int型のように整数を扱うデータ型とdouble型のように小数点付きのデータを扱うデータ型があり、数を覚える必要はありませんが、沢山のデータ型があります。
重要なのは、全てのデータ型は、固定2進数表現形式の整数型と浮動小数点表現形式の浮動小数点型の2種類に分けられる、という事です。
・整数型は符号有り型と符号無し型の2種類がある
整数型の基本はint型ですが、データ型のサイズを意識しなければならない場合は、short, long, long long型を使います。負の値を扱いたくない場合は、unsigned というキーワードを付けると符号無し型になります。
・符号無し型は扱える値の最大値を倍にできる
整数型の基本はint型で、Visual Studioの場合、約21億位までのデータを扱うことができます。21億を超えるようなデータを扱う場合は、unsigned int型にすることで、倍の42億迄のデータを扱えます。それを超える場合は、long long型にします。
・浮動小数点型のデータ型の違いは精度の違い
浮動小数点型には、float型、double型、long double型があります。これらの型の違いは、精度の違いです。
・実数にdouble型を使うとデータ型が揃いやすい
実数(小数点付きのデータ9を扱いたい場合double型を使います。これは、小数点の付いた定数(浮動小数点定数)のデータ型がdouble型のためで、データ型が揃いやすくなります。
・書式指定子はデータ型に合わせる
printf関数やsacnf関数で使う書式指定子は、扱うデータのデータ型に合わせて使います。int型やdouble型以外のデータ型を扱う場合は、扱うデータ型に合わせた書式指定子を使わなければなりません。
整数型のデータ型(int型、char型)には%d, %u, %xという書式指定子を、浮動小数点型のデータ型(float型、double型)には%lf, %le, %lgという書式指定子を使ってデータをprintf表示するプログラムを作成しましょう。データは、int型データ、char型データ、float型データ、double型データを、それぞれscanf入力するようにします。
今回の練習問題はプログラミング問題というより、様々なデータを入力して、その表示結果の違いを考えるという問題です。
今まで勉強してきたプログラムの書き方の復習になります。文法的な意味を付け加えながら、少し掘り下げた説明をします。
プログラムは「文」という単位で実行されていきます。今まで勉強してきた文を、文法的に少し詳しく説明します。この中で、特に注意して欲しい文法に「式」があります。return文、if文、switch文の構成要素の1つになっていて、式が分かると、プログラミングスキルを一歩前進させることができます。
変数宣言文
変数宣言文では、変数を初期化して宣言するという書き方があります。
式文
「式」は、変数、定数、演算式、関数呼出しで、今までprint文とかscanf文と呼んでいましたが、文法的には「関数呼出し式」の「式文」という扱いになります。演算式は、「式」と「演算子」から構成されていて、式と式を組み合わせて、式とすることができます。このため、非常に長い式を書く事ができます。演算子で結ばれた式は、演算子の優先順位と結合規則に従って、結ばれていきます。
return文
return文の文法は「return 式;」です。関数の所で詳しい説明をします。
if文, else文
if文の文法は「if(式) 文」です。条件と呼んでいた部分は「式」の形をとっていれば文法的には正しい書き方になります。
switch文
switch文の文法は「switch(整数式) 文」です。ただ、switch文は多分岐構造に使った方がよいので、caseラベル、defaultラベル、break文を組み合わせた書き方にします。
break文
今は、switch文の中で使っていますが、この後、繰返し処理でも使うようになります。
ここでは、新しい演算子として複合代入演算子を紹介しています。
プログラミングというより、文法的な説明になります。
特に、「演算子の優先順位と結合規則」の所では、頭の体操問題を用意、式と演算子がどの様につながれていくのかを学びます。
・変数宣言する時に初期化できる
変数宣言文で変数を用意しますが、この時、初期化式を書くと、変数を用意するのと同時に、初期化式で指定したデータがセットされます。
・式にセミコロンと付けると「式文」になる
文の基本は「式文」です。
・式はプログラムの基本単位になる
式には、定数、変数、式を演算子で結んだ演算子式、関数呼出し式があります。演算式に演算子をつなげることができるので、式は、どんどん長くすることができます。
・演算子は優先順位と結合規則に従ってつながる
式が複数の演算子でつながれていく時、演算子の優先順位と結合規則に従ってつながっていきます。
・複合代入演算子は代入と加減乗除+剰余算の組合わせ
複合代入演算子は便利な演算子です。使える時は、積極的に使う様にしましょう。
・関数呼出しの( )の中は、式の並び
関数呼出しの( )の中は「実引数並び」と呼ばれる文法で、「式」をカンマで区切って書きます。
・return の後は式を書く
「return 0;」と書いていましたが、文法的には「return 式;」です。0は整数定数で式なので文法的に正しいことになります。
・if文の条件は式を書く
今まで「条件」を書くと言っていた所は、文法的には「式」の形をとっていれば問題ありません。式の計算結果が0以外の場合が真で、0の場合が偽という判定になります。
・swith文の( )の中は、整数式を書く
switchの横の( )の中には、整数式を書きます。整数式というのは、「式」の形をとっていて、そのデータ型が整数型でなければならない、という文法です。
プログラムで、文字を扱うことも出来ます。C言語で扱える文字は半角文字です。全角文字は、「3.5 文字列とchar型配列」で説明する文字列で扱うことになります。C言語では、文字と文字列は違うものです。
文字は、コンピュータの中では文字番号という整数で扱われます。文字は1バイトの大きさを持つデータなので、データ型としてはchar型を使います。この文字番号は、世界共通の番号であるASCIIコード(ASCIIコード)が使われています。
文字は、printf関数やscanf関数を使って、画面に表示したり、キーボードから入力することが出来ます。この時指定する書式指定子は%cです。
整数に整数定数、実数に浮動小数点定数がある様に、文字にも定数があります。文字には文字定数があります。
文字の実体は文字番号で整数ですので、加減乗除など、整数が使える計算を行うことが出来ます。
「文字」について学びます。
文字の実体は、ASCIIコードと呼ばれる整数です。C言語はコンピュータのハードウェアに近い言語なので、文字と文字列の扱い方が違っています。コンピュータの中に記録されている文字がどの様なものかを説明しています。
折角、コンピュータに近いC言語を勉強しているので、コンピュータの中の動きを想像できる様になりましょう。
・コンピュータの中の文字は文字番号でchar型を使う
文字はASCIIコードと呼ばれる番号です。ASCIIコードは1バイトの整数データなので、char型を使います。
全角文字は1バイトよりも大きな整数データです。このためchar型で扱うことは出来ません。
・文字の書式指定子は%cを使う
文字を、キーボードから入力したり、画面に表示するための書式指定子は%cを使います。
文字の実体は整数ですので、int型の整数を%cを指定することで、その整数の値に対応したASCIIコードの文字を表示することができます。
・文字(半角文字)の文字番号はASCIIコード
ASCIIコードには、目に見える英数字や記号の他、改行文字やタブ文字といった、目に見えない制御文字と呼ばれる文字の番号も割り振られています。
・文字定数はシングルクォーテーションを使う
文字には、文字定数があります。
・文字は文字番号(整数)なので計算ができる
文字の足し算や引き算をすると、英字の場合は、ASCIIコードはアルファベット順に並んでいるので、指定した数だけ前後した文字になります。
文字を「%c」という書式指定子を使って入力するプログラムを作成しましょう。
入力した文字に対して、以下の表示を行いましょう。
入力した文字の文字番号(ASCIIコード)を10進数と16進数で表示する
入力した文字の種類(数字、英小文字、英大文字、それ以外)を表示する
英小文字の場合は、入力した文字に対する英大文字も表示する
英大文字の場合は、入力した文字に対する英小文字も表示する
文字は半角1文字しか扱うことができません。しかし、プログラムでは、複数の文字の並んだメッセージを扱うことの方が多いです。複数の文字の並んだメッセージは、文法的には「文字列」と呼んでいて、char型配列で扱います。「配列」については「6 配列」で詳しく説明します。ここでは、文字列をどのように扱うのかについて、簡単に説明します。
文字列は、文字が複数並んだもので、最後の文字として目には見えない「ヌル文字」と呼ばれる文字がセットされたものです。
文字列は、printf関数やscanf関数を使って、画面に表示したり、キーボードから入力することが出来ます。この時指定する書式指定子は%sです。
整数に整数定数、実数に浮動小数点定数、文字に文字定数がある様に、文字列にも定数があります。文字列には文字列定数があります。
文字列の実体は複数の文字が並んだものです。代入演算子で代入したり、加減乗除などの計算はできません。
「文字列」について学びます。
文字列の実体は、char型の文字が複数集まったものです。char型の箱が複数並んだイメージ図を思い浮かべられる様になりましょう。
文字列を入れる為に用意した箱の数が足りなくなると、「実行エラー」がおきてしまいます。実行エラーとは、どのようなものかについても説明しています。
・文字と文字列は違う
文字定数と文字列定数の違いは、記号がシングルクォーテーションとダブルクォーテーションの違いである点と、文字定数は半角1文字しか書けないのに対して、文字列定数は何文字でも書ける点です。
書式指定子は、文字が「%c」で、文字列が「%s」です。更に、scanf関数で、文字を入力する時は、他の数値入力と同様に、入力する変数の前に&付けましたが、文字列入力の時は&を付けません。
あと、文字は代入演算子で代入できますが、文字列は代入することは出来ません。
・文字列は最後にヌル文字が入っているchar型の箱の集まり
char型配列で、文字列定数を使って初期化して宣言すると、文字列定数で書いた文字数+1個の箱が用意されて、最後の箱に「ヌル文字」がセットされます。
・全角文字は1文字でも文字列で扱う
char型配列で、全角文字を書いた文字列定数で期化して宣言すると、全角文字の文字数×2+1個の箱が用意されます。全角1文字は、char型の箱が2つ使われます。
全角文字の場合も、文字番号が文字の実体になりますが、この文字番号を記録するための箱のサイズがchar型の2個分になるからです。
メモ:全角文字は、使われているコードの種類によって異なる番号になります。コードの種類には、UTF-8やcp932といったものがあります。UTF-8は、日本語だけでなく様々な言語に対応したコードで、1文字を表わすのに3バイト(char型の箱が3つ)も使う場合があります。cp932は、シフトJISと呼ばれるコードで(若干違いますが・・・)、全角文字は2バイトと固定されていて、プログラムを作る時はcp932の方が作りやすいです。動画のプログラムでは、cp932のことをシフトJISと言っていて、全角文字を意識するプログラミングでは、シフトJISであることを前提にした書き方になっています。
・文字列の書式指定子は「%s」を使う
文字列の入ったchar型配列の大きさは、sizeof演算子で求めることが出来ます。
・用意した箱の数を超える文字列を入力すると実行エラー
Visual Studioのデバッグ実行した場合、用意した箱を超えて文字列を入力すると「例外をスローしました」というメッセージが表示されます。これが「実行エラー」です。
プログラムが動いている途中にトラブルが発生して、プログラムが止まってしまった状態です。
・文字列を入れる箱の数は多めに用意する
文字列を入れる箱の数は多めに用意した方がよいです。
ただ、むやみに多くすると、これもまた実行エラーの原因になりますので、多くとも100から200位に抑えておきましょう。
テキストアドベンチャーゲームのオープニングと、最初の選択のシーンのプログラムを作成しましょう。
以下に、プログラムの流れを説明します。
・プログラムの流れ
名前入力用のchar型配列を用意する。
名前を入力する(「%s」でscanf入力)。
プロローグを表示する。
Enterキー待ちの状態にする。
Enterキーが押されたら、画面クリアして、第一の選択のシーンを表示し、選択肢を入力する。
これから作るテクストアドベンチャーゲームでは、プレイヤーが幾つかの選択をすることによって、アイテムを取得し、最終シーンでは、あるアイテムを持っていたならばゴールする、といったプログラムにします。この、アイテムを取得しているのか否か、という情報を記録するのがbool型の変数になります。
bool型について学びます。
bool型の変数は、if文の条件に使われる事が多いです。if文の条件に書く場合の、書き方についは、今までの様な「==演算子」や「!=演算子」を使った書き方はしません。
bool型の変数を使った条件の書き方に慣れる様にしましょう。
・真偽はbool型で扱う
真と偽というのもデータとして扱うことができます。真と偽はbool型です。
・真偽定数はboolとfalseの2つ
bool型の変数には、boolもしくはfalseを代入します。
・bool型の変数はフラグと呼ばれる
bool型の変数にtrueを代入することを「フラグをオンにする(セットする)」、falseを代入することを「フラグをオフにする(リセットする)」という言い方をします。
・bool型の変数はifの条件に書く
bool型の変数をif文の条件に使用する場合は、「==演算子」や「!=演算子」使いません。変数名だけを書くか「!変数名」の様に、「!(否定)演算子」と組み合わせた書き方をします。
プレイヤーに選択をさせながら、冒険を進めるゲームを作ります。サンプルプログラムは、下記のイメージ図にあるように、道の選択と扉の選択の、2つの選択しかしていませんが、自分でストーリーを考え、様々な選択をさせることで、独自のゲームを作るとよいでしょう。
どのシーンで何を選択して、何を取得するかや、どの様なト書きやセリフにするか等は、下記の様なシナリオを事前に作っておくようにしましょう。
練習問題12で作ったテキストアドベンチャーにアスキーアートを表示することで、見栄えをよくします。
練習問題12のサンプルプログラムに使えるアスキーアートを、右記からダウンロードできる様にしています。
大量のアスキーアートをプログラムで表示するためには、全ての行をprintfの関数呼出しの形に修正しなければならず、とても手間がかかります。
同じような修正を何度も繰返さなければならない時に便利な、「正規表現」をつかった文字列置換を説明しています。正規表現は、色々なアプリで使われる「パターンマッチング法」です。覚えておくと便利です。
・正規表現は文字列置換に使える
正規表現を使ったパターンマッチングによる文字列置換を覚えると、修正作業を楽にすることができます。Visual Studioは正規表現による文字列置換が使えます。
正規表現は非常に沢山の機能があります。今回は、アスキーアートをprintf文に変える置換方法を説明します。
テスト実施フォーム ← テストチャレンジできます
上記テストの解説と解答