/*****************************************************************************/ /* PENTOMINO(6*10) with Breadth First Search 2001/02/05 by takaken */ /*****************************************************************************/ /* BOARD MAP ( 0)( 1)( 2)( 3)( 4)( 5)( 6) 7 8 9 10 11 12 (13) 14 15 16 17 18 19 (20) | 63 64 65 66 67 68 (69) 70 71 72 73 74 75 (76) (77)(78)(79)(80)(81)(82) */ #include #include #include #define FALSE 0 #define TRUE 1 #define SPACE 0 #define WALL 1 #define SILHOUETTE 2 #define BOX 3 #define BOARD_SIZE 83 #define XSIZE 7 #define BUCKET_SIZE 60013 typedef unsigned long ulong; typedef struct bucket { int result_count; long silhouette; short used_piece; struct bucket *link; } bucket_t; bucket_t BUCKET[BUCKET_SIZE]; bucket_t *HEADER[BOARD_SIZE]; int ResultCount; int BucketCount, MaxBucket; int PaintCode, PaintCount; int PAINT[BOARD_SIZE]; int BOARD[BOARD_SIZE]; int DIFF[4] = {-XSIZE, 1, XSIZE, -1}; int INDEX[12]; int PIECE[12][8][4] = { 1, 2, 3, 4, /* □□□□□ */ 7,14,21,28, /*       */ 0, 0, 0, 0, /*       */ 0, 0, 0, 0, /*       */ 0, 0, 0, 0, /*       */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 7, /* □□□□  */ 1, 2, 3,10, /* □     */ 1, 7,14,21, /*       */ 1, 8,15,22, /*       */ 4, 5, 6, 7, /*       */ 7, 8, 9,10, 7,14,20,21, 7,14,21,22, 1, 2, 3, 8, /* □□□□  */ 1, 2, 3, 9, /*  □    */ 5, 6, 7, 8, /*       */ 6, 7, 8, 9, /*       */ 6, 7,14,21, /*       */ 7, 8,14,21, 7,13,14,21, 7,14,15,21, 1, 2, 6, 7, /*  □□□  */ 1, 2, 9,10, /* □□    */ 1, 5, 6, 7, /*       */ 1, 8, 9,10, /*       */ 6, 7,13,20, /*       */ 7, 8,15,22, 7,13,14,20, 7,14,15,22, 1, 2, 7, 8, /* □□□   */ 1, 2, 8, 9, /* □□    */ 1, 6, 7, 8, /*       */ 1, 7, 8, 9, /*       */ 1, 7, 8,14, /*       */ 1, 7, 8,15, 6, 7,13,14, 7, 8,14,15, 1, 2, 7, 9, /* □□□   */ 1, 7,14,15, /* □ □   */ 1, 8,14,15, /*       */ 2, 7, 8, 9, /*       */ 0, 0, 0, 0, /*       */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 7,14, /* □□□   */ 1, 2, 9,16, /* □     */ 7,12,13,14, /* □     */ 7,14,15,16, /*       */ 0, 0, 0, 0, /*       */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 8,15, /* □□□   */ 5, 6, 7,14, /*  □    */ 7, 8, 9,14, /*  □    */ 7,13,14,15, /*       */ 0, 0, 0, 0, /*       */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 7,13, /*  □□   */ 1, 8, 9,16, /* □□    */ 6, 7,12,13, /* □     */ 7, 8,15,16, /*       */ 0, 0, 0, 0, /*       */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 7,14, /*  □□   */ 1, 8, 9,15, /* □□    */ 5, 6, 7,13, /*  □    */ 6, 7, 8,13, /*       */ 6, 7, 8,15, /*       */ 6, 7,14,15, 7, 8, 9,15, 7, 8,13,14, 1, 7,13,14, /*  □□   */ 1, 8,15,16, /*  □    */ 5, 6, 7,12, /* □□    */ 7, 8, 9,16, /*       */ 0, 0, 0, 0, /*       */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /******** SPECIAL PIECE ********/ 6, 7, 8,14, /*  □    */ 0, 0, 0, 0, /* □□□   */ 0, 0, 0, 0, /*  □    */ 0, 0, 0, 0, /*       */ 0, 0, 0, 0, /*       */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /*****************************************************************************/ /* Debug ( Display ) */ /*****************************************************************************/ void Display() { int i; system("cls"); printf("BucketCount = %d\n", BucketCount); printf("ResultCount = %d ", ResultCount); for (i=0; iused_piece | bit); if (used_piece == 0x7FF) { ResultCount += this_bucket->result_count; return; } /* start_space */ while (BOARD[start_space]) start_space++; /* Cut of Branch */ if (!PaintCheck(start_space)) return; if (!FrontCheck(start_space, used_piece, 0)) return; /* silhouette */ pos = start_space + 27; if (pos > 75) pos = 75; for (silhouette=0; pos>start_space; pos--) { silhouette <<= 1; if (BOARD[pos] >= SILHOUETTE) silhouette |= 1; } /* HASH FUNC */ hash = (used_piece * 37 + silhouette) % BUCKET_SIZE; /* POINTER */ for (;;) { next_bucket = &BUCKET[hash]; if (next_bucket->result_count == 0) break; if (next_bucket->used_piece==used_piece && next_bucket->silhouette==silhouette) { next_bucket->result_count += this_bucket->result_count; return; } hash = (hash + 491) % BUCKET_SIZE; } /* BUCKET IN */ if (BucketCount >= (BUCKET_SIZE * 4 / 5)) { printf("BUCKET FULL\n"); exit(1); } if (++BucketCount > MaxBucket) MaxBucket = BucketCount; next_bucket->result_count = this_bucket->result_count; next_bucket->used_piece = used_piece; next_bucket->silhouette = silhouette; next_bucket->link = HEADER[start_space]; HEADER[start_space] = next_bucket; } /*****************************************************************************/ /* Breadth First Search */ /*****************************************************************************/ void Search(char start_space) { int pos, i, j, k, index, *piece, pos_table[4]; short bit; long silhouette; bucket_t *this_bucket; for (;;) { /* BUCKET OUT */ if ((this_bucket = HEADER[start_space]) == NULL) break; HEADER[start_space] = this_bucket->link; /* PUT SILHOUETTE */ silhouette = this_bucket->silhouette; for (pos=start_space+1; silhouette; pos++, silhouette>>=1) if (silhouette & 1) BOARD[pos] = SILHOUETTE; /* ADD PIECE */ for (bit=1, i=0; i<11; i++, bit<<=1) { if (this_bucket->used_piece & bit) continue; index = INDEX[i]; for (j=0; jsilhouette; for (pos=start_space+1; silhouette; pos++, silhouette>>=1) if (silhouette & 1) BOARD[pos] = SPACE; /* RELEASE FROM BUCKET */ this_bucket->result_count = 0; /* EMPTY */ BucketCount--; } } /*****************************************************************************/ /* Pentomino */ /*****************************************************************************/ void Pentomino() { int i; char start_space; bucket_t *start_bucket; /* INITIALIZE */ for (i=0; iresult_count = 1; start_bucket->used_piece = 0; start_bucket->silhouette = 0; start_bucket->link = NULL; HEADER[start_space] = start_bucket; BucketCount = 1; /* SEARCH */ for (start_space=7; start_space