学生向けプログラミング入門 | 無料

学生向けにプログラミングを無料で解説。Java、C++、Ruby、PHP、データベース、Ruby on Rails, Python, Django

C++プログラミング入門その19 while文とswitch文を使用したプログラム

>>この記事には書き直した新しいページがあります。<<


<<前  [TOP]  次>>


Visual Studioで新規プロジェクトを作り、次のcppファイルを作成して下さい。


【WhileTest1.cpp】

#include<iostream>

void main() {

	int i=20, sum=0;

	while(i>10) {

		sum +=i;
		i--;
	}

	std::cout << "sum = " << sum << std::endl;
}



変数 i の値が10より小さくなるまで、足し算し続けるプログラムです。
このプログラムでは、while文といわれる構文を使用しています。

while( 継続条件 ) {

    実行文;
}



while文では、継続条件が真(true)である間、中括弧内の実行文を繰り返し実行します。
従って、while文をfor文で書き直したり、for文をwhile文で書き直すこともできます。


例えば、次のfor文は、

for ( i=0; i<10; i++) {
    sum +=i;
}

次のように書き換えられます。

i=0;

 while( i<10) {
    sum += i;
    i++;
}



サンプルプログラムをビルドしてデバッグしてみましょう。





Visual Studioで新規プロジェクトを作り、次のcppファイルを作成して下さい。


【SwitchTest1.cpp】

#include<iostream>

int GetInput(int input);

void main() {

	int input,cont;

	while(1) {

		std::cout << "適当な数字を入力してください。0ならば終わり ==> ";
		std::cin.clear();
		std::cin.ignore();

		std::cin >> input;

		cont = GetInput(input);

		if(cont == 0) {

			break;
		}

		std::cout << "結果 = " << cont << std::endl;
	}
}

int GetInput(int input) {

	int result;

	switch(input) {

		case 1:	result = 1; break;
		case 2:	result = 2; break;
		case 3: 
		case 4:	result = 3; break;
		case 0:	result = 0; break;
		default:	result = 4; break;

	}

	return result;
}



このプログラムでは、switch文といわれる構文を使用しています。

switch ( 整数値をとる式 ) {

    case 定数値: 実行文; break;
     case 定数値: 実行文; break;
         ・
         ・
         ・
    default: 実行文; break;
}



switch文は、整数値を持つ式にしか使えない点に注意してください。
C言語では、文字も整数値を持つので文字にも使えます。
caseの後の値は定数でなくてはなりません。


defaultはif文のelseにあたりますが、記述しなくても動きます。
caseのどれにもあたらなければ、defaultが実行されます。
if文の一部はswitch文でスリムに書き換えることができます。


もし、文字を扱うときは、定数値をシングルコーテーション(’’)で囲むことを忘れないようにしてください。


サンプルプログラムのように、

case 3:
case 4: result = 3; break;

とすれば、( input == 3 || input == 4 )と同じ意味になります。
break文で一つのcase文を区切っていると考えてください。


while(1){}は無限ループになります。
break文がないとプログラムが終了しませんので使用するときは注意してください。


サンプルプログラムをビルドしてデバッグしてみましょう。
最初だけ入力を2回行って下さい。





Visual Studioで新規プロジェクトを作り、次のcppファイルを作成して下さい。


【Game2.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;

void 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);

        while(true) {

                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 << "階段があった。下に降りますか? ";

                        switch(yesno()) {

                                case 1: map_create();
                                        enemy_create();
                                        current_point();
										std::cout << std::endl << std::endl << "地下 "<< map_floor << "階に降りた。" << std::endl << std::endl;
                                        break;

			}

                }

                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 ) {

	switch(suit) {

                case 1: hero_offence = hero_offence - hero_sword + strong;
                        hero_sword = strong; break;

                case 2: hero_defence = hero_defence - hero_buckler + strong;
                        hero_buckler = strong; break;

                case 3: hero_defence = hero_defence - hero_armer + strong;
                        hero_armer = strong; break;
        }

        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;

                switch(enemy_item_suit) {

                        case 1: std::cout << "剣:level " <<enemy_item_strong << std::endl;
                                break;

                        case 2: std::cout << "盾:level " <<enemy_item_strong << std::endl;
                                break;

                        case 3: std::cout << "鎧:level " << enemy_item_strong ;
                                break;
                }

				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;

        while(true) {
                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;

                switch(i) {
                        case 1: enemy_item_strong = rand()%(10 + map_floor);
                                break;
                        case 2: enemy_item_strong = rand() % (5 +map_floor);
                                break;

                        default: enemy_item_strong = rand() % (7 +map_floor);
                                 break;
                }
        }
        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;

        while(true){
			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 {
                        switch(input) {
                                case 'y':
                                case 'Y': return !0;
                                          break;
                                case 'n':
                                case 'N': return 0;
                                          break;
                        }
                }
        }

}



前に作成したダンジョンゲーム「Game1.cpp」をwhile文とswitch文を使って書き換えたプログラムです。
for文はwhile文に、if文はswitch文になっています。


書き換えた関数は次の関数です。

  • void main();
  • void calc_parameter( int suit, int strong )
  • void get_enemyitem()
  • void fight()
  • void enemy_create()
  • int yesno()


    なお、while(true)という記述を何回か使っていますが、これはwhile(1)と同じことで、無限ループになっています。





    <<前  [TOP]  次>>