マップチップデータは、用意したチップの数だけ種類があり、0からの連番を付ける。15章1,2のデータは、多くても2桁までということを前提にし、データを作成している。
《加工前のデータ》
02,02,02,02,00,00,00,00,00,00,00,02,02,02,02,02,02,02,02,02
02,00,00,00,00,00,00,21,02,00,00,02,02,02,02,02,02,02,02,02
・
・
・
02,02,02,02,02,02,02,02,02,02,02,02,02,02,02,00,02,02,02,02《加工後のデータ》
02
02
02
02
00
00
00
00
00
00
00
02
02
02
02
02
02
02
02
02
・
・
・加工後のデータを見てみると、1件のデータに対して2バイト+改行の1バイトで、計3バイト使っていることが分かる。20×15のマップデータであるため、データサイズは20×15×3で900バイトとなる。
データサイズはそのまま読み込み時間に影響する。当然、サイズが大きければ大きいほど読み込みに時間がかかる。では、このデータサイズを小さくできないだろうか?
マップチップの種類は、100や200を超えることはまずありえない。とすると、その大きさの数を表現するのに1バイト(8ビット)あれば十分であることが分かる(1バイトは0〜255までを表現できる)。ならば、データを%dで2桁の文字にするのではなく、文字として出力してはどうだろうか?
データ変換プログラムを次のように修正する。《修正済みのデータ変換プログラム》
/* マップデータを読み込み、ゲームデータ用のファイルを作成する */ #include <stdio.h> #include <stdlib.h> #include <ctype.h> void main(void) { char InputFileName[] = "MapData.txt"; char OutputFileName[] = "MapData2.txt"; char data[3]; int c, i; FILE *fp1, *fp2; if ((fp1 = fopen(InputFileName, "r")) == NULL) { printf("入力ファイル「%s」のオープンに失敗しました。処理を中止します。\n", InputFileName); exit(1); } fp2 = fopen(OutputFileName, "w"); i = 0; while ((c = getc(fp1)) != EOF) { if (isdigit(c)) { data[i] = (char)c; i++; } else { data[i] = '\0'; fprintf(fp2, "%c", atoi(data)); /* putc(fp2, atoi(data));でも同じ */ printf("%d\n", atoi(data)); // 画面確認用 i = 0; } } fclose(fp2); fclose(fp1); }※出力を%cで行っている
このプログラムにより作成されたデータファイルをテキストエディタで見ても、何が何だか分からない。しかし、ファイルサイズは小さくなった。
1文字で1データを扱うようになったため、マップデータ格納要配列はint型で宣言する必要がなくなる。よって、次のように変更する。
static charMapData[MAP_HEIGHT][MAP_WIDTH]; // マップデータ※int型は4バイト必要であるのに対しchar型は1バイトであるため、この配列に必要なメモリサイズが4分の1で済む。
次に、データを読み込む関数を次のように修正する。
//----------------------------------------------------------------------------- // 関数名 : MapDataRead() // 機能概要: マップデータの読み込み //----------------------------------------------------------------------------- static bool MapDataRead(void) { FILE *fp; char FileName[] = "MapData2.txt"; int x, y; if ((fp = fopen(FileName, "r")) == NULL) { OutputDebugString("MapData Read Error\n"); return false; } for (y=0 ; y<MAP_HEIGHT ; y++) { for (x=0 ; x<MAP_WIDTH ; x++)MapData[y][x] = getc(fp);} fclose(fp); return true; }※1文字ずつ読み込み、配列に格納する。
たったこれだけの変更で、データファイルのサイズを3分の1に、配列のメモリサイズを4分の1に縮小できた。これは、巨大なデータを扱う場合に非常に有効な手段である。
第15章2で作成したプログラムに上記修正を行い、正常に動作することを確認しなさい。