6.3 定石データの読み書き |
本節では定石データファイルを読み書きする関数の説明をします。
定石データは膨大になることがあるため、ファイルに保存しておくと管理しやすくなります。
また定石データだけをファイルにしておけば、他の人が作成した定石データを使うことができて便利です。
まず最初に定石データファイルのフォーマットについて説明します。
ファイルフォーマットは以下の通りです。
最初にデータの個数が書き込まれており、次にデータの個数分だけ局面データが書き込まれています。
名前 | 意味 | 型 | 個数 |
---|---|---|---|
Num | データの個数 | int | 1 |
Data | 局面データ | PositionData | Num |
定石データを読み込む関数Opening_Load()は以下のようになっています。
static int Opening_Read(Opening *self, FILE *fp) { PositionData *data = NULL; if (fread(&self->Num, sizeof(int), 1, fp) < 1) { return 0; } if (self->Num % NUM_INFO_BLOCK == 0) { self->Max = (self->Num / NUM_INFO_BLOCK + 1) * NUM_INFO_BLOCK; } else { self->Max = (self->Num / NUM_INFO_BLOCK + 2) * NUM_INFO_BLOCK; } data = realloc(self->Data, self->Max * sizeof(PositionData)); if (!data) { return 0; } self->Data = data; if (fread(self->Data, sizeof(PositionData), self->Num, fp) < (size_t)self->Num) { return 0; } return 1; } int Opening_Load(Opening *self, const char *in_file_name) { FILE *fp; fp = fopen(in_file_name, "rb"); if (!fp) { return 0; } if (!Opening_Read(self, fp)) { fclose(fp); return 0; } fclose(fp); return 1; }
渡されたファイル名のファイルを開き、局面データの個数を読み込みます。
次に局面データの分だけメモリ領域を確保します。
ただし、最低NUM_INFO_BLOCK個の空きデータが存在するように領域を確保します。
最後に局面データを読み込みファイルを閉じます。
定石データを書き込む関数Opening_Write()は以下の通りです。
ファイルを開いて局面データの数と、局面データを書き込んでいるだけです。
static int Opening_Write(const Opening *self, FILE *fp) { if (fwrite(&self->Num, sizeof(int), 1, fp) < 1) { return 0; } if (fwrite(self->Data, sizeof(PositionData), self->Num, fp) < (size_t)self->Num) { return 0; } return 1; } int Opening_Save(const Opening *self, const char *in_file_name) { FILE *fp; fp = fopen(in_file_name, "wb"); if (!fp) { return 0; } if (!Opening_Write(self, fp)) { fclose(fp); return 0; } fclose(fp); return 1; }