//-< GUESS.CPP >-----------------------------------------------------*--------* // GOODS Version 1.0 (c) 1992 GARRET * ? * // ( Garret object oriented data storage ) * /\| * // Store interface with objects * / \ * // Created: 14-Feb-92 K.A. Knizhnik * / [] \ * // Last update: 16-May-92 K.A. Knizhnik * GARRET * //-------------------------------------------------------------------*--------* #define SMART_POINTERS // используем умные указатели #include #include #include "fstor.hpp" // используется простое файловое хранилище #include "oodbs.hpp" #define MAX_STRING_SIZE 256 Dbs_Channel DB_Vio ( 10 ) ; // создается пул каналов ввода/вывода Dbs_Pool DB_Cache ( 64 ) ; // создается пул страниц (размером 64 страницы) Dbs_File DB_File ( "guess.dbs" ); // файл с которым работает база данных Dbs_F_Store DB_Store ( DB_File, DB_Cache ); // хранилище данного файла Dbs_Store* DB_List = &DB_Store;// список хранилищ исполззуемых базой данных Object_Database Db( 1, &DB_List ); // создание базы данных // первый параметр - количество хранилищ, 2-ой - массив указателей на хранилища, class tree_node : public File_Object { public: typedef Ptr node_ptr; node_ptr guess(); static node_ptr what_is_it(node_ptr parent); static node_ptr create(node_ptr no, char* question, node_ptr yes) { return new (strlen(question)) tree_node(no, question, yes); } protected: node_ptr yes; node_ptr no; char question[1]; tree_node(node_ptr no, char* question, node_ptr yes) { this->no = no; this->yes = yes; strcpy(this->question, question); } }; void input(char* prompt, char* buf, size_t buf_size) { char* p; do { printf(prompt); *buf = '\0'; fgets(buf, buf_size, stdin); p = buf + strlen(buf); } while (p <= buf+1); if (*(p-1) == '\n') { *--p = '\0'; } } bool positive_answer() { char buf[16]; return fgets(buf, sizeof buf, stdin) && (*buf == 'y' || *buf == 'Y'); } tree_node::node_ptr tree_node::what_is_it(node_ptr parent) { char animal[MAX_STRING_SIZE], question[MAX_STRING_SIZE]; input("What is it ? ", animal, sizeof animal); input("What is difference from other ? ", question, sizeof question); node_ptr root = create(parent, question, NULL); root->yes = create(NULL, animal, NULL); return root; } tree_node::node_ptr tree_node::guess() { printf("May be, %s (y/n) ? ", question); if (positive_answer()) { if (Nil(yes)) { printf("It was very simple question for me...\n"); } else { node_ptr clarify = yes->guess(); if (!Nil(clarify)) { Modify(); yes = clarify; } } } else { if (Nil(no)) { if (Nil(yes)) { return what_is_it(this); } else { Modify(); no = what_is_it(NULL); } } else { node_ptr clarify = no->guess(); if (!Nil(clarify)) { Modify(); no = clarify; } } } return NULL; } int main() { tree_node::node_ptr root(NULL); Db.Open(); // открываем базы данных while(true) { printf("Think of an animal.\nReady (y/n) ? "); if (!positive_answer()) { break; } if (Nil(root)) { if (Db.Empty()) { root = tree_node::what_is_it(NULL); continue; } else { root = Ptr::Root(); } } root->guess(); } printf("End of the game\n"); Db.Close(); // надо не забыть закрыть базу return 0; }