#include #include #include #define NONE 0x000 #define LEFT 0x001 #define RIGHT 0x002 #define UP 0x004 #define DOWN 0x008 #define MAX_VALUE 9 #define MAX_DEPTH 3 // ÃÖ´ë Çã¿ë ±íÀÌ #define FIND_NODE 10 #define MAX_STACK 100 #define MAX_NODE 4 // ÃÖ´ë ÀÚ½Ä ³ëµå ¼ö #define TRUE 1 #define FALSE 0 typedef struct _node { int value[9]; // ÆÛÁñ µ¥ÀÌŸ int depth; // ³ëµåÀÇ ±íÀÌ int cursorPosition; // Ä¿¼­ÀÇ ÇöÀç À§Ä¡ int fromDirection; // Ä¿¼­°¡ ¾îµð·ÎºÎÅÍ ¿Ô´Â°¡ struct _node *nextNode[4]; // ÀÚ½Ä ³ëµå ÃÖ´ë 4°³ } PUZZLE; PUZZLE stack[MAX_STACK]; int current_stack; typedef int BOOL; BOOL isFirst; int tempPosition; int callCount; void initialize(PUZZLE *pNode, PUZZLE *gNode); int DFS(PUZZLE *pNode[], PUZZLE *gNode, int pCount, int pDepth); int swapNodeValue(PUZZLE *childNode[], int i, int cursorPosition); int getChildCount(int direction); int comparePuzzle(PUZZLE *pNode, PUZZLE *gNode); int findDirection(PUZZLE *node); void showDirection(PUZZLE *node, int direction); void printCureentNode(); void push(PUZZLE *t); PUZZLE pop(void); int isEmptyStack(void); void initStack(void); int main() { PUZZLE *iPuzzle; PUZZLE *gPuzzle; int i; iPuzzle=(PUZZLE*)malloc(sizeof(PUZZLE)); gPuzzle=(PUZZLE*)malloc(sizeof(PUZZLE)); iPuzzle->value[0]=2; iPuzzle->value[1]=8; iPuzzle->value[2]=3; iPuzzle->value[3]=1; iPuzzle->value[4]=6; iPuzzle->value[5]=4; iPuzzle->value[6]=7; iPuzzle->value[7]=0; iPuzzle->value[8]=5; gPuzzle->value[0]=1; gPuzzle->value[1]=2; gPuzzle->value[2]=3; gPuzzle->value[3]=8; gPuzzle->value[4]=0; gPuzzle->value[5]=4; gPuzzle->value[6]=7; gPuzzle->value[7]=6; gPuzzle->value[8]=5; iPuzzle->depth=0; iPuzzle->fromDirection=NONE; for (i=0; inextNode[i]=NULL; printf("\nSOURCE : "); for (i=0; ivalue[i]); } printf("\nTARGET : "); for (i=0; ivalue[i]); } // ÇÁ·Î±×·¥ ½ÇÇàÈÄ ÃÖÃÊ ÀÚ½Ä ³ëµå »ý¼ºÇϹǷΠTRUE·Î ¼¼Æà isFirst=TRUE; // ½ºÅà ÃʱâÈ­ initStack(); initialize(iPuzzle, gPuzzle); //DFS(pNode, gNode, i, currentDepth); // 0,1,2,3¹ø° ÀÚ½Ä ³ëµå return 1; } void initialize(PUZZLE *pNode, PUZZLE *gNode) { PUZZLE *node[MAX_NODE]; static int currentDepth=0; int cursorPosition; int i,j; int makeChildNumber; printf("\n"); // Ãâ¹ß ³ëµå¿Í ¸ñÇ¥ ³ëµå¸¦ ºñ±³ÇÔ if (comparePuzzle(pNode, gNode) != FIND_NODE) { printf("COULD NOT FIND NODE\n"); } currentDepth=currentDepth+1; // ÇöÀç Ä¿¼­ À§Ä¡¸¦ ã°í, Ä¿¼­°¡ ¿òÁ÷ÀÏ ¼ö ÀÖ´Â ¹æÇâÀ» ¾Ë¾Æ³¿ cursorPosition=findDirection(pNode); tempPosition=cursorPosition; // »ý¼ºÇÒ ¼ö ÀÖ´Â ÀÚ½Ä ³ëµåÀÇ ¼ö¸¦ ±¸ÇÔ makeChildNumber=getChildCount(cursorPosition); printf("\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); // ±íÀÌ Á¦ÇÑ¿¡ µµ´ÞÇÏÁö ¾Ê¾Ò°í, ¸ñÇ¥³ëµå¸¦ ãÁö ¸øÇß´Ù¸é if (currentDepth <= MAX_DEPTH) { for (i=0; idepth=currentDepth; // ºÎ¸ð ³ëµå¸¦ ÀÚ½Ä ³ëµå¿Í ¿¬°á pNode->nextNode[i]=node[i]; // ÀÚ½Ä ³ëµå°¡ °¡¸®Å°°í ÀÖ´Â °ÍÀº NULL node[i]->nextNode[0]=NULL; node[i]->nextNode[1]=NULL; node[i]->nextNode[2]=NULL; node[i]->nextNode[3]=NULL; printf("\nºÎ¸ð[%d]->[%d]¹ø° ÀÚ½ÄÀÇ ÁÖ¼Ò[%d]", pNode, i, node[i]); // »ý¼ºµÈ ÀÚ½Ä ³ëµå¿Í Àӽà ³ëµå¿¡ ºÎ¸ð ³ëµåÀÇ °ªÀ» ÀúÀå for (j=0; jvalue[j]=pNode->value[j]; } swapNodeValue(node, i, cursorPosition); } printf("\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); //printf("\nÇöÀç ±íÀÌ : %d", currentDepth); for (i=0; i%d¹ø° ÀÚ½Ä[%d]³ëµå°ª:", pNode, i, node[i]); for (j=0; jvalue[j]); } printf("[*]ºÎ¸ð[%d]->%d¹ø° ÀÚ½Ä[%d] ±íÀÌ : %d\n", pNode, i, node[i], node[i]->depth); // DFS RECURSIVE DFS(node, gNode, i, currentDepth); // 0,1,2,3¹ø° ÀÚ½Ä ³ëµå } } } int DFS(PUZZLE *pNode[], PUZZLE *gNode, int pCount, int pDepth) { PUZZLE *childNode[MAX_NODE]; int i,j; static int cursorPosition; int exCursorPosition; int makeChildNumber; callCount++; tempPosition=0; printf("--------------------------------------------------------------------\n"); printf(" HOW MANY TIMES CALL DFS FUNCTION : %d\n", callCount); printf("--------------------------------------------------------------------\n"); //printf("ÀÚ½Ä ³ëµå ±íÀÌ : %d\n", pDepth); // ³Ñ°ÜÁ® ¿Â ÀÚ½Ä ³ëµå¿Í ¸ñÇ¥ ³ëµå¸¦ ºñ±³ÇÔ for (i=pCount; i<=pCount; i++) { if (comparePuzzle(pNode[i], gNode) == FIND_NODE) { printf("[#%d NODE] FOUND!\n", i); return 1; } } // ºÎ¸ð ³ëµåÀÇ ÇöÀç Ä¿¼­ À§Ä¡¸¦ ã°í, Ä¿¼­°¡ ¿òÁ÷ÀÏ ¼ö ÀÖ´Â ¹æÇâÀ» ¾Ë¾Æ³¿ cursorPosition=findDirection(pNode[pCount]); tempPosition=cursorPosition; exCursorPosition=cursorPosition; // Exclusive OR ¿¬»êÀ¸·Î ÀÌÀü ³ëµå·ÎºÎÅÍ Ä¿¼­°¡ ¿òÁ÷¿´´ø ¹æÇâÀ¸·Î µÇµ¹¾Æ°¡´Â °ÍÀ» ¹æÁöÇÔ exCursorPosition=cursorPosition^pNode[pCount]->fromDirection; printf("³ëµå[%d]ÀÇ EXCLUSIVE ¿¬»ê ÈÄ Ä¿¼­ À§Ä¡ : %d\n", pNode[pCount], exCursorPosition); // ÇöÀç Ä¿¼­ À§Ä¡¿¡¼­ ¾î´À ¹æÇâÀ¸·Î °¥¼ö ÀÖ´ÂÁö üũÇÔ showDirection(pNode[pCount], cursorPosition); printf("³ëµå[%d]ÀÇ Ä¿¼­°¡ °¥ ¼ö ¾ø´Â ¹æÇâ : %d\n", pNode[pCount], pNode[pCount]->fromDirection); // ±íÀ̸¦ Áõ°¡½ÃÅ°°í pDepth=pDepth++; // »ý¼ºÇÒ ¼ö ÀÖ´Â ÀÚ½Ä ³ëµåÀÇ ¼ö¸¦ ±¸ÇÔ makeChildNumber=getChildCount(exCursorPosition); printf("³ëµå[%d]ÀÇ »ý¼º°¡´É Àڽļö : %d\n", pNode[pCount], makeChildNumber); // ±íÀÌ Á¦ÇÑ¿¡ µµ´ÞÇÏÁö ¾Ê¾ÒÀ¸¸é ÀÚ½Ä ³ëµå ¼º if (pDepth <= MAX_DEPTH) { for (i=0; idepth=pDepth; // ºÎ¸ð ³ëµå¸¦ ÀÚ½Ä ³ëµå¿Í ¿¬°á pNode[pCount]->nextNode[i]=childNode[i]; // ÀÚ½Ä ³ëµå°¡ °¡¸®Å°°í ÀÖ´Â °ÍÀº NULL·Î ÁöÁ¤ childNode[i]->nextNode[0]=NULL; childNode[i]->nextNode[1]=NULL; childNode[i]->nextNode[2]=NULL; childNode[i]->nextNode[3]=NULL; printf("\nºÎ¸ð[%d]->[%d]¹ø° ÀÚ½ÄÀÇ ÁÖ¼Ò[%d]", pNode[pCount], i, childNode[i]); // »ý¼ºµÈ ÀÚ½Ä ³ëµå¿¡ ºÎ¸ð ³ëµåÀÇ °ªÀ» ÀúÀå for (j=0; jvalue[j]=pNode[pCount]->value[j]; //printf("[%d] ",childNode[i]->value[j]); } // ³ëµå¾ÈÀÇ °ªÀ» À̵¿ÇÏ¿© º¯°æ swapNodeValue(childNode, i, cursorPosition); } printf("\n--------------------------------------------------------------------\n"); for (i=0; i[%d]¹ø° ÀÚ½Ä[%d] ³ëµå°ª:", pNode[pCount], i, childNode[i]); for (j=0; jvalue[j]); } printf("ºÎ¸ð[%d]->[%d]¹ø° ÀÚ½Ä[%d] ±íÀÌ: %d\n", pNode[pCount], i, childNode[i], childNode[i]->depth); // DFS RECURSIVE DFS(childNode, gNode, i, pDepth); // 0,1,2,3¹ø° ÀÚ½Ä ³ëµå } } return 0; } // ÀÌ¿ôÇÏ´Â ÆÛÁñ µ¥ÀÌŸ¸¦ ±³È¯Çϱâ À§ÇÑ ÇÔ¼ö int swapNodeValue(PUZZLE *childNode[], int count, int cursorPosition) { PUZZLE *tempNode; int temp1; int temp2; int i; // Àӽà ³ëµå »ý¼º tempNode=(PUZZLE*)malloc(sizeof(PUZZLE)); // Àӽà ³ëµå¿¡ °ªÀ» º¹»ç for (i=0; ivalue[i]=childNode[count]->value[i]; } // Ä¿¼­ À§Ä¡¿Í ±× ÀÌ¿ô¿¡ À§Ä¡ÇÑ °ªÀ» ±³Ã¼ temp1 = tempNode->value[cursorPosition]; if ((tempPosition&LEFT) == LEFT) { temp2 = tempNode->value[cursorPosition-1]; childNode[count]->value[cursorPosition]=temp2; childNode[count]->value[cursorPosition-1]=temp1; childNode[count]->cursorPosition=cursorPosition&LEFT; childNode[count]->fromDirection=RIGHT; // ÀÌ¹Ì ½ÇÇàÇÑ ±¸¹®Àº Skip Çϱâ À§ÇÔÀÓ tempPosition=tempPosition-LEFT; return 0; } else if ((tempPosition&UP) == UP) { temp2 = tempNode->value[cursorPosition-3]; childNode[count]->value[cursorPosition]=temp2; childNode[count]->value[cursorPosition-3]=temp1; childNode[count]->cursorPosition=cursorPosition&UP; childNode[count]->fromDirection=DOWN; tempPosition=tempPosition-UP; return 0; } else if ((tempPosition&RIGHT) == RIGHT) { temp2 = tempNode->value[cursorPosition+1]; childNode[count]->value[cursorPosition]=temp2; childNode[count]->value[cursorPosition+1]=temp1; childNode[count]->cursorPosition=cursorPosition&RIGHT; childNode[count]->fromDirection=LEFT; tempPosition=tempPosition-RIGHT; return 0; } else if ((tempPosition&DOWN) == DOWN) { temp2 = tempNode->value[cursorPosition+3]; childNode[count]->value[cursorPosition]=temp2; childNode[count]->value[cursorPosition+3]=temp1; childNode[count]->cursorPosition=cursorPosition&DOWN; childNode[count]->fromDirection=UP; tempPosition=tempPosition-DOWN; return 0; } return 0; } // »ý¼ºÇÒ ¼ö ÀÖ´Â ÀÚ½Ä ³ëµåÀÇ ¼ö¸¦ ±¸Çϱâ À§ÇÑ ÇÔ¼ö int getChildCount(int direction) { int makeChildCount; // »ý¼º ÇÒ ¼ö ÀÖ´Â ÀÚ½Ä ³ëµåÀÇ ¼ö¸¦ ±¸Çϱâ À§ÇØ Ã¼Å© if (direction == 1 || direction == 2 || direction == 4 || direction == 8) makeChildCount=1; else if (direction == 3 || direction == 5 || direction == 6 || direction == 9 || direction == 10 || direction == 12) makeChildCount=2; else if (direction == 7 || direction == 11 || direction == 13 || direction == 14) makeChildCount=3; else if (direction == 15) makeChildCount=4; return makeChildCount; } // ÇöÀç Ä¿¼­ÀÇ À§Ä¡¸¦ ±¸ÇÔ int findDirection(PUZZLE *node) { int direction; int i; for (i=0; ivalue[i] == 0) { direction=i; printf("³ëµå[%d]ÀÇ Ä¿¼­ À§Ä¡ : %d\n", node, direction); break; } } if ((i/3) == 0) { direction=DOWN; } else if ((i/3) == 1) { direction=UP | DOWN; } else if ((i/3) == 2) { direction=UP; } if ((i%3) == 0) { direction=direction | RIGHT; } else if ((i%3) == 1) { direction=direction | LEFT | RIGHT; } else if ((i%3) == 2) { direction=direction | LEFT; } return direction; } // Ãâ¹ß ³ëµå¿Í ¸ñÇ¥ ³ëµå¸¦ ºñ±³ÇÔ int comparePuzzle(PUZZLE *pNode, PUZZLE *gNode) { int i; for (i=0; ivalue[i] != gNode->value[i]) return -1; } if (i == 9) return FIND_NODE; return 0; } // Ä¿¼­°¡ ¿òÁ÷ÀÏ ¼ö ÀÖ´Â ¹æÇâÀ» Ç¥½Ã void showDirection(PUZZLE *node, int direction) { switch(direction) { case 1 : printf("³ëµå[%d]ÀÇ Ä¿¼­ À§Ä¡·ÎºÎÅÍ ¿òÁ÷Àϼö ÀÖ´Â ¹æÇâ : LEFT\n", node); break; case 2 : printf("³ëµå[%d]ÀÇ Ä¿¼­ À§Ä¡·ÎºÎÅÍ ¿òÁ÷Àϼö ÀÖ´Â ¹æÇâ : RIGHT\n", node); break; case 3 : printf("³ëµå[%d]ÀÇ Ä¿¼­ À§Ä¡·ÎºÎÅÍ ¿òÁ÷Àϼö ÀÖ´Â ¹æÇâ : LEFT | RIGHT\n", node); break; case 4 : printf("³ëµå[%d]ÀÇ Ä¿¼­ À§Ä¡·ÎºÎÅÍ ¿òÁ÷Àϼö ÀÖ´Â ¹æÇâ : UP\n", node); break; case 5 : printf("³ëµå[%d]ÀÇ Ä¿¼­ À§Ä¡·ÎºÎÅÍ ¿òÁ÷Àϼö ÀÖ´Â ¹æÇâ : LEFT | UP\n", node); break; case 6 : printf("³ëµå[%d]ÀÇ Ä¿¼­ À§Ä¡·ÎºÎÅÍ ¿òÁ÷Àϼö ÀÖ´Â ¹æÇâ : RIGHT | UP\n", node); break; case 7 : printf("³ëµå[%d]ÀÇ Ä¿¼­ À§Ä¡·ÎºÎÅÍ ¿òÁ÷Àϼö ÀÖ´Â ¹æÇâ : LEFT | RIGHT | UP\n", node); break; case 8 : printf("³ëµå[%d]ÀÇ Ä¿¼­ À§Ä¡·ÎºÎÅÍ ¿òÁ÷Àϼö ÀÖ´Â ¹æÇâ : DOWN\n", node); break; case 9 : printf("³ëµå[%d]ÀÇ Ä¿¼­ À§Ä¡·ÎºÎÅÍ ¿òÁ÷Àϼö ÀÖ´Â ¹æÇâ : LEFT | DOWN\n", node); break; case 10 : printf("³ëµå[%d]ÀÇ Ä¿¼­ À§Ä¡·ÎºÎÅÍ ¿òÁ÷Àϼö ÀÖ´Â ¹æÇâ : RIGHT | DOWN\n", node); break; case 11 : printf("³ëµå[%d]ÀÇ Ä¿¼­ À§Ä¡·ÎºÎÅÍ ¿òÁ÷Àϼö ÀÖ´Â ¹æÇâ : LEFT | RIGHT | DOWN\n", node); break; case 12 : printf("³ëµå[%d]ÀÇ Ä¿¼­ À§Ä¡·ÎºÎÅÍ ¿òÁ÷Àϼö ÀÖ´Â ¹æÇâ : UP | DOWN\n", node); break; case 13 : printf("³ëµå[%d]ÀÇ Ä¿¼­ À§Ä¡·ÎºÎÅÍ ¿òÁ÷Àϼö ÀÖ´Â ¹æÇâ : LEFT | UP | DOWN\n", node); break; case 14 : printf("³ëµå[%d]ÀÇ Ä¿¼­ À§Ä¡·ÎºÎÅÍ ¿òÁ÷Àϼö ÀÖ´Â ¹æÇâ : RIGHT | UP | DOWN\n", node); break; case 15 : printf("³ëµå[%d]ÀÇ Ä¿¼­ À§Ä¡·ÎºÎÅÍ ¿òÁ÷Àϼö ÀÖ´Â ¹æÇâ : LEFT | RIGHT | UP | DOWN\n", node); break; } } void printCurrentNode() { int i; printf("\n"); for(i=0;i<9;i++){ printf("%d\t", stack[current_stack-1].value[i]); } } void push(PUZZLE *t) { if (current_stack >= MAX_STACK -1) { printf("\nStack Overflow!\n"); exit(1); } else stack[current_stack] = *t; current_stack++; } PUZZLE pop(void) { PUZZLE ptr; if (current_stack < 0) { printf("\nStack Underflow\n"); exit(1); } else { ptr=stack[current_stack]; current_stack--; } return ptr; } void initStack(void) { current_stack=-1; } int isEmptyStack(void) { return (current_stack == -1); }