반응형
예전에 C로 구현한 파일입출력 기반의 Yes or No 아키네이터이다. 컴퓨터가 모르는 부분에 다다르면 직접 사용자가 알려줄 수 있다.
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct node { char *obj_name; char *question; struct node *yes_ptr; struct node *no_ptr; } Node; void nodePrint(Node *n); // 노드의 정보를 출력하며 게임을 진행하는 함수 void treeSave(Node *n); // 트리의 정보를 텍스트 파일에 저장하는 함수 Node * treeRead(Node *n); // 텍스트 파일에서 트리의 정보를 읽어 저장하는 함수 (트리 초기화) Node * insertNode(Node *n, char *NodeObj); // 노드를 삽입하는 함수 (컴퓨터가 모르는 정보를 알려줄 때) void deleteTree(Node *n); // 모든 노드를 free하는 함수 void treePrint(Node *n); // 1D 부분함수 Node *n; int main() { int loop = 1; char answer[100]; n = treeRead(n); while (loop) { printf("OK, please think of something.\n"); nodePrint(n); while (1) { // YES나 NO가 아닐 경우를 대비하여 무한루프로 YES나 NO일 때까지 받음 printf("Would you like to play again?\n"); printf(">"); gets(answer); if (strcmp(strupr(answer), "YES") == 0) { loop = 1; break; } else if (strcmp(strupr(answer), "NO") == 0) { loop = 0; break; } else { printf("Yes or No로 대답해주세요.\n"); } } } treeSave(n); deleteTree(n); return 0; } void nodePrint(Node *n) { char answer[100]; char obj[100]; if (n == NULL) { // 아무것도 없으면 정답이 뭔지 질문 printf("Oh. Well you win then -- What were you thinking of?\n"); } else { if (n->question != NULL) { // 질문이 비어있지 않으면 질문출력 printf("%s\n", n->question); while (1) { printf(">"); gets(answer); if (strcmp(strupr(answer), "YES") == 0) { nodePrint(n->yes_ptr); // YES일 때 yes_ptr로 노드 이동 break; } else if (strcmp(strupr(answer), "NO") == 0) { nodePrint(n->no_ptr); // NO일 떄 no_ptr로 노드 이동 break; } else { printf("Yes or No로 대답해주세요.\n"); } } } else { // 질문이 비어있으면 obj가 맞는지 확인 printf("Is it a %s?\n", n->obj_name); while (1) { printf(">"); gets(answer); if (strcmp(strupr(answer), "YES") == 0) { printf("Good. That was soooo easy\n"); // 컴퓨터가 이김 break; } else if (strcmp(strupr(answer), "NO") == 0) { insertNode(n, n->obj_name); // 플레이어가 이김, 정답에 대한 질문 printf("Thanks.\n\n"); break; } else { printf("Yes or No로 대답해주세요.\n"); } } } } } // 1D 부분 void treePrint(Node *n) { if (n != NULL) { if (n->question != NULL) { printf("question: %s\nobject: NOTHING\n", n->question); } else { printf("question: NOTHING\nobject: %s\n", n->obj_name); } printf("YES: "); if (n->yes_ptr->question != NULL) { printf("%s\n", n->yes_ptr->question); } else { printf("%s\n", n->yes_ptr->obj_name); } printf("NO: "); if (n->no_ptr->question != NULL) { printf("%s\n", n->no_ptr->question); } else { printf("%s\n", n->no_ptr->obj_name); } treePrint(n->yes_ptr); treePrint(n->no_ptr); } } void treeSave(Node *n) { FILE *f; f = fopen("test.txt", "w"); fprintf(f, ""); // 텍스트 파일 기존에 있는거 다 지움 fclose(f); f = fopen("test.txt", "a"); if (n != NULL) { // 저장 if (n->question != NULL) { printf("question: %s\n", n->question); fprintf(f, "question: %s\n", n->question); } else { printf("object: %s\n", n->obj_name); fprintf(f, "object: %s\n", n->obj_name); } treeSave(n->yes_ptr); treeSave(n->no_ptr); } } Node * treeRead(Node *n) { FILE *f; char tmp[201]; int i; static int c = 1; // 몇번쨰 줄을 읽을지 정하는 변수 : c번째 줄을 읽음 f = fopen("test.txt", "r"); if (f == NULL) { return NULL; } else { n = (Node *)malloc(sizeof(Node)); for (i = 0; i < c; i++) fgets(tmp, 201, f); if ( tmp == NULL ) n = NULL; // 줄에 아무것도 없으면 빈 노드 else if (strstr(tmp, "question:")) { // 질문일 떄 n->question = (char *)malloc(sizeof(char) * strlen(tmp)); n->obj_name = NULL; strcpy(n->question, tmp + 10); n->question[strlen(n->question) - 1] = 0; // 끝에 개행문자 지움 c++; n->yes_ptr = treeRead(n->yes_ptr); // yes_ptr로 노드 초기화 c++; n->no_ptr = treeRead(n->no_ptr); // no_ptr로 노드 초기화 } else { // 오브젝트일 떄 n->question = NULL; n->obj_name = (char *)malloc(sizeof(char) * strlen(tmp)); strcpy(n->obj_name, tmp + 8); n->obj_name[strlen(n->obj_name) - 1] = 0; // 끝에 개행문자 지움 n->yes_ptr = n->no_ptr = NULL; // 오브젝트만 남으면 이 노드는 제일 끝에 있는 노드이므로 뒤에 노드 없음 } } return n; fclose(f); } Node * insertNode(Node *n, char *NodeObj) { char obj[200]; char tmp[200]; char question[300]; char answer[100]; strcpy(tmp, NodeObj); printf("Oh. well you win then -- What were you thinking of?\n"); printf(">"); gets(obj); while (1) { printf("Please give me a question about %s, so I can tell the difference between %s and a %s\n", obj, obj, NodeObj); printf(">"); gets(question); if (strstr(question, "?")) break; else printf("물음표 넣어서 대답해주세요.\n"); } while (1) { printf("What is the answer for %s?\n", obj); printf(">"); gets(answer); if (strcmp(strupr(answer), "YES") == 0) { break; } else if (strcmp(strupr(answer), "NO") == 0) { break; } else printf("Yes or No로 대답해주세요.\n"); } n->question = (char *)malloc(sizeof(char) * (strlen(question) + 1)); strcpy(n->question, question); free(n->obj_name); n->obj_name = NULL; if (strcmp(strupr(answer), "YES") == 0) { // 플레이어가 알려준 오브젝트에 대한 정답이 YES일때 n->yes_ptr = (Node *)malloc(sizeof(Node)); n->yes_ptr->question = NULL; n->yes_ptr->obj_name = (char *)malloc(sizeof(char) * (strlen(obj) + 1)); strcpy(n->yes_ptr->obj_name, obj); n->no_ptr = (Node *)malloc(sizeof(Node)); n->no_ptr->question = NULL; n->no_ptr->obj_name = (char *)malloc(sizeof(char) * (strlen(tmp) + 1)); strcpy(n->no_ptr->obj_name, tmp); } else { // 플레이어가 알려준 오브젝트에 대한 정답이 NO일때 n->no_ptr = (Node *)malloc(sizeof(Node)); n->no_ptr->question = NULL; n->no_ptr->obj_name = (char *)malloc(sizeof(char) * (strlen(obj) + 1)); strcpy(n->no_ptr->obj_name, obj); n->yes_ptr = (Node *)malloc(sizeof(Node)); n->yes_ptr->question = NULL; n->yes_ptr->obj_name = (char *)malloc(sizeof(char) * (strlen(tmp) + 1)); strcpy(n->yes_ptr->obj_name, tmp); } n->yes_ptr->yes_ptr = n->yes_ptr->no_ptr = NULL; n->no_ptr->yes_ptr = n->no_ptr->no_ptr = NULL; return n; } void deleteTree(Node *n) { if (n == NULL) return; else { if (n->obj_name != NULL) free(n->obj_name); else free(n->question); deleteTree(n->yes_ptr); deleteTree(n->no_ptr); } }
반응형
'C, C++ > 과제창고' 카테고리의 다른 글
[C] 단일연결리스트 합병정렬 (singly linked list merge sort) (0) | 2018.10.14 |
---|---|
[C] 학교과제_황제노드찾기 (0) | 2018.07.01 |