/*---------------------------------------------------*/ /* 3D Pentomino Solver */ /* */ /* usage : pento [ x y z ] */ /* */ /* default ... "4 3 5" */ /* */ /* 注)Iピースによる重複排除は 4 3 5のときのみ。 */ /* PIC用データ出力時は #define PICDATA を有効化。*/ /* */ /* 2008.3.28 T.Nakamura (c) */ /*---------------------------------------------------*/ #include #include #include // #define PICDATA /*------------------------*/ /* define constant */ /*------------------------*/ #define PIECE_NO 12 #define UNUSE 0 #define USE 1 #define INHIBIT -1 #define EMPTY 0 #define MAX_X 7 #define MAX_Y 7 #define MAX_Z 12 /*------------------------*/ /* external variable */ /*------------------------*/ int eval_cnt,eval_cnt_m; char board[MAX_X][MAX_Y][MAX_Z]; struct board_piece_s { int no; struct piece3d_xyz_s* type[24]; } board_piece[PIECE_NO][MAX_X][MAX_Y][MAX_Z]; int use_piece[PIECE_NO]; int seq_no; int size_x; int size_y; int size_z; int blank_no; static char piece_char[13] = { '.', 'I', 'L', 'T', 'U', 'f', 'W', 'y', 'N', 'X', 'V', 'P', 'Z'}; clock_t ts,te; struct piece_stak_s { int type; int x[5],y[5],z[5]; } piece_stack[12]; int stackp; /*------------------------*/ /* display result */ /*------------------------*/ void display() { #define MAX_COL 85 char lp1[MAX_COL]; char lp2[MAX_COL]; int x,y,z,i,j,p; char t; printf(" seq_no=%d eval_cnt=%d(M)\n",seq_no,eval_cnt_m); for (z=1; z<=size_z; z++) { for (y=0; y<=size_y; y++) { for(x=0; x0) printf("%s\n",lp1); printf("%s\n",lp2); } } printf("\n\n"); #ifdef PICDATA for (i=0;ipos[0].x+posx] [bp->pos[0].y+posy] [bp->pos[0].z+posz]==EMPTY && board[bp->pos[1].x+posx] [bp->pos[1].y+posy] [bp->pos[1].z+posz]==EMPTY && board[bp->pos[2].x+posx] [bp->pos[2].y+posy] [bp->pos[2].z+posz]==EMPTY && board[bp->pos[3].x+posx] [bp->pos[3].y+posy] [bp->pos[3].z+posz]==EMPTY) return 1; return 0; } void put_get_piece(int i, int j, int posx, int posy, int posz, int piece_no) { struct piece3d_xyz_s* bp; bp = board_piece[i][posx][posy][posz].type[j]; board[posx][posy][posz] = board[bp->pos[0].x+posx] [bp->pos[0].y+posy] [bp->pos[0].z+posz] = board[bp->pos[1].x+posx] [bp->pos[1].y+posy] [bp->pos[1].z+posz] = board[bp->pos[2].x+posx] [bp->pos[2].y+posy] [bp->pos[2].z+posz] = board[bp->pos[3].x+posx] [bp->pos[3].y+posy] [bp->pos[3].z+posz] = piece_no; #ifdef PICDATA if (piece_no!=EMPTY) { piece_stack[stackp].type = piece_no; piece_stack[stackp].x[0] = posx; piece_stack[stackp].y[0] = posy; piece_stack[stackp].z[0] = posz; piece_stack[stackp].x[1] = bp->pos[0].x+posx; piece_stack[stackp].y[1] = bp->pos[0].y+posy; piece_stack[stackp].z[1] = bp->pos[0].z+posz; piece_stack[stackp].x[2] = bp->pos[1].x+posx; piece_stack[stackp].y[2] = bp->pos[1].y+posy; piece_stack[stackp].z[2] = bp->pos[1].z+posz; piece_stack[stackp].x[3] = bp->pos[2].x+posx; piece_stack[stackp].y[3] = bp->pos[2].y+posy; piece_stack[stackp].z[3] = bp->pos[2].z+posz; piece_stack[stackp].x[4] = bp->pos[3].x+posx; piece_stack[stackp].y[4] = bp->pos[3].y+posy; piece_stack[stackp].z[4] = bp->pos[3].z+posz; stackp++; } else { stackp--; } #endif } int check_pos(int x,int y,int z) { if (board[x][y+1][z]!=0 && board[x+1][y][z]!=0 && board[x][y][z+1]!=0) return 1; return 0; } void search(int posx,int posy,int posz,int put_no) { int i,j; struct piece3d_xyz_s* bp; while(board[posx][posy][posz]!=0) { posx++; if (posx>size_x) { posx = 1; posy++; if (posy>size_y) { posy = 1; posz++; } } } /** check board **/ if (check_pos(posx,posy,posz)) return; for (i=0; i1000000) { eval_cnt = 0; eval_cnt_m++; } if (check_board(i,j,posx,posy,posz)) { put_get_piece(i,j,posx,posy,posz,i+1); if (put_no!=PIECE_NO) { use_piece[i] = USE; /*** search next piece place ***/ search(posx+1,posy,posz,put_no+1); use_piece[i] = UNUSE; } else { /*** display ***/ seq_no++; display(); } /*** get last piece ***/ put_get_piece(i,j,posx,posy,posz,EMPTY); } } /* end of for-j loop */ } /* end of unuse if (unuse piece) */ } /* end of for-i loop */ } /* end of search */ int sort_piece3d( struct xyz_s *a, struct xyz_s *b) //int sort_piece3d( const void *a, const void *b) { if (a->x > b->x) return(1); else if (a->x == b->x) { if (a->y > b->y) return(1); else if (a->y == b->y) { if (a->z > b->z) return(1); } } return(-1); } void make_piece3d() { int x,y,z; int i,j,k,m,jj,jj0,r,diff; int min_z,min_y; int piece_data_no; for (i=0;i