13.7 課題 13

cd c を実行した後で( ~/c に移動した後で)、以下の課題を やってみよ。

課題 13.1
関数の宣言時におけるコンパイルエラー

本文の「コンパイルエラーになる例」を入力し、実際にコンパイルしてみて、 エラーが出ることを確かめよ。 次に、関数宣言をつけ加えて、エラーが出なくなることを確認せよ。

課題 13.2
ロールプレイングゲーム作る。

主人公は地下のダンジョンを冒険し、より深い地下に降りて行くのが使命である。 地下の階はある広さがあり、主人公の位置は(7,4)のように座標で表される。 敵は1人だけしか一度には出てこないが、 敵を殺すと新たな敵があらわれる。 敵は動けないが、強さや装甲の堅さは乱数で決める。主人公が、敵と同じマス目に 入ると戦闘が始まる(逃げる事も出来るが、逃走が成功するかどうかも乱数で決 める。)。戦って勝利すると、敵が持っている 強化アイテムを手に入れられる(持ってないときもある)。また、マップには 薬が必ず落ちている。薬には主人公の生命力を回復させる働きがあり、その度合 により強さがあり、薬を拾うとその強さが加算されて行く。薬を使うと 薬はなくなってしまう。 敵の位置は分からない。また、地下への階段がどこかに必ずある。

以下のプログラムを入力せよ。但し、以下のプログラムの関数の定義には 関数の型がわざと省略されているので適切な関数の型を書き加えよ。 更に、関数宣言をしてないので、適切な関数宣言をせよ。 また、それぞれの関数のゲーム上での役割を簡単に説明せよ。

プレイしてみて、問題がないかどうか確かめよ。

作成した関数宣言(整数型の関数や引数のないものも完全に関数宣言すること) と解説(その関数のゲーム中での役割についての簡単な説明)をメイルで、 creport まで送ること。但し、題は kadai13 とすること。

プログラム全体は大きいので、送らないこと。

#include <stdio.h>

/* 関数の宣言をここにする */

/* 関数の宣言の終わり*/


/* enemy */
    int enemy_x;            /* x 座標 */
    int enemy_y;            /* 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;          /* 階段の x 座標 */
    int map_ent_y;          /* 階段の y 座標 */
    int map_floor=0;        /* 階 */
    int map_item_exist;     /* アイテムの有無 */
    int map_item_strong;    /* アイテムのレベル*/
    int map_item_x;         /* アイテムの場所 x */
    int map_item_y;         /* アイテムの場所 y */

/* hero */
    int hero_point;         /* 経験値 */
    int hero_x;             /* x 座標 */
    int hero_y;             /* 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;         /* 鎧のレベル */

/* trush */
    char trush[256];        /* ごみ */

main(){
    int input;

    hero_create();
    map_create();
    current_point();

    printf("Input senario Number => ");
    scanf("%d",&input);
    fgets(trush);

    srand(input);

    for(;;){
        if(enemy_life <= 0){
            enemy_create();
        }


        printf("現在位置 (%d, %d): 地下 %d 階\n\n",hero_x,hero_y,
            map_floor);
        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)){
            printf("階段があった。下に降りますか? ");
            if(yesno()==1){
                map_create();
                enemy_create();
                current_point();
                printf("\n\n地下 %d 階に降りた。\n\n",map_floor);
            }
        }
        if( pos_compare(hero_x,hero_y, enemy_x,enemy_y)){
            int point=hero_point;
            fight();
            if(point < hero_point){
                enemy_create();
            }
        }
    }
}

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;
}

show_status(){
    printf("\n現在の状況:\n");
    printf("体力: %d/%d\t攻撃力: %d\t守備力: %d",hero_life,hero_life_upper,
            hero_offence,hero_defence);
    printf("\t経験値: %d\n",hero_point);
    printf("\n持ち物のレベル\n剣: %d\t盾: %d\t鎧: %d\n",
            hero_sword,hero_buckler,hero_armer);
    printf("\n薬の回復力: %d\n\n\n",hero_drug);
    return;
}

hero_die(){
    printf("Hero is died at floor %d.\n",map_floor);
    printf("\nstatus\n");
    printf("hero level %d\n",hero_point/10);
    printf("\n\nGame Over\n");
    exit(0);
}

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;
}

use_drug(){
    if(hero_drug > 0){
        hero_life += hero_drug;
        if(hero_life_upper < hero_life){
            hero_life = hero_life_upper;
        }
        hero_drug=0;
        printf("\n\t薬を使った。\b\n\n");
        show_status();
    }else{
        printf("\n\t薬は今持っていない。\n\n");
    }
    return;
}

get_enemyitem(){
    if ( enemy_item_suit!=0 ){
        show_status();
        printf("\t敵はアイテムを持っていた\n");
        if(enemy_item_suit==1){
            printf("剣: level %d\n",enemy_item_strong);
        }else if(enemy_item_suit==2){
            printf("盾: level %d\n",enemy_item_strong);
        }else if(enemy_item_suit==3){
            printf("鎧: level %d\n",enemy_item_strong);
        }
        printf("装着するか?");
        if(yesno()){
            printf("\tヒーローの状態が変わった。\b\n\n");
            calc_parameter(enemy_item_suit, enemy_item_strong);
            show_status();
        }else{
            printf("\tアイテムを捨てた!\n\n");
        }
    }else{
        printf("\t敵はアイテムを持っていなかった。\n\n");
    }
    return;
}

escape(){
    int x,y;
    x = rand()%10;
    y = rand()%10;
    if( x < y ){
        return !0;
    }else{
        return 0;
    }
}

/* 敵は呼び出し元で生成すること */
fight(){
    int dum;

    for(;;){
        show_status( );
        printf("敵と戦いますか? ");
        if ( yesno()==0 && escape() == 1){
            printf("\t敵から逃げました。\n\n");
            break;
        }else{
            printf("\t敵と戦います。\n\n");
        }
        printf("Hero の攻撃: ");
        dum = (hero_offence*(rand()%10)) / (enemy_defence+1);
        enemy_life -= dum;
        printf("敵に %d のダメージ\n\n",dum);
        if (enemy_life <= 0){
            printf("\t敵を倒した!\b\n\n");
            hero_point ++;
            hero_life_upper+=10;
            printf("\tレベルがあがった。\b\n\n");
            get_enemyitem( );
            break;
        }
        printf("敵の攻撃: ");
        dum = (enemy_offence*(rand()%10)) / (hero_defence+1);
        hero_life -= dum;
        printf("%d のダメージを受けた!\n\n", dum);
        if (hero_life <=0){
            hero_die();
        }
    }
    return;
}

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;
}

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){   /* item を持っている時 */
            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{                  /* item を持っていない時 */
            enemy_item_suit=0;
            enemy_item_strong=0;
        }
    return;
}

command(){

    char input;

    printf("Command mode\n");
    printf("          up:  k\n");
    printf("left:h  status:s          right:l\n");
    printf("         down: j\n\n");
    printf("use drug:d      Quit:q\n");

    for(;;){
        printf("\ncommand input => ");
        fgets(trush);
        if(scanf("%c", &input)!=1){
            printf("Error:");
            fgets(trush);
        }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*/
walk_arround( char move ){
    if(move=='l'){
            if( hero_x == map_wide_x){
                printf("その方向には歩けません!\n");
                return;
            }
            hero_x++;
    }else if(move=='k'){
            if(hero_y == map_wide_y){
                printf("その方向には歩けません!\n");
                return;
            }
            hero_y++;
    }else if(move=='h'){
            if(hero_x == 0){
                printf("その方向には歩けません!\n");
                return;
            }
            hero_x--;
    }else if(move=='j'){
            if(hero_y == 0){
                printf("その方向には歩けません!\n");
                return;
            }
            hero_y--;
    }
    return;
}


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;
    }
}

get_drug(int exist, int strong){
    if(exist == 1){
        printf("\n\t薬(%d)を拾った!\b\n\n",strong);
        hero_drug+=strong;
    }
    return;
}

current_point(){
    hero_x = rand()%map_wide_x;
    hero_y = rand()%map_wide_y;
    return;
}


yesno(){
    char input;
    for(;;){
        printf("yes or no (y/n) => ");
        fgets(trush);
        if(scanf("%c", &input)!=1){
            printf("Error:");
            fgets(trush);
        }else{
            if(input=='y'||input=='Y') {
                return !0;
            }else if (input=='n'||input=='N'){
                return 0;
            }
        }
    }
}



最初のページ 戻る 目次
Hiroyasu Asami