C++でスロットを作ってみよう
-関数を作成してコードの整理をしてみる-
プログラムを勉強したことが無い人でもとても簡単にゲームを作る基礎をC++を使用して実際に作りながら
プログラミングをしたことがない人に向けて教える感覚で説明していきます。
今回は前回とはゲームの挙動自体に進捗は見られませんが、コードを整理する為の方法の基礎を使って、
できるだけ同じ内容を書かないように整理をしていきます。
関数を作ってコードを分かりやすくする
関数は一部の参考書などで難しい言葉が使用された際や参考にした文献などを説明する際に使われるその言葉に米印が書かれていて、それに関する詳しい説明が別の箇所に乗っていてその箇所を見にいく時と似ている動作をプログラムが行います。
まずは以下のコードを #include から int main() までの間に以下のコードを書いてください。
void printOwnMoney(int money) { //画面に表示させるUI printf("\n"); printf("スロットゲーム\n"); printf("========================\n"); printf("l所持金:%dコイン\n", money); printf("========================\n"); return; }
この関数の中身は所持金を確認するために繰り返し書いていたコードです。
上のコードを書いておくことでこのコードを書いた行より下側で簡単に上のコードを実行してくれる準備ができています。
これと同様に掛け金を設定していたコードも新たに関数にする為に以下のコードを先ほど書いた printOwnMoney の最後の括弧から int main の行の間に書き足してください。
int checkBet() { int bet; //掛け金を表示するUI printf("\n"); printf("掛け金を入力して下さい(数字)\n"); //掛け金の入力処理 scanf_s("%d", &bet); //画面に表示させるUI printf("\n"); printf("掛け金:%d\n", bet); return bet; }
前回に書いた所持金が増えた、減ったを表すテキストは消してしまっています。
それではこれらの関数を使ってメインの中身をコンパクトにしていきます。
メイン内のコードを以下のように書き換えて下さい。
int main() { int money = 1000; int bet = 0; //所持金を表示させる関数 printOwnMoney(money); //掛け金を確認する関数とそれを足す処理 bet = checkBet(); money = money + bet; //所持金を表示させる関数 printOwnMoney(money); //掛け金を確認する関数とそれを引く処理 bet = checkBet(); money = money - bet; //所持金を表示させる関数 printOwnMoney(); //今は入力で止めるために使用 printf("\n"); printf("数字を入力すると終了します。"); scanf_s("%d", &bet); return 0; }
これでメインの中身がかなり見やすくコンパクトになりました。
これでプログラムを実行してみると前回と同様の動きをしていることが分かります。
基本的に上のような関数を使って様々な箇所で同じプログラムを使いたい場合は関数を使って呼び出すことでコード上で同じ内容を繰り返し使用したい場合に楽になったり、
関数に名前が付けれるので関数毎に使用している機能が区別でき、分かりやすくすつ為に使用します。
最終的には少し見にくいですが画像のようなコードになっていればOKです。
変数と関数
グローバル変数とローカル変数
関数を作る前に覚えておくべきこととして変数を宣言した場所が大事になります。
現在所持金と掛け金の変数はメインの関数の中で作成している為、メインの関数以外で使うことができません。
正確には『{}』の中で宣言した変数は『{}』より外側でその変数を使用できない仕組みになっています。
関数の作成の仕方は後ほど説明しますが、変数の使える幅を説明する用の例を挙げさせて頂きます。
int A = 1000; void Test(); int main() { int B = 2000; { int C = 3000; } //AとBが使える A = 1000; B = 2000; //Cは使えない C = 3000; //関数を使用する test(); return 0; } void Test() { //Aは使える A = 1000; //BとCは使えない B = 2000; C = 3000; return 0; }
上記の例で「A」「B」「C」のそれぞれの場所を確認すると例のコードにも書いてはいますが、それぞれ以下の位置にあり使える範囲は記載の通りになります。
変数の名前 | 表記されている場所 | 使用できる範囲 |
A | 『{}』の中には書かれておらず、最も外側の場所 | メインの関数だけでなく、宣言された場所より下の行ならどこからでも使用できる |
B | メイン関数の『{}』の中 | メインの関数内のみで使用可能 |
C | メイン関数の『{}』の中の更にもう一つ『{}』の中 | 同じメインの関数内でも{}で区切られている場所内でのみ使用できる |
このように変数を作った際にその変数よりいくら下側の行に書かれていようと『{}』で区切られた箇所でのみ使用できるよう仕様になっています。
変数「A」のようなプログラムのどこからでも変数の値を変えたり、使用したりすることができる変数を『グローバル変数』と言い、変数「B」「C」のようにどの場所でも特定の範囲内で確認できるような変数を『ローカル変数』と呼ばれます。
これを聞くと変数を全て「A」の箇所に書いておけば最も楽に思えるかもしれませんが、今回のようなコマンドプロンプト上で動くスロットはさほど長いコードや変数の種類を沢山用意する必要がないので問題ないかもしれませんが、より膨大なプログラムを作成することになった際に変数を作る際の用途に合った変数を考えた時に、別の箇所で使っている似た名前の変数と被ったり、同じ場所に置かれているがために用途が分かりにくくなる可能性があるため、使用する変数は用途に応じて場所を考える必要があります。
上記を踏まえて関数の宣言と定義のことについて説明します。
関数の宣言と定義
今回の記事で使用した「関数」は『関数の型』の後に『関数の名前』を書きその後に『()』を書いてその後に『{ }』を書くことで『{ }』の中身に書いたコードを実行することができるようになります。
関数を作る際の型から『()』はその関数を作ることを意味し、『関数の宣言』と言い、
関数の『{ }』の中身はその関数の『定義』と言われます。
以下がコードが関数を作成する際の例です。
・戻り値が小数点を含まない整数の関数
int FunctionInt() { return 1; }
・戻り値が小数点を含む数字の関数
float FunctionFloat() { return 1.5; }
変数の宣言の回と同様に関数を宣言する際にどの型の関数を作るか決める必要があり、変数の宣言をする際に使用できる型は全て使用できます。
型を決めた後の関数の名前は自由に作れるのでその関数の内容が名前で判断しやすいものを作ると伝わりやすく、見返した際に思い返しやすくもなるので名前をなるべる分かりやすいものを付けるの良いです。
関数の内容の終わる部分に return 『値』で終わるように書く必要があり、この値のことを『戻り値』と言い、関数を他の場所で使った際に最終的にこの『戻り値』の値が返ってくる仕組みになっています。
上記の例の関数を使用して以下のような例を作ります。
int main() { int A = 0; float B = 0.0; A = FunctionInt(); B = FunctionFloat(); int C = FunctionInt() + FunctionInt(); return 0; }
このコードの場合に例で作った FunctionInt() 内の return の後に書いた数字は「1」となので、このメインの関数内では FunctionInt() と書かれている場所は最終的に整数「1」として扱うようになります。
またこの関数の戻り値が数字であり、型が同じ場合は演算子を使用して関数の戻り値同士で計算することがでます。
同様にFunctionFloat() の戻り値は「1.5」なので上記の例の場合は最終的に以下の処理と同様の意味になっています。
int main() { int A = 0; float B = 0.0; A = 1; B = 1.5; int C = 1 + 1; return 0; }
スロットを作成するコードにおいて「掛け金の確認用」の関数が今回この戻り値を使用しており、入力した値を掛け金としてその値が戻り値として所持金を増減させる計算をメインの関数で使用している仕組みにしています。
また関数を宣言する際に void という戻り値を設定する必要がない場合に使用する特殊な型があります。
・戻り値のない関数
void FunctionVoid() { return; }
この void の型を使用する場面としては void の中身だけで機能を完結させたい場合にしようします。
スロットを作るコードにおいては自分の所持金をコマンドプロンプト上に表示させるために使用しています。
引数を含む関数の宣言と定義
今回は所持金を表す変数がメインの関数内で宣言されている為、メイン以外の関数ではこの変数を扱うことができません。このような場合に関数を宣言する際の『( )』この括弧の中に型と名前を書くことでメインの関数以外の箇所でも変数が『( )』の中に書いた名前として別の関数内でも使用できるようになります。
この「()」の中に書き込む他の関数に持っていく値を『引数(ひきすう』と言います。
//所持金表示用の関数 void printOwnMoney(int test) { //画面に表示させるUI printf("\n"); printf("スロットゲーム\n"); printf("========================\n"); printf("l所持金:%dコイン\n", test); printf("========================\n"); return; } //メインの関数 int main() { int money = 1000; //所持金を表示 void printOwnMoney(500); //所持金を変数を使用して表示 void printOwnMoney(money); return 0; }
引数を含む関数を使用する際は関数の名前と『()』の中に宣言の時に指定した型に当てはまる数字などを直接書き込むか、型に当てはまる変数を例のように書き込むことで、関数 printOwnMoney 内では宣言の際に()で指定した名前である「test」としてその関数内で扱えるようになります。
また引数は『()』の中身をコンマで区切ることで複数の値を引数として扱うことができます。
void PrintTest(int num1, int num2, float num3, char letter); int main() { int index; float number; char moji = 'A'; PrintTest(index, index, number, moji); }
引き数の型の種類と数が自由に変えられ、上記の場合だと左から「整数」、「整数」、「小数点」、「文字」の順になっていて、この関数を呼び出す時も宣言時に作った時と全く同じ順序で型を合わせなければ使用できません。
引き数を沢山使いたい場合もあるかもしれませんが、あまり多く引数を設定してしまうと使いづらくなる可能性があるので適度な関数を作ることを目指すとよいと思います。
おまけ
関数の宣言と定義は実は以下のように分けて書くこともできます。
#include <stdio.h> //関数の宣言だけ void HelloWorld(); int main() { HelloWorld(); return 0; } //関数の定義を後で書く void HelloWorld() { printf("HELLO WORLD"); }
通常メインの関数から始まってほかの関数を使用したい場合はそのメイン関数より上側の行に関数の宣言がされている必要があります。
この例のように関数の宣言だけの場合は上記のように中身は書かずに宣言だけを行い、それ以降のどの場所でも良いので今までの説明どおり関数の宣言と定義をすることでメイン関数より下側に内容が書かれていても問題なく動作させることができます。
今回のスロットではこの機能を使う予定はないので簡単にメモしておきます。
今回はここまで
今回はどちらかというとC++のコードの大事な要素の説明だけでゲーム制作自体は全く変化はありませんでしたが、コードが比較的に見やすくなりました。
次回でif文というものを使って条件による分岐を作り、スロットのあたりと外れをランダムに発生させるようにしてスロットの片鱗が見れるようにしたいと思います。
前回までの記事は以下から確認できます。