Собственно, буквально за несколько дней до того как Белокрылов
привел нам пример экспертной системы, которая угадывает слово
по принципу ответа да/нет, мой начальник на работе показал
мне очень похожую прогу, написанную им самим и предложенную как
альтернатива зачёту в одной из групп ИТМО.
Прога называется Cat
Принцип работы, как и реализация, очень прост:
Программа при старте спрашивает "Это кот?"
Если нет, то идет по вершинам дерева свойств предметов.
Если слово отгадано, то игра заканчивается,
если нет, то прости ввести само слово и его свойство.
Все изменения в дереве сохраняются.
Конечно это упрощенный вариант того о чем говорил Белокрылов,
но все же позволяет понять принцип её работы!
Exe-шник с небольшим деревом ответов
Инструкции:
набирать в консоли можно только буквами латиницей
положительный ответ "Y", отрицательный "N"
А вот исходный код:
(всего то ~200 строк кода )
#define EE_MARK "ee" struct TREE_ITEM { char *question; TREE_ITEM *down, *next; }; TREE_ITEM* AllocateNode(const char *question) { TREE_ITEM *pItem = (TREE_ITEM*)malloc(sizeof(TREE_ITEM)); if (!pItem) return NULL; pItem->down = pItem->next = NULL; pItem->question = strdup(question); return pItem; } void FreeNode(TREE_ITEM *pNode) { if (!pNode) return; free(pNode->question); free(pNode); } void FreeTree(TREE_ITEM *pTree) { if (!pTree) return; FreeTree(pTree->next); FreeTree(pTree->down); FreeNode(pTree); } void SaveSubTree(FILE *fp, TREE_ITEM *pTree, INT n = 0) { char *s = (char *)calloc(n + 1, 1); memset(s, ' ', n); if (!pTree) { fprintf(fp, "%s%s\n", s, EE_MARK); free(s); return; } fprintf(fp, "%s%s\n", s, pTree->question); SaveSubTree(fp, pTree->next, n + 1); SaveSubTree(fp, pTree->down, n + 1); free(s); } void PrintTree(TREE_ITEM *pTree) { puts("---------------------------------"); SaveSubTree(stdout, pTree); puts("---------------------------------"); } void SaveTree(TREE_ITEM *pTree) { CopyFile("tree", "tree.old", FALSE); FILE *fp = fopen("tree", "wt"); if (!fp) return; SaveSubTree(fp, pTree); fclose(fp); } char *SkipSpaces(char *p) { while (*p && (*p == ' ')) p++; return p; } TREE_ITEM* LoadSubTree(FILE *fp) { char str[1024]; fgets(str, sizeof(str), fp); if (str[strlen(str) - 1] == '\n') str[strlen(str) - 1] = 0; char *p = SkipSpaces(str); if (!strcmp(p, EE_MARK)) return NULL; TREE_ITEM *pRet = AllocateNode(p); pRet->next = LoadSubTree(fp); pRet->down = LoadSubTree(fp); return pRet; } TREE_ITEM *LoadTree() { FILE *fp = fopen("tree", "rt"); if (!fp) return NULL; TREE_ITEM *pRet = LoadSubTree(fp); fclose(fp); return pRet; } bool YesNo() { while (TRUE) { char c = toupper(getchar()); getchar(); if (c == 'Y') return true; else if (c == 'N') return false; } } void Run(TREE_ITEM *pRoot) { TREE_ITEM *pCur = pRoot, *pPrev; while (pCur) { printf("Eto %s? ", pCur->question); if (YesNo()) { if (pCur->down) Run(pCur->down); else puts("Uraaaaaaaaaa!!!"); return; } else { pPrev = pCur; pCur = pCur->next; } } puts("Chto eto?"); char name[1024]; gets(name); char dif[1024]; printf("Chem otlichaetsia ot %s?\n", pPrev->question); gets(dif); pPrev->next = AllocateNode(dif); pPrev->next->down = AllocateNode(name); } int _tmain(int argc, _TCHAR* argv[]) { SetConsoleCP(1251); SetConsoleOutputCP(1251); TREE_ITEM *pRoot = LoadTree(); if (!pRoot) { pRoot = AllocateNode("Kot"); if (!pRoot) return -1; } PrintTree(pRoot); Run(pRoot); PrintTree(pRoot); SaveTree(pRoot); FreeTree(pRoot); puts("Press ENTER to exit"); getchar(); return 0; }