动物猜想简化版

时间:2021-11-27 02:33:14
动物猜想简化版

尝试完成具有如下功能的程序。

举例说明:
程序提示你“你现在猜想的是一只狗吗?Y:N”。
如果你想到的是一只狗,程序会说“我赢了!”,结束。
如果你想的是一只鸽子,程序会说“我输了,请告诉我你想像的动物,并告诉我这个动物不同与以上猜测动物的特征!”,输入“鸽子,(为空代表从根插入),一种鸟类”,结束。
再次运行程序“你现在猜想的是一种鸟类吗?Y:N”。
否则提示“你现在猜想的是一只狗吗?”,是则提示“你现在猜想的是一只鸽子吗?Y:N”。
是则程序赢并结束。
如果不是程序则继续认输并提示你输入想像的动物。如输入“海鸥,一种鸟类,一种在海边生存的鸟类”,结束。
这样程序在最开始的时候只会猜狗这一种动物,然后会变的越来越聪明。

刚开始学习C++,这样的程序怎样做啊?求教。。。。。。。。

16 个解决方案

#1


这样的题目应该用Prolog去写。

#2


#include "stdafx.h "
#include <iostream>
#include <string>
using namespace std;

class PlayGame;

class Node {                     
public:
    Node(PlayGame *p) : playgame(p) {}
    void process();
    PlayGame *playgame;
};

class PlayGame                     
{
      public:
   virtual void process(Node *node)=0;
   virtual ~PlayGame() {} 
};

class Questions:public PlayGame   {
  public:
    Questions(string ques, Node *yes, Node *no);   
    virtual void process(Node *node);  
~Questions(){}
protected:
    string question;
    Node *yesNode; 
    Node *noNode;  
};

class Answers : public PlayGame       
{      
public:
    Answers(string a) : animal(a) {}        
    virtual void process(Node *node); 
~Answers(){}
protected:
    string animal;
};

void
Node::process()
{
    playgame->process(this);
}

Questions::Questions(string q, Node *y, Node *n)   
  : question(q), yesNode(y), noNode(n) {}

void
Questions::process(Node *node)                    
{
    string answer;
    cout<<"你现在猜想的是一种"<<question << "? Y:N"<<"\n";
    cin>>answer;
    if(answer == "Y") {
//if(answerIsYes()) {
        yesNode->process();
    } 
else 
{
 noNode->process();
    }
}

void
Answers::process(Node *node)                  
{
    string answer;
    cout << "你现在猜想的是一只" << animal << "吗? Y:N"<<"\n";
    cin >> answer;    
    if(answer == "Y") {
//if(answerIsYes()) {
        cout << "我赢了!" << endl;
      } 
else {

char newAnimal[100]={0};
cout<<"我输了,请告诉我你想像的动物?"<<"\n";
cin>>newAnimal;
        cout << "请告诉我这个动物不同与以上猜测动物的特征!"<<"\n";
         char newQuestion[100]={0};
 cin>>newQuestion;
         node->playgame= new Questions(newQuestion,new Node(new Answers(newAnimal)),new Node(new Answers(animal)));
    }
}


void main()
{
   Node root(new Answers("狗"));
cout << "游戏开始!" << endl;
for(;;){
    root.process();
}
    cout << "游戏结束!" << endl;
}

我已经做的这里了 可是不能扩展叶子节点 怎么办啊?这样只能进行两次智能学习啊 后面的都不行了  

#3


具体写起来太麻烦,我给你说说我的思路:

为了进行应答思考,程序需要一个知识库数据结构。因为是二值问答,采用二叉树是比较简单的方式。

知识库的节点带有“知识类型”字段,可标记出该节点是“判定条件”呢,还是“具体动物”呢。
如果是判定条件,则节点带有“条件”字段,包含了用户输入的“区别”内容。
如果是具体动物,则节点带有“名称”字段,包含该动物名字。

节点带有两个指向本类型的指针,分别是Yes指针和No指针。用于在用户回答“判定条件”的提问后往下行走。

设计一个“知识库”类用于保存该二叉树,并实现对知识库的知识获取和添加。
类中提供二叉树根、当前位置等指针;
提供“取得当前节点值”的方法;
提供“按回答移动当前位置”的方法;
提供“增添新知识”方法——该方法将在当前节点位置插入一个新的节点,类型为“判定条件”,将用户输入的条件保存其中;再插入另一个节点用于保存新动物,并下挂在新条件节点的Yes指针下;将老的当前节点下移到新条件节点的No指针下。

主程序里首先创建一个知识库对象,通过其构造函数先建立起基础知识。然后进入游戏循环,逐步取出知识库里的知识进行问答,在知识库失败后获取新知识并将其加入知识库中。

#4


当程序用户在“具体动物”节点回答No,则表明知识库失败;回答Yes,则知识库成功。

当程序用户在“判定条件”上回答Yes或No,则程序从知识库获取下一内容。

#5


为了简化程序,可以给每个节点设置一个父指针,方便进行插入操作。毕竟只是个小库,空间复杂度要求不高。

#6


根据我上面的程序 应该怎样改啊 是不是改 node->playgame= new Questions(newQuestion,new Node(new Answers(newAnimal)),new Node(new Answers(animal)));
这个方法就行了啊  二叉树那学的不是很明白啊  求解释  谢谢了

#7


你上面那个是乱写的......一堆类胡乱关联

#8


奥  那我再按照你的写一个看看吧   谢谢你

#9


要是您有时间 给我写一个样本就好了 我还是不大会

#10


晕  还是不行  求高手指教啊!!!!!!!!!!!!!!!!

#11


还没仔细调试过,不知道有没有错:
//#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;

struct node
{
public:
    char type;      //  节点类型,0表示条件,1表示具体动物
    string name,condition;  //  节点内容
    node *yes,*no,*parent;
};

class thesaurus
{
private:
    node *root;
    node *current;

public:
    thesaurus();
    string readCurrentName() {return current->name;};
    string readCurrentCondition() {return current->condition;};
    char readCurrentType() {return current->type;};
    void move(int answer);      //  根据answer参数将current指针指向下一个位置。1表示用户选择了yes,0表示选择了no
    void increase(const string name, const string condition);  //  增加新知识
    void resetCurrent() {current=root->yes;};   //  复位当前位置指针
};

thesaurus::thesaurus()
{
    //  创建根节点
    root=new node();
    root->type=0;
    root->name="";
    root->condition="";
    root->yes=NULL;
    root->no=NULL;
    root->parent=NULL;

    //  初始化知识库
    node *p=new node();
    p->type=1;
    p->name="狗";
    p->condition="";
    p->parent=root;
    p->yes=NULL;
    p->no=NULL;
    root->yes=p;

    current=p;
}

void thesaurus::move(int answer)
{               //  根据answer参数将current指针指向下一个位置。1表示用户选择了yes,0表示选择了no
    if (current->type==0)
    {
        if (answer)
            current=current->yes;
        else
            current=current->no;
    }
    return;
}

void thesaurus::increase(const string cName, const string cCondition)
{
    //  创建新节点,保存新知识
    node *p,*q;
    p=new node();
    q=new node();
    
    p->type=0;
    p->name="";
    p->condition=*(new string(cCondition));
    p->yes=q;
    p->no=current;
    p->parent=current->parent;

    q->type=1;
    q->name=*(new string(cName));
    q->condition="";
    q->yes=NULL;
    q->no=NULL;
    q->parent=p;

    //  插入新节点
    if (current->parent->yes==current)
        current->parent->yes=p;
    else
        current->parent->no=p;
    current->parent=p;
}

void main()
{
    thesaurus ts;
    char ch;
    string name,condition;

    while (1)
    {
        ts.resetCurrent();
        while (1)
        {
            if (ts.readCurrentType()==0)
            {
                cout<<"你现在猜想的是"<<ts.readCurrentCondition()<<"吗?(Y/N)";
                cin>>ch;
                ts.move(ch=='Y'||ch=='y');
            }
            else
            {
                cout<<"你现在猜想的是一只"<<ts.readCurrentName()<<"吗?(Y/N)";
                cin>>ch;
                if (ch=='Y'||ch=='y')
                {
                    printf("我赢了!\n");
                    break;
                }
                else
                {
                    printf("我输了,请告诉我你想像的动物?");
                    cin>>name;
                    printf("请告诉我这个动物不同与以上猜测动物的特征!");
                    cin>>condition;
                    ts.increase(name,condition);
                    break;
                }
            }
        }
    }

    return;
}

其实这样的问题要是交给Prolog来写,可能就是几行十几行的事儿了。

#12


你要是多给点分,恐怕早就有大牛给你代码了。只有40分,除了我们这些缺分的人就没别人会给你写这么多了......

#13


该回复于2012-03-20 09:36:01被版主删除

#14


多谢指导啊  怎样才能练就你这一身本领啊?

#15


很容易的,多写点代码就会了

#16


楼主,现在我也要做动物猜想简化版的程序了……你做的怎么样了?

#1


这样的题目应该用Prolog去写。

#2


#include "stdafx.h "
#include <iostream>
#include <string>
using namespace std;

class PlayGame;

class Node {                     
public:
    Node(PlayGame *p) : playgame(p) {}
    void process();
    PlayGame *playgame;
};

class PlayGame                     
{
      public:
   virtual void process(Node *node)=0;
   virtual ~PlayGame() {} 
};

class Questions:public PlayGame   {
  public:
    Questions(string ques, Node *yes, Node *no);   
    virtual void process(Node *node);  
~Questions(){}
protected:
    string question;
    Node *yesNode; 
    Node *noNode;  
};

class Answers : public PlayGame       
{      
public:
    Answers(string a) : animal(a) {}        
    virtual void process(Node *node); 
~Answers(){}
protected:
    string animal;
};

void
Node::process()
{
    playgame->process(this);
}

Questions::Questions(string q, Node *y, Node *n)   
  : question(q), yesNode(y), noNode(n) {}

void
Questions::process(Node *node)                    
{
    string answer;
    cout<<"你现在猜想的是一种"<<question << "? Y:N"<<"\n";
    cin>>answer;
    if(answer == "Y") {
//if(answerIsYes()) {
        yesNode->process();
    } 
else 
{
 noNode->process();
    }
}

void
Answers::process(Node *node)                  
{
    string answer;
    cout << "你现在猜想的是一只" << animal << "吗? Y:N"<<"\n";
    cin >> answer;    
    if(answer == "Y") {
//if(answerIsYes()) {
        cout << "我赢了!" << endl;
      } 
else {

char newAnimal[100]={0};
cout<<"我输了,请告诉我你想像的动物?"<<"\n";
cin>>newAnimal;
        cout << "请告诉我这个动物不同与以上猜测动物的特征!"<<"\n";
         char newQuestion[100]={0};
 cin>>newQuestion;
         node->playgame= new Questions(newQuestion,new Node(new Answers(newAnimal)),new Node(new Answers(animal)));
    }
}


void main()
{
   Node root(new Answers("狗"));
cout << "游戏开始!" << endl;
for(;;){
    root.process();
}
    cout << "游戏结束!" << endl;
}

我已经做的这里了 可是不能扩展叶子节点 怎么办啊?这样只能进行两次智能学习啊 后面的都不行了  

#3


具体写起来太麻烦,我给你说说我的思路:

为了进行应答思考,程序需要一个知识库数据结构。因为是二值问答,采用二叉树是比较简单的方式。

知识库的节点带有“知识类型”字段,可标记出该节点是“判定条件”呢,还是“具体动物”呢。
如果是判定条件,则节点带有“条件”字段,包含了用户输入的“区别”内容。
如果是具体动物,则节点带有“名称”字段,包含该动物名字。

节点带有两个指向本类型的指针,分别是Yes指针和No指针。用于在用户回答“判定条件”的提问后往下行走。

设计一个“知识库”类用于保存该二叉树,并实现对知识库的知识获取和添加。
类中提供二叉树根、当前位置等指针;
提供“取得当前节点值”的方法;
提供“按回答移动当前位置”的方法;
提供“增添新知识”方法——该方法将在当前节点位置插入一个新的节点,类型为“判定条件”,将用户输入的条件保存其中;再插入另一个节点用于保存新动物,并下挂在新条件节点的Yes指针下;将老的当前节点下移到新条件节点的No指针下。

主程序里首先创建一个知识库对象,通过其构造函数先建立起基础知识。然后进入游戏循环,逐步取出知识库里的知识进行问答,在知识库失败后获取新知识并将其加入知识库中。

#4


当程序用户在“具体动物”节点回答No,则表明知识库失败;回答Yes,则知识库成功。

当程序用户在“判定条件”上回答Yes或No,则程序从知识库获取下一内容。

#5


为了简化程序,可以给每个节点设置一个父指针,方便进行插入操作。毕竟只是个小库,空间复杂度要求不高。

#6


根据我上面的程序 应该怎样改啊 是不是改 node->playgame= new Questions(newQuestion,new Node(new Answers(newAnimal)),new Node(new Answers(animal)));
这个方法就行了啊  二叉树那学的不是很明白啊  求解释  谢谢了

#7


你上面那个是乱写的......一堆类胡乱关联

#8


奥  那我再按照你的写一个看看吧   谢谢你

#9


要是您有时间 给我写一个样本就好了 我还是不大会

#10


晕  还是不行  求高手指教啊!!!!!!!!!!!!!!!!

#11


还没仔细调试过,不知道有没有错:
//#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;

struct node
{
public:
    char type;      //  节点类型,0表示条件,1表示具体动物
    string name,condition;  //  节点内容
    node *yes,*no,*parent;
};

class thesaurus
{
private:
    node *root;
    node *current;

public:
    thesaurus();
    string readCurrentName() {return current->name;};
    string readCurrentCondition() {return current->condition;};
    char readCurrentType() {return current->type;};
    void move(int answer);      //  根据answer参数将current指针指向下一个位置。1表示用户选择了yes,0表示选择了no
    void increase(const string name, const string condition);  //  增加新知识
    void resetCurrent() {current=root->yes;};   //  复位当前位置指针
};

thesaurus::thesaurus()
{
    //  创建根节点
    root=new node();
    root->type=0;
    root->name="";
    root->condition="";
    root->yes=NULL;
    root->no=NULL;
    root->parent=NULL;

    //  初始化知识库
    node *p=new node();
    p->type=1;
    p->name="狗";
    p->condition="";
    p->parent=root;
    p->yes=NULL;
    p->no=NULL;
    root->yes=p;

    current=p;
}

void thesaurus::move(int answer)
{               //  根据answer参数将current指针指向下一个位置。1表示用户选择了yes,0表示选择了no
    if (current->type==0)
    {
        if (answer)
            current=current->yes;
        else
            current=current->no;
    }
    return;
}

void thesaurus::increase(const string cName, const string cCondition)
{
    //  创建新节点,保存新知识
    node *p,*q;
    p=new node();
    q=new node();
    
    p->type=0;
    p->name="";
    p->condition=*(new string(cCondition));
    p->yes=q;
    p->no=current;
    p->parent=current->parent;

    q->type=1;
    q->name=*(new string(cName));
    q->condition="";
    q->yes=NULL;
    q->no=NULL;
    q->parent=p;

    //  插入新节点
    if (current->parent->yes==current)
        current->parent->yes=p;
    else
        current->parent->no=p;
    current->parent=p;
}

void main()
{
    thesaurus ts;
    char ch;
    string name,condition;

    while (1)
    {
        ts.resetCurrent();
        while (1)
        {
            if (ts.readCurrentType()==0)
            {
                cout<<"你现在猜想的是"<<ts.readCurrentCondition()<<"吗?(Y/N)";
                cin>>ch;
                ts.move(ch=='Y'||ch=='y');
            }
            else
            {
                cout<<"你现在猜想的是一只"<<ts.readCurrentName()<<"吗?(Y/N)";
                cin>>ch;
                if (ch=='Y'||ch=='y')
                {
                    printf("我赢了!\n");
                    break;
                }
                else
                {
                    printf("我输了,请告诉我你想像的动物?");
                    cin>>name;
                    printf("请告诉我这个动物不同与以上猜测动物的特征!");
                    cin>>condition;
                    ts.increase(name,condition);
                    break;
                }
            }
        }
    }

    return;
}

其实这样的问题要是交给Prolog来写,可能就是几行十几行的事儿了。

#12


你要是多给点分,恐怕早就有大牛给你代码了。只有40分,除了我们这些缺分的人就没别人会给你写这么多了......

#13


该回复于2012-03-20 09:36:01被版主删除

#14


多谢指导啊  怎样才能练就你这一身本领啊?

#15


很容易的,多写点代码就会了

#16


楼主,现在我也要做动物猜想简化版的程序了……你做的怎么样了?