<<前 [TOP] 次>>
Visual Studioで新規プロジェクトを作り、次のcppファイルを作成して下さい。
【Game1.cpp】
#include <iostream> #include <stdlib.h> int yesno( ); void current_point( ); void enemy_create( ); void hero_create( ); int escape( ); void calc_parameter( int suit, int strong ); void hero_die( ); void show_status( ); void map_create( ); void get_drug(int exist, int strong); int pos_compare(int a_x, int a_y, int b_x, int b_y); void walk_arround( char move ); void use_drug( ); void get_enemyitem( ); void fight( ); void command( ); /* enemy */ int enemy_x; int enemy_y; int enemy_life; int enemy_offence; int enemy_defence; int enemy_item_suit; int enemy_item_strong; /* map */ int map_wide_x; int map_wide_y; int map_ent_x; int map_ent_y; int map_floor=0; int map_item_exist; int map_item_strong; int map_item_x; int map_item_y; /* hero */ int hero_point; int hero_x; int hero_y; int hero_life; int hero_life_upper; int hero_offence; int hero_defence; int hero_drug; int hero_sword; int hero_buckler; int hero_armer; int main() { int input; hero_create(); map_create(); current_point(); std::cout << "Input senario Number => "; std::cin >> input; std::cin.clear(); std::cin.ignore(); srand(input); for(;;) { if(enemy_life <= 0) { enemy_create( ); } std::cout << "現在位置 (" << hero_x << "," << hero_y << "):地下 " << map_floor << "階" << std::endl << std::endl; command(); if( pos_compare(map_item_x,map_item_y,hero_x,hero_y)){ get_drug(map_item_exist, map_item_strong); map_item_exist=0; } if( pos_compare(map_ent_x,map_ent_y, hero_x,hero_y)) { std::cout << "階段があった。下に降りますか? "; if(yesno() == 1) { map_create(); enemy_create(); current_point(); std::cout << std::endl << std::endl << "地下 " << map_floor << "階に降りた。" << std::endl << std::endl; } } if (pos_compare(hero_x,hero_y, enemy_x,enemy_y)) { int point=hero_point; fight(); if(point < hero_point) { enemy_create(); } } } } void map_create( ) { map_floor++; map_wide_x = rand()%( 2 + map_floor) + 10; map_wide_y = rand()%( 2 + map_floor) + 10; map_ent_x = rand()%map_wide_x; map_ent_y = rand()%map_wide_y; map_item_exist=1; map_item_strong= rand()%( 10+10*map_floor) + 30; map_item_x=rand()%map_wide_x; map_item_y=rand()%map_wide_y; return; } void show_status( ) { std::cout << std::endl << "現在の状況:" << std::endl; std::cout << "体力: " << hero_life << "/" << hero_life_upper << "\t攻撃力:" << hero_offence << "\t守備力:" << hero_defence << std::endl; std::cout << "\t経験値:" << hero_point << std::endl; std::cout << std::endl; std::cout << "持ち物のレベル" << std::endl; std::cout << "剣:" << hero_sword << "\t盾:" << hero_buckler << "\t鎧:" << hero_armer << std::endl << std::endl; std::cout << "薬の回復力:" << hero_drug << std::endl << std::endl << std::endl; return; } void hero_die( ) { std::cout << "Hero is died at floor " << map_floor << "." << std::endl; std::cout << std::endl; std::cout << "status" << std::endl; std::cout << "hero level " << hero_point/10 << std::endl; std::cout << std::endl; std::cout << "Game Over" << std::endl; exit(0); } void calc_parameter( int suit, int strong ) { if(suit==1) { hero_offence = hero_offence - hero_sword + strong; hero_sword = strong; } else if(suit==2) { hero_defence = hero_defence - hero_buckler + strong; hero_buckler = strong; } else if(suit==3) { hero_defence = hero_defence - hero_armer + strong; hero_armer = strong; } return; } void use_drug( ) { if(hero_drug > 0) { hero_life += hero_drug; if(hero_life_upper < hero_life) { hero_life = hero_life_upper; } hero_drug=0; std::cout << std::endl << "\t薬を使った。\b" << std::endl << std::endl; show_status(); } else { std::cout << std::endl << "\t薬は今持ってない。" << std::endl << std::endl; } } void get_enemyitem( ) { if ( enemy_item_suit!=0 ) { show_status(); std::cout << "\t敵はアイテムを持っていた。" << std::endl; if(enemy_item_suit==1) { std::cout << "剣:level " << enemy_item_strong << std::endl; } else if( enemy_item_suit==2) { std::cout << "盾:level " << enemy_item_strong << std::endl; } else if(enemy_item_suit==3) { std::cout << "鎧:level " << enemy_item_strong ; } std::cout << "装備するか?"; if(yesno()) { std::cout << "\tヒーローの状態が変わった。\b" << std::endl << std::endl; calc_parameter(enemy_item_suit, enemy_item_strong); show_status(); } else { std::cout << "\tアイテムを捨てた!" << std::endl << std::endl; } } else { std::cout << "\t敵はアイテムを持っていなかった。" << std::endl << std::endl; } return; } int escape() { int x, y; x = rand()%10; y = rand()%10; if( x < y ) { return !0; } else { return 0; } } void fight() { int dum; for(;;) { show_status( ); std::cout <<"敵と戦いますか?"; if ( yesno()==0 && escape() == 1){ std::cout << "\t敵から逃げました。" << std::endl << std::endl; break; } else { std::cout << "\t敵と戦います。" << std::endl << std::endl; } std::cout << "Heroの攻撃:"; dum = (hero_offence*(rand()%10)) / (enemy_defence+1); enemy_life -= dum; std::cout << "敵に " << dum << "のダメージ" << std::endl << std::endl; if(enemy_life -= dum){ std::cout << "\t敵を倒した!\b" << std::endl << std::endl; hero_point ++; hero_life_upper+=10; std::cout << "\tレベルが上がった。\b" << std::endl << std::endl; get_enemyitem( ); break; } std::cout << "敵の攻撃:"; dum = (enemy_offence*(rand()%10)) / (hero_defence+1); hero_life -= dum; std::cout << dum << "のダメージを受けた!" << std::endl << std::endl; if (hero_life <=0) { hero_die(); } } return; } void hero_create() { hero_point = 0; hero_life_upper = 100 + rand()%10; hero_life = hero_life_upper; hero_x = 0; hero_y = 0; hero_offence = rand()%5 + 5; hero_defence = rand()%5 + 5; hero_drug = 0; hero_sword = rand()%3 +1; hero_buckler=rand()%3; hero_armer = rand()%2 +1; return; } void enemy_create() { int i; enemy_x = rand() % map_wide_x; enemy_y = rand() % map_wide_y; enemy_life = rand() % 100 + map_floor*50; enemy_offence=rand() % 10 + map_floor; enemy_defence=rand() % (map_floor+2); if ( rand() % 2 == 1 ) { i=rand()%3+1; enemy_item_suit=i; if(i==1) { enemy_item_strong = rand()%(10 + map_floor); } else if ( i==2) { enemy_item_strong = rand() % (5 + map_floor); } else { enemy_item_strong = rand() % (7 + map_floor); } } else { enemy_item_suit = 0; enemy_item_strong = 0; } return; } void command() { char input; std::cout << "Command mode" << std::endl; std::cout << " up: k" << std::endl; std::cout << "left:h status:s right:l" << std::endl; std::cout << " down: j" << std::endl << std::endl; std::cout << "use drug:d Quit:q" << std::endl; for(;;) { std::cout << std::endl << "comand input => "; std::cin.clear(); std::cin.ignore(); std::cin >> input; if(!std::cin) { std::cout << "Error:"; } else { if (input=='d') { use_drug(); break; } else if (input == 's' ) { show_status(); break; } else if (input=='j' || input=='k' || input=='l' || input=='h') { walk_arround(input); break; } else if(input=='q') { exit(0); } } } return; } /* move lower j: left l: right h: upper k */ void walk_arround( char move ) { if(move=='l') { if( hero_x == map_wide_x) { std::cout << "その方向には歩けません!" << std::endl; return; } hero_x++; } else if(move=='k') { if(hero_y == map_wide_y) { std::cout << "その方向には歩けません!" << std::endl; return; } hero_y++; } else if (move=='h'){ if(hero_x == 0) { std::cout << "その方向には歩けません!" << std::endl; return; } hero_x--; } else if (move=='j') { if(hero_y == 0) { std::cout << "その方向には歩けません!" << std::endl; return; } hero_y--; } return; } int pos_compare(int a_x, int a_y, int b_x, int b_y) { if ( a_x == b_x && a_y == b_y ) { return !0; } else { return 0; } } void get_drug(int exist, int strong) { if(exist == 1) { std::cout << std::endl; std::cout << "\t薬(" << strong << ")を拾った!\b" << std::endl << std::endl; hero_drug+=strong; } return; } void current_point() { hero_x = rand()%map_wide_x; hero_y = rand()%map_wide_y; return; } int yesno() { char input; for(;;){ std::cout << "yes or no (y/n) => "; std::cin.clear(); std::cin.ignore(); std::cin >> input; if(!std::cin) { std::cout << "Error:" << std::endl << std::endl; } else { if(input=='y' || input=='Y') { return !0; } else if (input=='n' || input=='N') { return 0; } } } }
まずこのゲームの内容について説明します。
主人公は地下のダンジョンを冒険し、より深い地下に降りていくのが使命です。
地下の階はある広さがあり、主人公の位置は(7,4)のように座標で表示されます。
敵は1人だけしか一度には出てきませんが、敵を殺すと新たな敵が現れます。
敵は動けませんが、強さや装甲の堅さは乱数で決まります。
主人公が敵と同じマス目にはいると戦闘が始まります。
逃げることも出来ますが、逃走が成功するかどうかも乱数で決まります。
勝って勝利すると、敵が持っている強化アイテムを手に入れられます。(持っていないときもあります。)
またマップには薬が必ず落ちています。
薬には主人公の生命力を回復させる働きがあります。
薬には強さがあり、薬を拾うとその強さが加算されています。
薬は使うとなくなってしまいます。
敵の位置はわかりません。
また、地下への階段がどこかに必ずあります。
まず関数の定義をもう一度書いておきます。
返り値の型 関数名 ( 引数, 引数, ・・・・){ 実行文; }
ここで返り値の型を指定すると関数の返り値を整数以外にとることができます。
例 文字の整数値を与えると対応する文字を返す char mojikansuu(int a) { char c; c = a; return c; }
この例では関数の名前の前にcharがあるので関数mojikansuu()は文字型の関数となり、返り値は文字型でなければなりません。
もう一つ例をあげます。
例 ポインタを返す char *string() { const char *s = "this is a test."; return s; }
この例はアドレスを返す関数の例です。
「[型]*」はポインタを意味していますので返り値はアドレスでなくてはなりません。
例では「"this is a test."」という文字列のアドレスを返しています。
関数の宣言について説明します。
関数を作ったときに、積極的にコンパイラにその関数の型や引数を教えてあげると、コンパイラはもし間違った関数の呼び出しをしたときにきちんとその旨を知らせてくれます。
このようにコンパイラに関数の仕様を知らせるために関数の仕様を書くことを関数の宣言といいます。
関数の宣言はファイルの先頭、すなわち#include文の後に書いておくと良いでしょう。
関数の型 関数名 ( 引数, 引数, ・・・・);
例 char mojikansuu(int a); char *string(void);
もし関数に引数がある場合は引数の型もちゃんと宣言しなければなりません。
ただし引数の変数名は完全なダミーなので名前を変えることもできますし、省略することもできます。
char mojikansuu(int num); char mojikansuu(int);
宣言の最後にセミコロン(;)をつけることを忘れないようにしなければなりません。
関数の引数がない場合はvoidを使ってください。
これによりコンパイラは「この関数には引数がない」を理解できます。
ただしchar *string();というように、voidを省略して宣言することもできます。
関数の宣言がない場合はコンパイルエラーがおこりますので、かならずmain関数の前に関数の記述しておく癖をつけておいてください。
関数には引数としてアドレスを渡すことができます。
関数は結果を一つしか返すことができません。
複数の結果を返したいときは変数のアドレスを渡すことで直接その値を操作することができます。
void str(const char *add) ; int main() { const char *s="this is a test."; str(s); std::cout << s << std::endl; } void str(const char *add) { const char *p= add; }
この例の場合、main()で宣言している文字列"this is a test."のアドレスを関数str()に渡しています。
もちろん関数str()でもそのアドレスを受け取ることができるように、引数の宣言に「const char *add」を用いている点に注意してください。
その結果addには先の"this is a test"のアドレスが代入されることになります。
従ってmain()関数での文字列出力でも「"this is a test."」となります。
文字型ポインタではこのプログラムで「std::cout << *s << std::endl;」とすると「"t"」のみが出力されます。
この違いを覚えておいてください。
グローバル変数について少し書いておきます。
これまで学習してきた変数はすべて関数の中のみで有効でしたが、他の関数からも見ることができるような変数を作ることもできます。
このような変数をグローバル変数といいます。
C言語ではグローバル変数は2種類あり、同じプログラムソースにあるものと違うプログラムソースにあるグローバル変数とは違う扱いになります。
ここでは同じプログラムソースにあるグローバル変数の宣言の仕方を学びます。
ファイル内で有効なグローバル変数を宣言するには関数の外側、ファイルの最初のところで宣言すればよいです。
グローバル変数の例 #include <iostream> int gloval = 1; /*グローバル変数*/ void test() { std::cout << "グローバル変数" << gloval << std::endl; } int main() { std::cout << "グローバル変数" << gloval << std::endl; gloval++; test(); }
この例では最初にグローバル変数は1に設定されていて、main()の中で表示するときは1になっています。
次にその値を2に増やして関数testを呼ぶと、関数testの中で表示しても確かに2になっています。
最後に文字リテラルについて説明します。
ダブルコーテーション(””)で囲こみ、出力させる文字列の中に「¥t」や「¥b」というのを使用しています。
これを文字リテラルといいます。
文字リテラルは以下のように変換されます。
サンプルプログラムをビルドして実行てみましょう。
最初の入力だけクリアがうまくいかないので、2回続けて入力してください。
↓↓クリックして頂けると励みになります。