/**************************************************/ /* 15パズル/PDB用テーブル作成 puz15db.c */ /* Computer & Puzzle 2001/04 by takaken */ /**************************************************/ #include #include #include #define BOARD_WIDTH 4 /* ボード横長さ */ #define BOARD_HEIGHT 4 /* ボード縦長さ */ #define BOARD_SIZE (BOARD_WIDTH * BOARD_HEIGHT) #define PDBSIZE 12108096 /* = 16 * 15C5 * 10C5 */ #define TBLSIZE 378378 /* = (PDB_SIZE-1)/32+1 */ typedef unsigned long u32; /******************/ /* データベース1 */ /******************/ char *FileName1 = "puz15p1.db"; int BOARD1[BOARD_SIZE] = { 3, 1, 1, 1, 2, 3, 3, 1, 2, 3, 3, 1, 2, 2, 2, 0 }; /******************/ /* データベース2 */ /******************/ char *FileName2 = "puz15p2.db"; int BOARD2[BOARD_SIZE] = { 1, 1, 1, 3, 1, 3, 3, 2, 1, 3, 2, 2, 3, 2, 2, 0 }; int BOARD[BOARD_SIZE]; char PDB[PDBSIZE]; /* パターンDB */ int MOVAL[BOARD_SIZE][5]; /* 移動可能テーブル */ int PASCAL[BOARD_SIZE][6]; /* パスカルの三角形 */ u32 BITTBL[32]; /* 1ビット値テーブル */ u32 SAMEDB[TBLSIZE]; /* 同一局面検査テーブル */ u32 CHECK1[TBLSIZE]; /* 新局面フラグテーブル */ u32 CHECK2[TBLSIZE]; /* 新局面フラグテーブル */ time_t StartTime; /****************************************************/ /* 探索結果のテーブルをディスクに保存する */ /****************************************************/ void WritePDB(char *filename) { int i; FILE *fp; fp = fopen(filename, "wb"); for (i=0; i=0 && y2=0 && x2= c) { h1 -= c; r1--; BOARD[i] = 1; } else { c = PASCAL[n2][r2]; if (h2 >= c) { h2 -= c; r2--; BOARD[i] = 2; } n2--; } n1--; } } /****************************************************/ /* 幅優先探索 (GETTBL[] -> PUTTBL[]) */ /****************************************************/ int Search(u32 GETTBL[], u32 PUTTBL[], int moves) { int count = 0, space, piece, number, i; int pos1, bit1, hash1, pos2, bit2, hash2; u32 bitmap1, bitmap2; /* GETTBL[]を順次呼び込む */ for (pos1=0; pos1>=1) { if (!(bitmap1 & 1)) continue; ChangeBoard(hash1 + bit1); for (space=0; BOARD[space]; space++); /* 新局面生成しPUTTBL[]へ書き出す */ for (i=0; (piece=MOVAL[space][i])!=-1; i++) { number = BOARD[piece]; BOARD[space] = number; BOARD[piece] = 0; hash2 = ChangeNumber(); pos2 = hash2 >> 5; bit2 = hash2 & 0x1F; bitmap2 = BITTBL[bit2]; if (!(SAMEDB[pos2] & bitmap2)) { SAMEDB[pos2] |= bitmap2; PUTTBL[pos2] |= bitmap2; PDB[hash2] = (char)moves; count++; } BOARD[space] = 0; BOARD[piece] = number; } } } return count; } void main_sub(void) { int i, count, hash, moves; /* フラグテーブル初期化 */ for (i=0; i> 5] = BITTBL[hash & 0x1F]; CHECK1[hash >> 5] = BITTBL[hash & 0x1F]; PDB[hash] = 0; printf("%2dmoves:%8d%4dsec\n",moves++, 1, time(NULL)-StartTime); for (;;) { /* CHECK1 -> CHECK2 */ count = Search(CHECK1, CHECK2, moves); if (!count) break; printf("%2dmoves:%8d%4dsec\n",moves++, count, time(NULL)-StartTime); for (i=0; i CHECK1 */ count = Search(CHECK2, CHECK1, moves); if (!count) break; printf("%2dmoves:%8d%4dsec\n",moves++, count, time(NULL)-StartTime); for (i=0; i