RPGっぽいの製作進捗：装備機能

RPGっぽいのに装備機能を追加しました。装備アイテムのアイテム名はSF風にしてみました。
あとは、前回までアイテム画面を表示するのに、インベントリ用の構造体を引数に持ってきていたのですが、メニュー機能経由で引数を持ってきていると面倒臭かったので、プレイヤーのステータスやインベントリなど、広い範囲で使うものは全てグローバル変数にしました。
![game5.png](https://qiita-image-store.s3.amazonaws.com/0/46217/9848278d-a2e5-8e40-cf1a-45197f3fc00d.png)←装備を外せました。その他の動作も確認済みです。
![game7.png](https://qiita-image-store.s3.amazonaws.com/0/46217/ef812a42-2ae3-fe46-c0a1-a822b59c78c4.png)
↑一日後、装備に装甲と推進装置を追加し、GUIを改善しました。この時点で200行増えて、EquipFunc.cのサイズが11.1KBとなりました。
装備変更機能を実装した時は、頭を抱えるようなバグは起きずサクサクと組めたので、ある程度は上達したのかも……？

以下プログラムソースです。改善後のものを貼っておきます。改善点がありましたら遠慮なくお願い致します。

```Ruby:EquipFunc.c
/*装備機能*/

#include <stdio.h>
#include "SysFunc.h"

extern struct Status Player;
extern struct ItemInfo Item[];
extern struct EquipInfo EqIf[];
extern struct Inv Inventory[];
extern int EquipInv[]; /*グローバル変数あれこれ*/

void EquipFunc()
{
	int EquipEnd = 0, flag = 0, Opt = 0, Opt2 = 0, OptMIN = 0, OptMAX = 0;
	int IDMIN, IDMAX, Eqcount, EqSlot[400]; /*装備参照用の変数*/
	char Input[50];
	
	while(EquipEnd != 1)
	{
		for (flag = 0; flag <= 399; flag++) /*繰り返し使うこともあるEqSlotを初期化*/
		{
			EqSlot[flag] = 0;
		}
		
		printf("\n\n\n------------------------------");
		printf("\n装備変更");
		printf("\n------------------------------");
		
		printf("\n\n%4s  %8s: %-38s  %-10s\n","No.","装備部位","アイテム名","パラメータ上昇値");
		
		for (flag = 0; flag <=9; flag++) /*現在装備を表示*/
		{
			
			switch (flag) /*装備箇所に応じて表示するステータスのラベルを変える*/
			{
			case 0:
			{
				printf("\n\n%-54s  W %6s %6s %6s","","ATTACK","RANGE","NOISE");
				break;
			}
			case 4:
			{
				printf("\n\n%-54s  W %6s","","HP");
				break;
			}
			case 5:
			{
				printf("\n\n%-54s  W %6s %6s %6s","","ENERGY","EN_G","NOISE");
				break;
			}
			case 6:
			{
				printf("\n\n%-54s  W %6s %6s","","SHIELD","NOISE");
				break;
			}
			case 7:
			{
				printf("\n\n%-54s  W %6s %6s","","SPEED","NOISE");
				break;
			}
			case 8:
			{
				printf("\n");
				break;
			}
			}
			
			printf("\n%3d.  ",flag + 1);
			
			switch (flag) /*装備部位名を表示。それぞれ違うのでswitchで分ける*/
			{
			case 0:
			{
				printf("%8s:","右主武装");
				break;
			}
			case 1:
			{
				printf("%8s:","右副武装");
				break;
			}
			case 2:
			{
				printf("%8s:","左主武装");
				break;
			}
			case 3:
			{
				printf("%8s:","左副武装");
				break;
			}
			case 4:
			{
				printf("%8s:","装甲");
				break;
			}
			case 5:
			{
				printf("%8s:","動力");
				break;
			}
			case 6:
			{
				printf("%8s:","障壁");
				break;
			}
			case 7:
			{
				printf("%8s:","推進装置");
				break;
			}
			case 8:
			{
				printf("%8s:","補助1");
				break;
			}
			case 9:
			{
				printf("%8s:","補助2");
			}
			}
			
			if (Player.Equipment[flag] == 0) /*その部位に装備していなかった場合*/
			{
				printf(" %-38s"," - EMPTY -"); /*なし*/
			}
			else
			{
				printf(" %-38s", EqIf[Player.Equipment[flag]].Name); /*装備名を表示*/
			}
			
			switch (flag) /*装備箇所に応じて表示するステータスを変える*/
			{
			case 0: /*0～3 武器*/
			{
			}
			case 1:
			{
			}
			case 2:
			{
			}
			case 3:
			{
				printf(" %2d %6d %6d %6d", EqIf[Player.Equipment[flag]].Weight, EqIf[Player.Equipment[flag]].Atk, EqIf[Player.Equipment[flag]].Range, EqIf[Player.Equipment[flag]].Noise);
				break;
			}
			case 4: /*4 装甲*/
			{
				printf(" %2d %6d", EqIf[Player.Equipment[flag]].Weight, EqIf[Player.Equipment[flag]].PlusHP);
				break;
			}
			case 5: /*5 エネルギージェネレータ*/
			{
				printf(" %2d %6d %6d %6d", EqIf[Player.Equipment[flag]].Weight, EqIf[Player.Equipment[flag]].PlusEN, EqIf[Player.Equipment[flag]].PlusEN_G, EqIf[Player.Equipment[flag]].Noise);
				break;
			}
			case 6: /*6 シールドジェネレータ*/
			{
				printf(" %2d %6d %6d", EqIf[Player.Equipment[flag]].Weight, EqIf[Player.Equipment[flag]].PlusShield, EqIf[Player.Equipment[flag]].Noise);
				break;
			}
			case 7: /*7 スラスタ*/
			{
				printf(" %2d %6d %6d", EqIf[Player.Equipment[flag]].Weight, EqIf[Player.Equipment[flag]].Speed, EqIf[Player.Equipment[flag]].Noise);
				break;
			}
			case 8: /*8,9 補助装備*/
			{
				break;
			}
			case 9:
			{
				break;
			}
			}
			
		}
		
		flag = 0;
		
		printf("\n\n  0.戻る\n\n\n入力：");
		
		OptMIN = 0;
		OptMAX = 10;
		
		while (flag != 1) /*アイテム選択 or 戻る*/
		{
			gets(Input);
			Opt = atoi(Input);
			
			OptJudge(&flag, Opt, OptMIN, OptMAX); /*参照：SysFunc.h OptJudge.c*/
		}
		
		IDMIN = 0;
		IDMAX = 0;
		
		switch (Opt)
		{
		case 0: /*メニューに戻る*/
		{
			EquipEnd = 1;
			break;
		}
		case 1: /*1から4まで武器*/
		{
		}
		case 2:
		{
		}
		case 3:
		{
		}
		case 4:
		{
			IDMIN = 1;
			IDMAX = 400; /*装備ID1～400は武器*/
			break;
		}
		case 5: /*装甲*/
		{
			IDMIN = 401;
			IDMAX = 500; /*装備ID401～500は装甲*/
			break;
		}
		case 6: /*エネルギージェネレータ*/
		{
			IDMIN = 501;
			IDMAX = 600; /*装備ID501～600はエネルギージェネレータ*/
			break;
		}
		case 7: /*シールドジェネレータ*/
		{
			IDMIN = 601;
			IDMAX = 700; /*装備ID601～700はシールドジェネレータ*/
			break;
		}
		case 8: /*スラスタ*/
		{
			IDMIN = 701;
			IDMAX = 800; /*装備ID701～800はスラスタ*/
			break;
		}
		case 9: /*9,10は補助装備*/
		{
		}
		case 10:
		{
			IDMIN = 801;
			IDMAX = 999; /*装備ID801～999は補助装備*/
			break;
		}
		}
		
		flag = 0;
		Eqcount = 0;
		
		if (Opt != 0) /*1～10、つまり装備変更を選択*/
		{
			for (flag = 0; flag <= 999; flag++) /*装備スロットを総ざらい*/
			{
				if (EquipInv[flag] >= IDMIN && EquipInv[flag] <= IDMAX) /*選択した装備部位と同じ分類の装備があるかどうかを判別*/
				{
					EqSlot[Eqcount] = EquipInv[flag]; /*結果を表示するための配列にIDを代入*/
					Eqcount++; /*EqSlotに代入する位置を1個ずらす*/
				}
			}
			
			printf("\n\n\n------------------------------\n");
			
			switch (Opt) /*装備部位名を表示。それぞれ違うのでswitchで分ける*/
			{
			case 1:
			{
				printf("%s:","右主武装");
				printf("\n------------------------------");
				printf("\n\n\n No.  %-38s %6s %6s %6s\n","アイテム名","ATTACK","RANGE","NOISE");
				for (flag = 0; flag <= 399 && EqSlot[flag] != 0; flag++) /*EqSlotの中身、つまりその部位に装備可能なものを表示する*/
				{
					printf("\n%3d.  %-38s %2d %6d %6d %6d", flag + 1, EqIf[EqSlot[flag]].Name, EqIf[EqSlot[flag]].Weight, EqIf[EqSlot[flag]].Atk, EqIf[EqSlot[flag]].Range, EqIf[EqSlot[flag]].Noise);
				}
				break;
			}
			case 2:
			{
				printf("%s:","右副武装");
				printf("\n------------------------------");
				printf("\n\n\n No.  %-38s %6s %6s %6s\n","アイテム名","ATTACK","RANGE","NOISE");
				for (flag = 0; flag <= 399 && EqSlot[flag] != 0; flag++) /*EqSlotの中身、つまりその部位に装備可能なものを表示する*/
				{
					printf("\n%3d.  %-38s %2d %6d %6d %6d", flag + 1, EqIf[EqSlot[flag]].Name, EqIf[EqSlot[flag]].Weight, EqIf[EqSlot[flag]].Atk, EqIf[EqSlot[flag]].Range, EqIf[EqSlot[flag]].Noise);
				}
				break;
			}
			case 3:
			{
				printf("%s:","左主武装");
				printf("\n------------------------------");
				printf("\n\n\n No.  %-38s %6s %6s %6s\n","アイテム名","ATTACK","RANGE","NOISE");
				for (flag = 0; flag <= 399 && EqSlot[flag] != 0; flag++) /*EqSlotの中身、つまりその部位に装備可能なものを表示する*/
				{
					printf("\n%3d.  %-38s %2d %6d %6d %6d", flag + 1, EqIf[EqSlot[flag]].Name, EqIf[EqSlot[flag]].Weight, EqIf[EqSlot[flag]].Atk, EqIf[EqSlot[flag]].Range, EqIf[EqSlot[flag]].Noise);
				}
				break;
			}
			case 4:
			{
				printf("%s:","左副武装");
				printf("\n------------------------------");
				printf("\n\n\n No.  %-38s %6s %6s %6s\n","アイテム名","ATTACK","RANGE","NOISE");
				for (flag = 0; flag <= 399 && EqSlot[flag] != 0; flag++) /*EqSlotの中身、つまりその部位に装備可能なものを表示する*/
				{
					printf("\n%3d.  %-38s %2d %6d %6d %6d", flag + 1, EqIf[EqSlot[flag]].Name, EqIf[EqSlot[flag]].Weight, EqIf[EqSlot[flag]].Atk, EqIf[EqSlot[flag]].Range, EqIf[EqSlot[flag]].Noise);
				}
				break;
			}
			case 5:
			{
				printf("%s:","装甲");
				printf("\n------------------------------");
				printf("\n\n\n No.  %-38s %6s\n","アイテム名","HP");
				for (flag = 0; flag <= 399 && EqSlot[flag] != 0; flag++) /*EqSlotの中身、つまりその部位に装備可能なものを表示する*/
				{
					printf("\n%3d.  %-38s %2d %6d", flag + 1, EqIf[EqSlot[flag]].Name, EqIf[EqSlot[flag]].Weight, EqIf[EqSlot[flag]].PlusHP);
				}
				break;
			}
			case 6:
			{
				printf("%s:","動力");
				printf("\n------------------------------");
				printf("\n\n\n No.  %-38s %6s %6s %6s\n","アイテム名","ENERGY","EN_G","NOISE");
				for (flag = 0; flag <= 399 && EqSlot[flag] != 0; flag++) /*EqSlotの中身、つまりその部位に装備可能なものを表示する*/
				{
					printf("\n%3d.  %-38s %2d %6d %6d %6d", flag + 1, EqIf[EqSlot[flag]].Name, EqIf[EqSlot[flag]].Weight, EqIf[EqSlot[flag]].PlusEN, EqIf[EqSlot[flag]].PlusEN_G, EqIf[EqSlot[flag]].Noise);
				}
				break;
			}
			case 7:
			{
				printf("%s:","障壁");
				printf("\n------------------------------");
				printf("\n\n\n No.  %-38s %6s %6s\n","アイテム名","SHIELD","NOISE");
				for (flag = 0; flag <= 399 && EqSlot[flag] != 0; flag++) /*EqSlotの中身、つまりその部位に装備可能なものを表示する*/
				{
					printf("\n%3d.  %-38s %2d %6d %6d", flag + 1, EqIf[EqSlot[flag]].Name, EqIf[EqSlot[flag]].Weight, EqIf[EqSlot[flag]].PlusShield, EqIf[EqSlot[flag]].Noise);
				}
				break;
			}
			case 8:
			{
				printf("%s:","推進装置");
				printf("\n------------------------------");
				printf("\n\n\n No.  %-38s %6s %6s\n","アイテム名","SPEED","NOISE");
				for (flag = 0; flag <= 399 && EqSlot[flag] != 0; flag++) /*EqSlotの中身、つまりその部位に装備可能なものを表示する*/
				{
					printf("\n%3d.  %-38s %2d %6d %6d", flag + 1, EqIf[EqSlot[flag]].Name, EqIf[EqSlot[flag]].Weight, EqIf[EqSlot[flag]].Speed, EqIf[EqSlot[flag]].Noise);
				}
				break;
			}
			case 9:
			{
				printf("%s:","補助1");
				printf("\n------------------------------");
				printf("\n\n\n No.  %-38s %6s %6s %6s\n","アイテム名","ATTACK","RANGE","NOISE");
				for (flag = 0; flag <= 399 && EqSlot[flag] != 0; flag++) /*EqSlotの中身、つまりその部位に装備可能なものを表示する*/
				{
					printf("\n%3d.  %-38s %2d %6d %6d %6d", flag + 1, EqIf[EqSlot[flag]].Name, EqIf[EqSlot[flag]].Weight, EqIf[EqSlot[flag]].Atk, EqIf[EqSlot[flag]].Range, EqIf[EqSlot[flag]].Noise);
				}
				break;
			}
			case 10:
			{
				printf("%s:","補助2");
				printf("\n------------------------------");
				printf("\n\n\n No.  %-38s %6s %6s %6s\n","アイテム名","ATTACK","RANGE","NOISE");
				for (flag = 0; flag <= 399 && EqSlot[flag] != 0; flag++) /*EqSlotの中身、つまりその部位に装備可能なものを表示する*/
				{
					printf("\n%3d.  %-38s %2d %6d %6d %6d", flag + 1, EqIf[EqSlot[flag]].Name, EqIf[EqSlot[flag]].Weight, EqIf[EqSlot[flag]].Atk, EqIf[EqSlot[flag]].Range, EqIf[EqSlot[flag]].Noise);
				}
				break;
			}
			}
			
			if (EqSlot[0] == 0) /*装備可能なものが一つもなかった場合。多分無いけど……一応*/
			{
				printf("\n装備可能なアイテムがありません。");
			}
			else
			{
				OptMIN = 0;
				OptMAX = flag + 1; /*「はずす」の番号が、装備可能なアイテムの数+1*/
				
				printf("\n\n%3d.はずす\n  0.戻る\n\n\n入力：", OptMAX);
				
				flag = 0;
				
				while (flag != 1) /*装備選択 or 戻る or 装備をはずす*/
				{
					gets(Input);
					Opt2 = atoi(Input);
					
					OptJudge(&flag, Opt2, OptMIN, OptMAX); /*参照：SysFunc.h OptJudge.c*/
				}
				
				if(Opt2 == 0) /*戻る*/
				{
				
				}
				else
				{
					if (Opt2 == OptMAX) /*装備をはずす*/
					{
						Player.Equipment[Opt - 1] = 0;
					}
					else /*装備変更*/
					{
						Player.Equipment[Opt - 1] = EqSlot[Opt2 - 1];
					}
				}
			}
			
		}
	}
}
```