| 3.4 評価クラスの生成とファイルの読み書き |
本節ではEvaluatorクラスの生成、破棄と評価パラメータファイルの読み書きについて説明します
EvaluatorクラスはEvaluator_New()で生成します。
Evaluator *Evaluator_New(void)
{
Evaluator *self;
self = malloc(sizeof(Evaluator));
if (self) {
if (!Evaluator_Initialize(self)) {
Evaluator_Delete(self);
self = NULL;
}
}
return self;
}
これまで説明したクラスと同様に領域を確保し、初期化関数を呼び出しています。
次に初期化関数Evaluator_Initialize()について見てみましょう。
static int Evaluator_Initialize(Evaluator *self)
{
int i, j;
int mirror_in, mirror_out, coeff;
int mirror_corner_coeff[] = { POW_3_2, POW_3_5, POW_3_0, POW_3_3, POW_3_6, POW_3_1, POW_3_4, POW_3_7 };
memset(self, 0, sizeof(Evaluator));
for (i = 0; i < PATTERN_ID_NUM; i++) {
self->Value[i] = calloc(PatternSize[i], sizeof(int));
if (!self->Value[i]) {
return 0;
}
}
for (i = 0; i < POW_3_8; i++) {
mirror_in = i;
mirror_out = 0;
coeff = POW_3_7;
for (j = 0; j < 8; j++) {
mirror_out += mirror_in % 3 * coeff;
mirror_in /= 3;
coeff /= 3;
}
if (mirror_out < i) {
self->MirrorLine[i] = mirror_out;
} else {
self->MirrorLine[i] = i;
}
}
for (i = 0; i < POW_3_8; i++) {
mirror_in = i;
mirror_out = 0;
for (j = 0; j < 8; j++) {
mirror_out += mirror_in % 3 * mirror_corner_coeff[j];
mirror_in /= 3;
}
if (mirror_out < i) {
self->MirrorCorner[i] = mirror_out;
} else {
self->MirrorCorner[i] = i;
}
}
return 1;
}
この関数では3つの処理を行っています。
最初に各パターンの評価値を格納するための領域を確保しています。
確保した領域が0で初期化されるようにcallocを使用しています。
次にMirror_Lineの初期化を行っています。
最後にMirror_Cornerの初期化を行っています。
Mirror_Lineは8マスを1列に並べたパターンに対して、反転したパターンのインデックスを調べるための変数です。
反転したパターンのインデックスが自分のインデックスより小さい場合には、反転したパターンのインデックスを返します。
反転したパターンのインデックスが自分のインデックスと同じか大きい場合には、自分のインデックスを返します。
Mirro_Cornerは隅の8マスのパターンに対して、反転したパターンのインデックスを調べます。
次にEvaluatorクラスの破棄です。
生成時に確保した領域を解放しているだけです。
static void Evaluator_Finalize(Evaluator *self)
{
int i;
for (i = 0; i < PATTERN_ID_NUM; i++) {
if (self->Value[i]) {
free(self->Value[i]);
}
}
}
void Evaluator_Delete(Evaluator *self)
{
Evaluator_Finalize(self);
free(self);
}
次にファイルから評価パラメータを読み込む関数です。
特に難しいことはせず
int Evaluator_Load(Evaluator *self, const char *in_file_name)
{
FILE *fp;
int i;
fp = fopen(in_file_name, "rb");
if (!fp) {
return 0;
}
for (i = 0; i < PATTERN_ID_NUM; i++) {
if (fread(self->Value[i], sizeof(int), PatternSize[i], fp) < (size_t)PatternSize[i]) {
fclose(fp);
return 0;
}
}
fclose(fp);
return 1;
}
最後にファイルに評価パラメータを書き込む関数です。
Evaluator_Load()の読み込む処理が書き込む処理に変わっているだけです。
int Evaluator_Save(const Evaluator *self, const char *in_file_name)
{
FILE *fp;
int i;
fp = fopen(in_file_name, "wb");
if (!fp) {
return 0;
}
for (i = 0; i < PATTERN_ID_NUM; i++) {
if (fwrite(self->Value[i], sizeof(int), PatternSize[i], fp) < (size_t)PatternSize[i]) {
fclose(fp);
return 0;
}
}
fclose(fp);
return 1;
}