C Program |
Crazy Sheep Puzzle |
C Program to Solve Crazy Sheep Puzzle | |
---|---|
#include <stdio.h> typedef enum {W, T, B, G} color; /* W = White, T = Tan, B = Black, G = Gray */ typedef enum {F, R} direct; /* F = Front, R = Rear */ typedef struct { color c[4]; direct d[4]; } P_type; /* one piece */ P_type p[16]; /* 16 pieces */ typedef struct { int piece; /* 0 to 15 */ int orient; /* 0 to 3 */ } B_type; /* piece and orientation */ B_type b[4][4]; /* the board */ int a[16]; /* remaining pieces */ void try (int, int[]); int check(int, int, int); void init_b(void); void print_board(int); void out24(int); int count = 0; void main() { int i; init_b(); for(i = 0; i < 16; i++) a[i] = i; try(16,a); } /* keep trying to place pieces */ void try (int n, int a[16]) { int i; int at[16]; int cp; int co; /* getchar(); printf("Try. n:%2i,a:", n); for(i = 0; i < n; i++) printf("%2i,", a[i]); printf("\n"); */ /* try each remaining piece */ for(cp = 0; cp < n; cp++) { if (n > 1) { for(i = 0; i < cp; i++) at[i] = a[i]; for(i = cp+1; i < n; i++) at[i-1] = a[i]; } for(i = n; i < 16; i++) at[i] = 1000000; /* try each orientation */ for(co = 0; co < 4; co++) { if (check(n, a[cp], co)) { /* count++; if (count < 20) print_board(n); */ /* if (n == 1) print_board(n); else */ if (n <= 1) { print_board(n); } if (n >= 1) try(n-1, at); } } } } /* check that a new placement works */ int check(int n, int ap, int co) { int num = 16 - n; int i = (int) (num / 4); int j = num % 4; int apt, cot; /* getchar(); printf("Check. ap:%2i, co:%2i\n", ap, co); */ b[i][j].piece = ap; b[i][j].orient = co; if (j > 0) { apt = b[i][j-1].piece; cot = b[i][j-1].orient; if (p[ap].c[(3+co)%4] != p[apt].c[(1+cot)%4]) return 0; if (p[ap].d[(3+co)%4] == p[apt].d[(1+cot)%4]) return 0; } if (i > 0) { apt = b[i-1][j].piece; cot = b[i-1][j].orient; if (p[ap].c[(0+co)%4] != p[apt].c[(2+cot)%4]) return 0; if (p[ap].d[(0+co)%4] == p[apt].d[(2+cot)%4]) return 0; } /* printf(" Check:Success! n:%2i, ap:%2i, co:%2i\n", n, ap, co); print_board(n); */ return 1; } | void print_board(int n) { int k, i, j; int c[4]; int minc, minci; int num = 17 - n; c[0] = b[0][0].piece; c[1] = b[0][3].piece; c[2] = b[3][3].piece; c[3] = b[3][0].piece; for (i = 0; i < 4; i++) if (c[i] == 4) c[i] = 2; minc = c[0]; minci = 0; for (i = 1; i < 4; i++) if (c[i] < minc) { minc = c[i]; minci = i; } if ((c[minci] == 2) && (c[(minci+2)%4] == 2)) if ( c[(minci+1)%4] > c[(minci+3)%4] ) minci = (minci+2)%4; for (i = 0; i < 4; i++) printf("%2i ", c[(minci+i)%4]); printf(";"); switch (minci) { case 0: printf("(%2i)", b[0][0].orient); for(i = 0; i < 4; i++) { printf("| "); for(j = 0; j < 4; j++) out24(b[i][j].piece); } break; case 1: printf("(%2i)", (b[0][3].orient+3)%4); for(j = 3;j >= 0; j--) { printf("| "); for(i = 0; i < 4; i++) out24(b[i][j].piece); } break; case 2: printf("(%2i)", (b[3][3].orient+2)%4); for(i = 3;i >= 0; i--) { printf("| "); for(j = 3;j >= 0; j--) out24(b[i][j].piece); } break; case 3: printf("(%2i)", (b[3][0].orient+1)%4); for(j = 0; j < 4; j++) { printf("| "); for(i = 3;i >= 0; i--) out24(b[i][j].piece); } break; } printf("|\n"); } void out24(int n) { if (n == 4) n = 2; printf("%2i ", n); } void init_b(void) { int i; for(i = 0; i < 16; i++) p[i].c[0] = W; for(i = 0; i < 8; i++) { p[i].d[0] = R; p[i].d[2] = F; } for(i = 8; i < 16; i++) { p[i].d[0] = F; p[i].d[2] = R; } for(i = 0; i < 2; i++) { p[i].d[1] = F; p[i].d[3] = R; } for(i = 10; i < 16; i++) { p[i].d[1] = F; p[i].d[3] = R; } for(i = 2; i < 10; i++) { p[i].d[1] = R; p[i].d[3] = F; } p[ 0].c[1] = B; p[ 0].c[2] = T; p[ 0].c[3] = G; p[ 1].c[1] = T; p[ 1].c[2] = G; p[ 1].c[3] = B; p[ 2].c[1] = T; p[ 2].c[2] = B; p[ 2].c[3] = G; p[ 3].c[1] = T; p[ 3].c[2] = G; p[ 3].c[3] = B; p[ 4].c[1] = T; p[ 4].c[2] = B; p[ 4].c[3] = G; p[ 5].c[1] = G; p[ 5].c[2] = B; p[ 5].c[3] = G; p[ 6].c[1] = B; p[ 6].c[2] = G; p[ 6].c[3] = T; p[ 7].c[1] = G; p[ 7].c[2] = B; p[ 7].c[3] = T; p[ 8].c[1] = G; p[ 8].c[2] = T; p[ 8].c[3] = B; p[ 9].c[1] = T; p[ 9].c[2] = B; p[ 9].c[3] = G; p[10].c[1] = T; p[10].c[2] = B; p[10].c[3] = G; p[11].c[1] = T; p[11].c[2] = B; p[11].c[3] = G; p[12].c[1] = G; p[12].c[2] = B; p[12].c[3] = T; p[13].c[1] = G; p[13].c[2] = T; p[13].c[3] = B; p[14].c[1] = B; p[14].c[2] = B; p[14].c[3] = G; p[15].c[1] = T; p[15].c[2] = B; p[15].c[3] = T; } |