/*------------------------------------------------*/ /* Copyright(C) T.Nakamura 2001 */ /* E-Mail: nakamura@tokyo.email.ne.jp */ /*------------------------------------------------*/ /* hexomino */ /* */ /* usage : hex */ /* */ /*------------------------------------------------*/ #include #include #include #include /*------------------------*/ /* define constant */ /*------------------------*/ #define PIECE_NO 35 #define PIECE_CELL_NO 6 #define PIECE_DIRECTION 8 #define UNUSE 0 #define USE 1 #define INHIBIT -1 #define VACANT 0 #define VACANT_FLAG 99999 #define MAX_X 21 #define MAX_Y 15 #define GOOD 0 #define NG 1 #define RAND_INIT 123 #define SHUFFLE_PIECE_ORDER 40 #define SHUFFLE_PIECE_DIR 5 #define REQUIRE_SOLUTION 1000000 #define DISPLAY_INTERVAL 2 #define CHANGE_APPROCH_COL 1 #define LEFT15 1 /*------------------------*/ /* external variable */ /*------------------------*/ int board[MAX_X][MAX_Y]; #if LEFT15 int use_piece[] = { 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0 }; #else int use_piece[PIECE_NO]; #endif int seq_no; int size_x; int size_y; clock_t t1,t2; /*------------------------*/ void display(void); struct piece_s { int x; int y; }; struct piece_org_s { struct piece_s piece[PIECE_CELL_NO]; }; void copy_piece(struct piece_org_s *target, struct piece_org_s *source) { int i; for (i=0; ipiece[i].x = source->piece[i].x; target->piece[i].y = source->piece[i].y; } } void mirror_piece(struct piece_org_s *target, struct piece_org_s *source) { int i; for (i=0; ipiece[i].x = source->piece[i].x; target->piece[i].y = -(source->piece[i].y); } } void rotate_piece(struct piece_org_s *target) { int i; int tmp; for (i=0; ipiece[i].x; target->piece[i].x = -(target->piece[i].y); target->piece[i].y = tmp; } } int sort_piece(struct piece_s *a, struct piece_s *b) { if (a->x > b->x) return(1); else if (a->x == b->x) { if (a->y > b->y) return(1); } return(-1); } int sort_piece2(struct piece_s *a, struct piece_s *b) { if (a->y > b->y) return(1); else if (a->y == b->y) { if (a->x > b->x) return(1); } return(-1); } void origin_piece(struct piece_org_s *target, int p) { int i; if (p==0) qsort(&(target->piece[0]),PIECE_CELL_NO,sizeof(struct piece_s), sort_piece); else qsort(&(target->piece[0]),PIECE_CELL_NO,sizeof(struct piece_s), sort_piece2); for (i=PIECE_CELL_NO-1; i>=0; i--) { target->piece[i].x -= target->piece[0].x; target->piece[i].y -= target->piece[0].y; } /** printf("%d :",i); for (i=0; ipiece[i].x,target->piece[i].y); } printf("\n"); **/ } struct piece_x { int no; struct { int x[PIECE_CELL_NO-1]; int y[PIECE_CELL_NO-1]; } type[PIECE_DIRECTION]; } piece[2][PIECE_NO]; void entry_piece(int piece_no,struct piece_org_s *target) { int p; int i; int same; int no; for (p=0; p<2; p++) { origin_piece(target,p); /*** DEBUG printf("%d :",i); for (i=0; ipiece[i].x,target->piece[i].y); } printf("\n"); ***/ same = 0; for (i=0; ipiece[1].x && piece[p][piece_no].type[i].y[0] == target->piece[1].y && piece[p][piece_no].type[i].x[1] == target->piece[2].x && piece[p][piece_no].type[i].y[1] == target->piece[2].y && piece[p][piece_no].type[i].x[2] == target->piece[3].x && piece[p][piece_no].type[i].y[2] == target->piece[3].y && piece[p][piece_no].type[i].x[3] == target->piece[4].x && piece[p][piece_no].type[i].y[3] == target->piece[4].y && piece[p][piece_no].type[i].x[4] == target->piece[5].x && piece[p][piece_no].type[i].y[4] == target->piece[5].y) { same = 1; break; } } if (same == 0) { no = piece[p][piece_no].no++; for (i=0; ipiece[1+i].x; piece[p][piece_no].type[no].y[i] = target->piece[1+i].y; } } } } void dump_piece() { int i,j,k,m,p; int posx,posy; size_x = 9; size_y = 12; /*** init board ***/ for (i=0; i0) rotate_piece(&piece_tmp); entry_piece(i,&piece_tmp); } } } #if !LEFT15 change_piece_order(); #endif /*** Dump ***/ /*** for (p=0;p<2;p++) { for (i=0; i0) printf("%s\n",lp1); printf("%s\n",lp2); } // printf("\n\n"); fflush(stdout); } int blank_no; /*------------------------*/ /* check_blank_area */ /*------------------------*/ void search_blank(int x,int y) { board[x][y] = VACANT_FLAG; blank_no++; if (board[x][y+1]==VACANT) search_blank(x,y+1); if (board[x+1][y]==VACANT) search_blank(x+1,y); if (board[x-1][y]==VACANT) search_blank(x-1,y); if (board[x][y-1]==VACANT) search_blank(x,y-1); } void search_blank_clear(int x,int y) { while(x<=size_x) { while(y<=size_y) { if (board[x][y]==VACANT_FLAG) board[x][y] = VACANT; y++; } y = 1; x++; } } void search_blank_clear2(int x,int y) { while(y<=size_y) { while(x<=size_x) { if (board[x][y]==VACANT_FLAG) board[x][y] = VACANT; x++; } x = CHANGE_APPROCH_COL; y++; } } /*------------------------*/ /* check_board */ /*------------------------*/ int check_board(int x,int y,int p) { if (p==0) { if (board[x+1][y]!=0 && board[x][y+1]!=0) return NG; if (board[x][y+2]!=0 && board[x+1][y+1]!=0 && board[x+1][y]!=0) return NG; if (board[x][y+1]!=0 && board[x+1][y+1]!=0 && board[x+2][y]!=0 && board[x+1][y-1]!=0) return NG; blank_no =0; search_blank(x,y); search_blank_clear(x,y); } else { if (board[x+1][y]!=0 && board[x][y+1]!=0) return NG; if (board[x+2][y]!=0 && board[x+1][y+1]!=0 && board[x][y+1]!=0) return NG; if (board[x+1][y]!=0 && board[x+1][y+1]!=0 && board[x][y+2]!=0 && board[x-1][y+1]!=0) return NG; blank_no =0; search_blank(x,y); search_blank_clear2(x,y); } // printf("blank %d\n", blank_no); if (blank_no%PIECE_CELL_NO!=0) return NG; return GOOD; } void dump_usepiece() { int i; printf("use_piece\n"); for (i=0;isize_y) { posy = 1; posx++; if (posx>=CHANGE_APPROCH_COL) { p = 1; break; } } } } if (p==1) { while(board[posx][posy]!=VACANT) { posx++; if (posx>size_x) { posx = CHANGE_APPROCH_COL; posy++; } } } //printf("posx, y %d %d\n", posx, posy); /** check board **/ if (check_board(posx, posy,p)) return; // disp_piece(); getch(); //display(); for (i=0; i20) display(); **/ /*** search next piece place ***/ if (p==0) search(posx,posy+1,put_no+1,p); else search(posx+1,posy,put_no+1,p); use_piece[i] = UNUSE; } else { /*** display ***/ //printf("seq_no %d\n", seq_no); seq_no++; //printf("seq_no %d\n", seq_no); if (seq_no%DISPLAY_INTERVAL==0 || seq_no==1) display(); if (seq_no>REQUIRE_SOLUTION-1) exit(0); } /*** get last piece ***/ board[posx][posy] = board[piece[p][i].type[j].x[0]+posx] [piece[p][i].type[j].y[0]+posy] = board[piece[p][i].type[j].x[1]+posx] [piece[p][i].type[j].y[1]+posy] = board[piece[p][i].type[j].x[2]+posx] [piece[p][i].type[j].y[2]+posy] = board[piece[p][i].type[j].x[3]+posx] [piece[p][i].type[j].y[3]+posy] = board[piece[p][i].type[j].x[4]+posx] [piece[p][i].type[j].y[4]+posy] = VACANT; } } /* end of for-j loop */ } /* end of unuse if (unuse piece) */ } /* end of for-i loop */ return; } /* end of search */ /*------------------------*/ /* initialize */ /*------------------------*/ void init(void) { int i,j; /*** set area type ***/ size_x = 19; size_y = 12; /*** init counter ***/ seq_no = 0; /*** init board ***/ for (i=0; i