반응형
예전에 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 |