C言語　ゲームプログラム講習　初歩




# ジャンケンプログラム

サークル活動で使ったコード

目的

- ゲームプログラムに触れる
- 関数を使ってみる
 

## 基本コード

基本コード(main(),selectHand()関数部分)はその前の講習で作らせた。

```C:jaynken.c
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>

int cntWin = 0; //自分が勝った回数
int selectHand(); //自分の手を宣言
void judge(int you, int enemy); //勝敗を判定し、結果を標準出力する
void printHand(int hand);

int cntGame = 0;
void loginGame();
void readGameState();
void writeGameState();
char userName[100] = "";
char userFileName[100] = "";

int main(void) {
    //自分の手と敵の手を宣言。１〜３の数字が入る
    int you;
    int enemy;

    //乱数の初期化　一度だけ行う
    srand((unsigned) time(NULL));

    //ユーザ名を入力する。新規ユーザの場合は記録ファイル(.csv)を作る

    
    int i = 0;
    //ゲーム動作部分
    for (i = 1; i < 300; i++) {
        //自分の手を設定
        printf("\n\n gu=1,tyoki=2,pa=3 End_this_game=0 \n Please input your hand...\n");
        scanf("%d", &you);

        //敵の手を設定
        enemy = selectHand();

        printf("Your Hand = %d and Enemy's Hand = %d... \n so...\n", you, enemy);

        //判定
         //関数化せよ
        //ここから
        if (enemy == you) {
            printf("aiko\n");
        } else if ((you == 1 && enemy == 2) || (you == 2 && enemy == 3) || (you == 3 && enemy == 1)) {
            printf("you win\n");

        } else {
            printf("you lose\n");
        }
        //ここまで


	  //ゲームの回数を加算
         cntGame++;          
        printf("total you　%d win on %d games , your rate %f %% \n",cntWin,cntGame,cntWin/cntGame);
        
      
     

    }
    return 0;
}

int selectHand() {
    //return 1 or 2 or 3
    return rand() % 3 + 1;
}

void judge(int you, int enemy) {


}

void printHand(int hand) {
    if (hand == 1) {
        printf("グー！　　 ＿_\n");
        printf("　　　　　/｣｣｣｣\n");
        printf("　　　　 ｜っ丿\n");
        printf("　 ∧_∧ / ／\n");
        printf("　( ･ω･)／\n");
        printf("　(つ　 ﾉ\n");
        printf("　 ｕ-ｕ\n");
    }
    if (hand == 2) {

        printf("　　　　　　　チョキ！\n");
        printf("　　　　　(Ｖ)\n");
        printf("　　　　　/ｱE)\n");
        printf("　 ∧_∧ / ／\n");
        printf("　( ･ω･)／\n");
        printf("　(つ　 ﾉ\n");
        printf("　 ｕ-ｕ\n");
    }
    if (hand == 3) {
        printf("　　　　　　　パー！\n");
        printf("　　　　　｢｢｢h\n");
        printf("　　　　 Ｃ　ﾉ\n");
        printf("　 ∧_∧ / ／\n");
        printf("　( ･ω･)／\n");
        printf("　(つ　 ﾉ\n");
        printf("　 ｕ-ｕ\n");

    }
}

void loginGame() {
    if (strlen(userFileName) == 0) {
        printf("Start jyanken game\n\ninput user name...");
        scanf("%s", userName);
        printf("Welcome %s !!!\n", userName);

        //文字列のコピー
        strcpy(userFileName, userName);
        //ユーザファイルの準備
        strcat(userFileName, ".csv");
        readGameState();
    }
}

void readGameState() {

    //ファイルの読み込みに必要な変数の宣言
    FILE *fp;
    int ret;
   
    //rモード　ファイルがないとき続行するとエラー起きる
    fp = fopen(userFileName, "r");

    //例外処理
    if (fp == NULL) {
        //ファイルがないときはファイルを作る
        writeGameState();
    } else {
          //ユーザ名、通算勝数、通算ゲーム数の記録を読み込む　※ユーザ名を読み込んでいることには、意味が無い
        while ((ret = fscanf(fp, "%[^,],%d,%d", userName, &cntWin, &cntGame)) != EOF) {
            //ユーザ名、通算勝数、通算ゲーム数の記録を出力
            printf("<<Record %s >> total %d win . total %d games .\n", userName, cntWin, cntGame);
        }
        fclose(fp);
    }
}

void writeGameState() {

    FILE *fp;
    
    //wモード　ファイルがないときは作る
    fp = fopen(userFileName, "w");

    //例外処理
    if (fp == NULL) {
        printf("error：cannot open file %s\n", userFileName);
        exit(1);//ファイルを開けないので終了する
    }
    //ファイルにデータを書き込んで終了する
    //ユーザ名、通算勝数、通算ゲーム数
    printf("\n%s write data... please wait...\n", userFileName);
    fprintf(fp, "%s,%d,%d\n", userName, cntWin, cntGame);
    printf("complete!!");
    fclose(fp);
}


````

---

## 課題

基本のコードに

1. 勝敗を判定し、結果を標準出力する部分を関数化せよ
1. 自分が勝った回数をカウントするコードを挿入せよ
1. じゃんけんの手を表示する関数を挿入せよ
1.  `printf("total you　%d win on %d games , your rate %f %% \n",cntWin,cntGame,cntWin/cntGame);`このコードを修正せよ
1. じゃんけんをするとき、０を入力したらゲームが終了するコードを挿入せよ
1. 次の関数を挿入せよ`loginGame();writeGameState();`

```C:勝利数をカウントするコード
       cntWin++;
```

```C:じゃんけんの手を表示するコード
     	printHand(you);
	printHand(enemy);
```

```C:修正後のコード
       printf("total you　%d win on %d games , your rate %f %% \n",cntWin,cntGame,(float)cntWin/(float)cntGame);
```

```C:ゲームを終了するためのコード
        if(you==0){
            printf("END");
            exit(0);//正常終了　OSによってソースが変わる
	//CentOS MacOS確認
        }

```

課題の狙い

1. 関数化の方法や関数の役割を理解しているか
1. プログラムのじゃんけん判定部分（条件分岐）を把握しているか
1. 関数の利用方法の確認
1. キャストを理解しているか
1. プログラム全体の流れを理解しているか
1. プログラム全体の流れを理解しているか


---

## 最終コード

```C:jaynken.c
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>

int cntWin = 0; //自分が勝った回数
int selectHand(); //自分の手を宣言
void judge(int you, int enemy); //勝敗を判定し、結果を標準出力する
void printHand(int hand);

int cntGame = 0;
void loginGame();
void readGameState();
void writeGameState();
char userName[100] = "";
char userFileName[100] = "";

int main(void) {
    //自分の手と敵の手を宣言。１〜３の数字が入る
    int you;
    int enemy;

    //乱数の初期化　一度だけ行う
    srand((unsigned) time(NULL));

    //ユーザ名を入力する。新規ユーザの場合は記録ファイル(.csv)を作る
    loginGame();
    
    int i = 0;
    //ゲーム動作部分
    for (i = 1; i < 300; i++) {
        //自分の手を設定
        printf("\n\n gu=1,tyoki=2,pa=3 End_this_game=0 \n Please input your hand...\n");
        scanf("%d", &you);
        printHand(you);
        //敵の手を設定
        enemy = selectHand();
        printHand(enemy);
        printf("Your Hand = %d and Enemy's Hand = %d... \n so...\n", you, enemy);

        //判定
        judge(you,enemy);
        
        //ゲームの回数を加算
        cntGame++;
        printf("total you　%d win on %d games , your rate %f %% \n",cntWin,cntGame,(float)cntWin/(float)cntGame);
        
        //記録をセーブする
        writeGameState();
    }
    return 0;
}

int selectHand() {
    //return 1 or 2 or 3
    return rand() % 3 + 1;
}

void judge(int you, int enemy) {
            //関数化せよ
        //ここから
        if (enemy == you) {
            printf("aiko\n");
        } else if ((you == 1 && enemy == 2) || (you == 2 && enemy == 3) || (you == 3 && enemy == 1)) {
            printf("you win\n");
            cntWin++;
        } else {
            printf("you lose\n");
        }
        //ここまで

}

void printHand(int hand) {
    if (hand == 1) {
        printf("グー！　　 ＿_\n");
        printf("　　　　　/｣｣｣｣\n");
        printf("　　　　 ｜っ丿\n");
        printf("　 ∧_∧ / ／\n");
        printf("　( ･ω･)／\n");
        printf("　(つ　 ﾉ\n");
        printf("　 ｕ-ｕ\n");
    }
    if (hand == 2) {

        printf("　　　　　　　チョキ！\n");
        printf("　　　　　(Ｖ)\n");
        printf("　　　　　/ｱE)\n");
        printf("　 ∧_∧ / ／\n");
        printf("　( ･ω･)／\n");
        printf("　(つ　 ﾉ\n");
        printf("　 ｕ-ｕ\n");
    }
    if (hand == 3) {
        printf("　　　　　　　パー！\n");
        printf("　　　　　｢｢｢h\n");
        printf("　　　　 Ｃ　ﾉ\n");
        printf("　 ∧_∧ / ／\n");
        printf("　( ･ω･)／\n");
        printf("　(つ　 ﾉ\n");
        printf("　 ｕ-ｕ\n");

    }
}

void loginGame() {
    if (strlen(userFileName) == 0) {
        printf("Start jyanken game\n\ninput user name...");
        scanf("%s", userName);
        printf("Welcome %s !!!\n", userName);

        //文字列のコピー
        strcpy(userFileName, userName);
        //ユーザファイルの準備
        strcat(userFileName, ".csv");
        readGameState();
    }
}

void readGameState() {

    //ファイルの読み込みに必要な変数の宣言
    FILE *fp;
    int ret;
   
    //rモード　ファイルがないとき続行するとエラー起きる
    fp = fopen(userFileName, "r");

    //例外処理
    if (fp == NULL) {
        //ファイルがないときはファイルを作る
        writeGameState();
    } else {
          //ユーザ名、通算勝数、通算ゲーム数の記録を読み込む　※ユーザ名を読み込んでいることには、意味が無い
        while ((ret = fscanf(fp, "%[^,],%d,%d", userName, &cntWin, &cntGame)) != EOF) {
            //ユーザ名、通算勝数、通算ゲーム数の記録を出力
            printf("<<Record %s >> total %d win . total %d games .\n", userName, cntWin, cntGame);
        }
        fclose(fp);
    }
}

void writeGameState() {

    FILE *fp;
    
    //wモード　ファイルがないときは作る
    fp = fopen(userFileName, "w");

    //例外処理
    if (fp == NULL) {
        printf("error：cannot open file %s\n", userFileName);
        exit(1);//ファイルを開けないので終了する
    }
    //ファイルにデータを書き込んで終了する
    //ユーザ名、通算勝数、通算ゲーム数
    printf("\n%s write data... please wait...\n", userFileName);
    fprintf(fp, "%s,%d,%d\n", userName, cntWin, cntGame);
    printf("complete!!");
    fclose(fp);
}
````