C言語で、文字だけ某ゲームっぽい簡単なゲームをコマンドプロンプトで動かしてみた

タイトル通り、某ゲームっぽい簡単なゲームをC言語でつくりました。

コマンドプロンプト(端末でもいいのかな？)で、

文字だけあのゲームっぽくしてみたいなーと思いまして練習のつもりで書きました。


※あくまでも個人的な趣味で書いたものなので、普段からCで書かれてる人から見たら
　汚い文になっているかもしれませんが、ご了承ください。

※また、コンパイラによってはwarningが出る場合があります(特にprintf関数とか…)
　もし試される場合は自己責任でお願いします。

※ゲームは動かしましたが、細かいことを気にしてないので
　クオリティはかなり低いです。

#流れ
C言語でコードを書く
　　　　↓
セリフ用のヘッダーファイルを書く(配列)
　　　　↓
コンパイラをインストールしてコンパイル
　　　　↓
コマンドプロンプトで動かす

#結果

![ot27j-1ucf8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273331/7eb706e0-6bbf-ebc4-f26e-7d20e40bf53e.gif)



#ソースコード
```c:game.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <windows.h>
#include "comment.h"
#define BUFFER_SIZE 256

void attack(int *p_life,int damage);		//攻撃用の関数
void cure(int *p_life, int cure);			//回復用の関数

int main(void){

	int enemy_life_point;	//敵のライフポイント
	int my_life_point;		//自分のライフポイント
	int cure1;				//回復用の変数
	int a;					//先攻後攻用の変数
	int b;					//攻撃回避用の変数
	int n;					//入力変数
	int m;					//入力変数
	int damage1, damage2;	//ダメージの変数
	int i;					//ループ変数

	srand((unsigned)time(NULL));
        
    //rand関数でHPはランダム、もし設定するときは範囲を指定
	enemy_life_point = rand();		//敵のライフポイント(変えてもよい)
	my_life_point = rand();		//自分のライフポイント(変えてもよい)

	a = rand();				//先攻後攻を決める

	if (a % 2 == 0 ) {		//自分が先攻

		do {
			b = rand();		//攻撃をよけるときの変数
			do {
				printf("-----------------------------------------\n");
				printf("[主人公]\n");
				printf("\n");
				
				//文章

				for (i = 0; i < 8; i++) {
					printf("%s", c[i]);
					Sleep(100);
				}

				Sleep(1000);
				printf("\n");

				printf("%d", enemy_life_point);
				for (i = 0; i < 16; i++) {
					printf("%s", d[i]);
					Sleep(100);
				}

				Sleep(1000);
				printf("\n");

				for (i = 0; i < 7; i++) {
					printf("%s", e[i]);
					Sleep(100);
				}

				printf("\n");
				
				//以上が文章
				
				//選択肢、1～4までで選択する。それ以外を押すと…
				printf("1:物理攻撃する。2:魔法攻撃する。3:回復する。:4:逃げる。:", n);
				scanf("%d",&n);

				switch (n) {
				case 1:
					damage1 = rand() % 20 + 1;				//攻撃の数字(ランダム)
					attack(&enemy_life_point, damage1);
					printf("\n");

					printf("%d", damage1);
					
					for (i = 0; i < 10; i++) {
						printf("%s", f[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("\n");
					break;
				case 2:
					damage2 = rand() % 20 + 10;				//攻撃の数字(ランダム)
					attack(&enemy_life_point, damage2);
					printf("%d", damage2);
					for (i = 0; i < 12; i++) {
						printf("%s", g[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("\n");
					break;
				case 3:
					cure1 = rand() % 20 + 1;				//回復の数字(ランダム)
					cure(&my_life_point, cure1);
					printf("\n");
					printf("%d", cure1);
					for (i = 0; i < 7; i++) {
						printf("%s", h[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("\n");
					break;
				case 4:
					printf("\n");							//逃げは禁止してます
					for (i = 0; i < 7; i++) {
						printf("%s", j[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("\n");
					break;
				case 334:									//野球好きならわかる隠しコマンド
					printf("\n");							
					for (i = 0; i < 13; i++) {
						printf("%s", hanshin[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("\n");
					break;
				default:									//その他の数字を入れた場合
					printf("\n");
					for (i = 0; i < 12; i++) {
						printf("%s", u[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("\n");
					break;
				};
			} while (n > 3);
			
			Sleep(1000);
			if (enemy_life_point <= 0 || my_life_point <= 0) {			//敵か自分のライフポイントが0になったら終了、do-while文を抜ける
				break;
			}

			printf("\n");							//現在の敵のポイントの説明
			printf("%d", enemy_life_point);
			for (i = 0; i < 16; i++) {
				printf("%s", k[i]);
				Sleep(100);
			}
			Sleep(1000);
			
			printf("\n");							//現在の自分のポイントの説明
			printf("%d", my_life_point);
			for (i = 0; i < 17; i++) {
				printf("%s", l[i]);
				Sleep(100);
			}
			Sleep(1000);
			printf("\n");
			
			//敵の攻撃の開始

			do {
				printf("-----------------------------------------\n");
				printf("[敵]\n");

				//敵の攻撃の文の説明

				for (i = 0; i < 8; i++) {
					printf("%s", o[i]);
					Sleep(100);
				}
				Sleep(1000);
				printf("\n");

				printf("%d", my_life_point);
				for (i = 0; i < 17; i++) {
					printf("%s", l[i]);
					Sleep(100);
				}
				Sleep(1000);
				printf("\n");

				for (i = 0; i < 7; i++) {
					printf("%s", e[i]);
					Sleep(100);
				}
				printf("\n");

				//選択肢

				printf("1:防御する。2:よける。：", m);
				scanf("%d", &m);
				
				switch (m) {
				case 1:										//防御するを選択したとき
					damage1 = rand() % 10 + 1;
					attack(&my_life_point, damage1);
					printf("\n");
					for (i = 0; i < 9; i++) {
						printf("%s", p[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("%d", damage1);
					Sleep(100);
					for (i = 0; i < 12; i++) {
						printf("%s", q[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("\n");
					break;
				case 2:										
					if (b % 2 == 0) {						//攻撃をよけきれなかったとき
						damage2 = rand() % 20 + 10;				
						attack(&my_life_point, damage2);
						printf("\n");

						for (i = 0; i < 10; i++) {
							printf("%s", r[i]);
							Sleep(100);
						}
						printf("%d", damage2);
						for (i = 0; i < 12; i++) {
							printf("%s", s[i]);
							Sleep(100);
						}
						Sleep(1000);
						printf("\n");
					}
					else {									//攻撃をよけれたとき
						damage2 = 0;
						attack(&my_life_point, damage2);
						printf("\n");
						for (i = 0; i < 7; i++) {
							printf("%s", t[i]);
							Sleep(100);
						}
						printf("%d", damage2);
						for (i = 0; i < 12; i++) {
							printf("%s", s[i]);
							Sleep(100);
						}
					}
					Sleep(100);
					printf("\n");
					break;

				case 334:									//野球好きにはわかる隠しコマンド
					printf("\n");							
					for (i = 0; i < 13; i++) {
						printf("%s", hanshin[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("\n");
					break;
				default:
					printf("\n");
					for (i = 0; i < 12; i++) {
						printf("%s", u[i]);
						Sleep(100);
					}
					printf("\n");
					break;
				};
			} while (m > 2);
			Sleep(1000);

			//敵か自分のライフポイントが-1になったらdo-while文が抜ける
			if (my_life_point <= -1 || enemy_life_point <= 0) {
				break;
			}
			printf("\n");
			printf("%d", my_life_point);
			for (i = 0; i < 17; i++) {
				printf("%s", l[i]);
				Sleep(100);
			}
			Sleep(1000);

			printf("\n");

			printf("%d", enemy_life_point);
			for (i = 0; i < 16; i++) {
				printf("%s", k[i]);
				Sleep(100);
			}
			Sleep(1000);

			printf("\n");

		} while (enemy_life_point > 0 || my_life_point > 0);	//ライフポイントが0以上ならループする
	}

	//自分が後攻だったとき。先攻とは逆にループさせている
	else {
		do {

			do {
				printf("-----------------------------------------\n");
				printf("[敵]\n");
				for (i = 0; i < 8; i++) {
					printf("%s", o[i]);
					Sleep(100);
				}
				Sleep(1000);
				printf("\n");

				printf("%d", my_life_point);
				for (i = 0; i < 17; i++) {
					printf("%s", l[i]);
					Sleep(100);
				}
				Sleep(1000);
				printf("\n");

				for (i = 0; i < 7; i++) {
					printf("%s", e[i]);
					Sleep(100);
				}
				printf("\n");

				printf("1:防御する。2:よける。：", m);
				scanf("%d",&m);

				switch (m) {
				case 1:
					damage1 = rand() % 10 + 1;
					attack(&my_life_point, damage1);
					printf("\n");
					for (i = 0; i < 9; i++) {
						printf("%s", p[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("%d", damage1);
					Sleep(100);
					for (i = 0; i < 12; i++) {
						printf("%s", q[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("\n");
					break;
				case 2:	
					if (b % 2 == 0) {
						damage2 = rand() % 20 + 10;
						attack(&my_life_point, damage2);
						printf("\n");
						for (i = 0; i < 10; i++) {
							printf("%s", r[i]);
							Sleep(100);
						}
						printf("%d", damage2);
						for (i = 0; i < 12; i++) {
							printf("%s", s[i]);
							Sleep(100);
						}
						Sleep(100);
						printf("\n");
					}
					else {
						damage2 = rand() % 5 + 1;
						attack(&my_life_point, damage2);
						printf("\n");
						for (i = 0; i < 7; i++) {
							printf("%s", t[i]);
							Sleep(100);
						}
						printf("%d", damage2);
						for (i = 0; i < 12; i++) {
							printf("%s", s[i]);
							Sleep(100);
						}
					}
					Sleep(100);
					printf("\n");
					break;

				case 334:
					printf("\n");
					for (i = 0; i < 13; i++) {
						printf("%s", hanshin[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("\n");
					break;
				default:
					printf("\n");
					for (i = 0; i < 12; i++) {
						printf("%s",u[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("\n");
					break;
				};
			} while (m > 2);

			printf("\n");

			printf("%d", my_life_point);
			for (i = 0; i < 17; i++) {
				printf("%s", l[i]);
				Sleep(100);
			}

			Sleep(1000);
			printf("\n");

			printf("%d", enemy_life_point);
			for (i = 0; i < 16; i++) {
				printf("%s", k[i]);
				Sleep(100);
			}

			Sleep(1000);
			printf("\n");

			do {
				printf("-----------------------------------------\n");
				printf("[主人公]\n");
				printf("\n");
				for (i = 0; i < 8; i++) {
					printf("%s", c[i]);
					Sleep(100);
				}
				Sleep(1000);

				printf("\n");

				printf("%d", enemy_life_point);
				for (i = 0; i < 16; i++) {
					printf("%s", d[i]);
					Sleep(100);
				}
				Sleep(1000);

				printf("\n");

				for (i = 0; i < 7; i++) {
					printf("%s", e[i]);
					Sleep(100);
				}
				printf("\n");

				printf("1:物理攻撃する。2:魔法攻撃する。3:回復する。4:逃げる；", n);
				scanf("%d", &n);
				switch (n) {
				case 1:
					damage1 = rand() % 20 + 1;				//攻撃の数字(ランダム)
					attack(&enemy_life_point, damage1);
					printf("\n");

					printf("%d", damage1);

					for (i = 0; i < 10; i++) {
						printf("%s", f[i]);
						Sleep(100);
					}
					Sleep(1000);
					break;
				case 2:
					damage2 = rand() % 20 + 10;				//攻撃の数字(ランダム)
					attack(&enemy_life_point, damage2);
					printf("%d", damage2);
					for (i = 0; i < 12; i++) {
						printf("%s", g[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("\n");
					break;
				case 3:
					cure1 = rand() % 20 + 1;				//回復の数字(ランダム)
					cure(&my_life_point, cure1);
					printf("\n");
					printf("%d", cure1);
					for (i = 0; i < 7; i++) {
						printf("%s", h[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("\n");
					break;
				case 4:
					printf("\n");							//逃げは禁止です
					for (i = 0; i < 7; i++) {
						printf("%s", j[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("\n");
					break;
				case 334:									//野球好きならわかる
					printf("\n");							
					for (i = 0; i < 13; i++) {
						printf("%s", hanshin[i]);
						Sleep(100);
					}
					Sleep(1000);
					printf("\n");
					break;
				default:									//その他の数字を入れた場合
					printf("\n");
					for (i = 0; i < 12; i++) {
						printf("%s", u[i]);
						Sleep(100);
					}
					Sleep(100);
					printf("\n");
					break;
				};
			} while (n > 3);

			printf("\n");

			if (my_life_point <= 0 || enemy_life_point <= 0) {
				break;
			}			
			printf("%d", enemy_life_point);
			for (i = 0; i < 16; i++) {
				printf("%s", k[i]);
				Sleep(100);
			}
			printf("\n");

			printf("%d", my_life_point);
			for (i = 0; i < 17; i++) {
				printf("%s", l[i]);
				Sleep(100);
			}
			Sleep(1000);
			printf("\n");

		} while (enemy_life_point > 0 || my_life_point > 0);
	}
	
	if (enemy_life_point <= 0) {
		printf("------------------------------\n");
		for (i = 0; i < 9; i++) {
			printf("%s", w[i]);
			Sleep(500);
		}
	}
	if(my_life_point <= 0){
		printf("------------------------------\n");
		for (i = 0; i < 15; i++) {
			printf("%s", x[i]);
			Sleep(500);
		}
	}
	return 0;
}

void attack(int *p_life,int damage){		//攻撃の関数

	int life = *p_life;
	life -= damage;
	*p_life = life;

	return;
}

void cure(int *p_life,int cure) {			//回復の関数

	int life = *p_life;
	life += cure;
	*p_life = life;

	return;
}
```


次にヘッダーファイル


```comment.h
char* c[] = { "敵","を","攻","撃","し","ま","す","。" };
char* d[] = { "が","現","在","の","敵","の","ラ","イ","フ","ポ","イ","ン","ト","で","す","。" };
char* e[] = { "何","を","し","ま","す","か","？" };
char* f[] = { "の","攻","撃","を","与","え","ま","し","た","。"};
char* g[] = { "の","魔","法","攻","撃","を","与","え","ま","し","た","。"};
char* h[] = {"回","復","し","ま","し","た","。"};
char* j[] = {"逃","げ","れ","ま","せ","ん","。"};
char* hanshin[] = {"な","ん","で","や","！","阪","神","関","係","無","い","や","ろ"};
char* k[] = {"が","現","在","の","敵","の","ラ","イ","フ","ポ","イ","ン","ト","で","す","。"};
char* l[] = {"が","現","在","の","自","分","の","ラ","イ","フ","ポ","イ","ン","ト","で","す","。"};
char* o[] = { "攻","撃","し","て","き","ま","す","。"};
char* p[] = {"攻","撃","を","受","け","ま","し","た","。" };
char* q[] = { "の","ダ","メ","ー","ジ","を","受","け","ま","し","た","。"};
char* r[] = {"よ","け","れ","ま","せ","ん","で","し","た","。"};
char* s[] = {"の","ダ","メ","ー","ジ","を","受","け","ま","し","た","。"};
char* t[] = {"よ","け","れ","ま","し","た","。"};
char* u[] = {"そ","ん","な","数","字","は","あ","り","ま","せ","ん","。"};
char* w[] = {"あ","な","た","の","勝","ち","で","す","。"};
char* x[] = {"あ","な","た","の","負","け","で","す","。","次","頑","張","っ","て","。"};
```


あとはこれをコンパイルすると動きます。

#ふりかえり
ヘッダーファイルは配列なのですが一文字ずつダブルクォーテーションで
囲まなくても良い方法がないかと考えましたが、
これ以外で行うと(1文字ずつ囲まず、まとめて囲むなど)うまくいかなかったので、
良い解決策(コード)があれば教えてほしいです。。。

個人的にはゲームのクオリティより、文字が１つずつ出てくる技術に少し感動しました。

このコードも改良しますが、次はゲームのクオリティにもこだわっていきたいです(笑)。