ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

基于有序二叉树的专家系统应用——动物游戏(C++)

2022-02-01 18:02:51  阅读:221  来源: 互联网

标签:TEXT WM C++ WS 二叉树 hWnd 专家系统 NULL IDC


二、设计与实现

1、设计思想

      建立一个有序二叉树作为决策树,用来作为专家系统的知识库。决策树中的叶子结点存储各种动物的名称,其他节点存储有关动物特征的问题。从根节点开始,访问节点的内容。如果是节点内容是问题,由用户回答“是”、“否”。若回答“是”,访问左孩子结点,若回答否,访问右孩子节点,直到节点的内容为动物名称为止。此时,程序给出猜测结果。如果猜对,专家胜利。如果猜错,用户给出动物名称和特征,程序根据两者更改决策树、添加新的节点。

2、类结构

 

 

3、主要数据结构

主要的数据结构是链栈和二叉树。

二叉树,用来作为决策树,叶节点存储动物名称,其他节点存储有关动物特征的问题。同时对于每个问题节点,回答“是”对应的是左孩子节点,回答“否”对应的右孩子节点。

链栈在从文件中读取决策树中起作用。由于在文件中存储的决策树是按照后序遍历的方式存入的。在读取决策树的时候,也按照后序的次序建立相应的节点。栈中存储的是即将建立的双亲结点的孩子节点。也就是在每一轮中,首先被读入的是两个孩子节点,被存入到栈中,当读到它们的双亲结点时,两个孩子节点出栈,作为双亲结点的左右孩子后,双亲结点入栈。

4、算法设计

 

5、核心代码展示

static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    int wmId, wmEvent;
    wmId = LOWORD(wParam);
    wmEvent = HIWORD(wParam);
    HDC hdc;
    PAINTSTRUCT ps;
    switch (message)
    {
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);

        // To paint with a DDB it first needs to be associated
        // with a memory device context. We make a DC that
        // is compatible with the screen by passing NULL to
        // CreateCompatibleDC.
        // Then we need to associate our saved bitmap with the
        // device context.

        HDC hdcMem = CreateCompatibleDC(NULL);
        HBITMAP hbmT = SelectBitmap(hdcMem, hbm);

        // Now, the BitBlt function is used to transfer the contents of the 
        // drawing surface from one DC to another. Before we can paint the
        // bitmap however we need to know how big it is. We call the GDI
        // function GetObject to get the relevent details.
        BITMAP bm;
        GetObject(hbm, sizeof(bm), &bm);

        BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);

        // Now, clean up. A memory DC always has a drawing
        // surface in it. It is created with a 1X1 monochrome
        // bitmap that we saved earlier, and need to put back
        // before we destroy it.
        SelectBitmap(hdcMem, hbmT);
        DeleteDC(hdcMem);

        // EndPaint balances off the BeginPaint call.
        EndPaint(hWnd, &ps);

        break;
    }
    case WM_CREATE:
    { static2 = CreateWindow(TEXT("STATIC"), TEXT("欢迎来到专家系统应用"), WS_CHILD | WS_VISIBLE | WS_EX_TRANSPARENT, 10, 10, 500, 20, hWnd, (HMENU)IDC_STATIC2, NULL, NULL);
    SendMessage(static2, WM_SETFONT, (WPARAM)hFont, 1);
    button5 = CreateWindow(TEXT("BUTTON"), TEXT("进入专家系统应用"), WS_CHILD | WS_VISIBLE, 360, 100, 150, 40, hWnd, (HMENU)IDC_BUTTON5, NULL, NULL);
    SendMessage(button5, WM_SETFONT, (WPARAM)hFont, 1);
    HINSTANCE hInstance = GetWindowInstance(hWnd);
    //hbm = LoadBitmapW(hInstance,MAKEINTRESOURCE(IDB_BITMAP1));//C:\\Users\\Administrator.33XBYKMCA2C5EX4\Desktop\SpecPic
    hbm = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
    return 0;
    }
    case WM_COMMAND:
    {
        HWND hwndTmp;
        int wmId = LOWORD(wParam);
        switch (wmId)
        {
        case ID_40003:
        {
            MessageBox(hWnd, TEXT("开发人员名单:武祎、王艺然、何鸿丞、辛喆\n开发时间:2020年6月\n版本号:8.0\n学校:北京理工大学"), TEXT("开发者信息"), MB_OK);
            break;
        }
        case ID_40001:
        {
            MessageBox(hWnd, in_address, TEXT("当前决策树的文件路径"), MB_OK);
            break;
        }
        case ID_40004:
        {
            AnimalNumber();
            MessageBox(hWnd, t_num,TEXT ("决策树中的动物数量"), MB_OK);
            break;
        }
        case ID_40005:
        {
            if (IsTreeEmpty())
            {
                MessageBox(hWnd, TEXT("当前决策树为空!"), TEXT("提示"), MB_ICONWARNING);
            }
            else
            {
                TCHAR2Char(in_address, a);
                Save(hWnd);
            }
            break;
        }
        case ID_40006:
        {
            TCHAR2Char(in_address, a);
            Build(hWnd);
            break;
        }
        case IDC_BUTTON3:
            GetDlgItemText(hWnd, IDC_EDIT1, address, 100);
            TCHAR2Char(address, a);
            if (Build(hWnd))
            {
                if (flag == 0)
                {
                    static3 = CreateWindow(TEXT("STATIC"), TEXT("后序遍历输出的语句"), WS_CHILD | WS_VISIBLE|WS_EX_TRANSPARENT, 10, 200, 200, 20, hWnd, (HMENU)IDC_STATIC3, NULL, NULL);
                    SendMessage(static3, WM_SETFONT, (WPARAM)hFont, 1);
                    edit2=CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE|WS_HSCROLL|WS_VSCROLL , 10, 220, 300, 200, hWnd, (HMENU)IDC_EDIT2, NULL, NULL);
                    SendMessage(edit2, WM_SETFONT, (WPARAM)hFont, 1);
                    flag++;
                }
                GetDlgItemText(hWnd, IDC_EDIT1, in_address, 100);
                Display(hWnd);
            }
            break;
        case IDC_BUTTON4:
        {
           
            if (Expert(-1, hWnd))
            {
               
            }
            else
            {
                ClearAllWindows();
                static1 = CreateWindow(TEXT("STATIC"), TEXT("猜动物"), WS_CHILD | WS_VISIBLE | WS_EX_TRANSPARENT, 10, 10, 50, 20, hWnd, (HMENU)IDC_STATIC1, NULL, NULL);
                SendMessage(static1, WM_SETFONT, (WPARAM)hFont, 1);
                static2 = CreateWindow(TEXT("STATIC"), question, WS_CHILD | WS_VISIBLE | WS_EX_TRANSPARENT, 10, 50, 500, 20, hWnd, (HMENU)IDC_STATIC2, NULL, NULL);
                SendMessage(static2, WM_SETFONT, (WPARAM)hFont, 1);
                button5 = CreateWindow(TEXT("BUTTON"), TEXT("结束本轮游戏"), WS_CHILD | WS_VISIBLE, 360, 300, 120, 30, hWnd, (HMENU)IDC_BUTTON5, NULL, NULL);
                SendMessage(button5, WM_SETFONT, (WPARAM)hFont, 1);
                button8 = CreateWindow(TEXT("BUTTON"), TEXT("是"), WS_CHILD | WS_VISIBLE, 10, 100, 60, 30, hWnd, (HMENU)IDC_BUTTON8, NULL, NULL);
                SendMessage(button8, WM_SETFONT, (WPARAM)hFont, 1);
                button11 = CreateWindow(TEXT("BUTTON"), TEXT("否"), WS_CHILD | WS_VISIBLE, 100, 100, 60, 30, hWnd, (HMENU)IDC_BUTTON11, NULL, NULL);
                SendMessage(button11, WM_SETFONT, (WPARAM)hFont, 1);
            }
            break;
            
        }
        case IDC_BUTTON8:
        {
            if (!Expert(1, hWnd))
            {
                DestroyWindow(static2);
                static2 = NULL;
                static2 = CreateWindow(TEXT("STATIC"), question, WS_CHILD | WS_VISIBLE | WS_EX_TRANSPARENT, 10, 50, 500, 20, hWnd, (HMENU)IDC_STATIC2, NULL, NULL);
                SendMessage(static2, WM_SETFONT, (WPARAM)hFont, 1);
            }
            else
            {
                DestroyWindow(static2);
                static2 = NULL;
                static2 = CreateWindow(TEXT("STATIC"), question, WS_CHILD | WS_VISIBLE | WS_EX_TRANSPARENT, 10, 50, 500, 20, hWnd, (HMENU)IDC_STATIC2, NULL, NULL);
                SendMessage(static2, WM_SETFONT, (WPARAM)hFont, 1);
                DestroyWindow(button8);
                button8 = NULL;
                DestroyWindow(button11);
                button11 = NULL;
                button12 = CreateWindow(TEXT("BUTTON"), TEXT("猜对了"), WS_CHILD | WS_VISIBLE, 10, 250, 60, 30, hWnd, (HMENU)IDC_BUTTON12, NULL, NULL);
                SendMessage(button12, WM_SETFONT, (WPARAM)hFont, 1);
                button13 = CreateWindow(TEXT("BUTTON"), TEXT("猜错了"), WS_CHILD | WS_VISIBLE, 100, 250, 60, 30, hWnd, (HMENU)IDC_BUTTON13, NULL, NULL);
                SendMessage(button13, WM_SETFONT, (WPARAM)hFont, 1);
            }
            break;
        }
        case IDC_BUTTON11:
        {
            if (!Expert(0, hWnd))
            {
                DestroyWindow(static2);
                static2 = NULL;
                static2 = CreateWindow(TEXT("STATIC"), question, WS_CHILD | WS_VISIBLE | WS_EX_TRANSPARENT, 10, 50, 500, 20, hWnd, (HMENU)IDC_STATIC2, NULL, NULL);
                SendMessage(static2, WM_SETFONT, (WPARAM)hFont, 1);
            }
            else
            {
                DestroyWindow(static2);
                static2 = NULL;
                static2 = CreateWindow(TEXT("STATIC"), question, WS_CHILD | WS_VISIBLE | WS_EX_TRANSPARENT, 10, 50, 500, 20, hWnd, (HMENU)IDC_STATIC2, NULL, NULL);
                SendMessage(static2, WM_SETFONT, (WPARAM)hFont, 1);
                DestroyWindow(button8);
                button8 = NULL;
                DestroyWindow(button11);
                button11 = NULL;
                button12 = CreateWindow(TEXT("BUTTON"), TEXT("猜对了"), WS_CHILD | WS_VISIBLE, 10, 250, 60, 30, hWnd, (HMENU)IDC_BUTTON12, NULL, NULL);
                SendMessage(button12, WM_SETFONT, (WPARAM)hFont, 1);
                button13 = CreateWindow(TEXT("BUTTON"), TEXT("猜错了"), WS_CHILD | WS_VISIBLE, 100, 250, 60, 30, hWnd, (HMENU)IDC_BUTTON13, NULL, NULL);
                SendMessage(button13, WM_SETFONT, (WPARAM)hFont, 1);

            }
            break;
        }
      
        case IDC_BUTTON5:
        {
            ClearAllWindows();
            static2 = CreateWindow(TEXT("STATIC"), TEXT("菜单"), WS_CHILD | WS_VISIBLE | WS_EX_TRANSPARENT, 10, 10, 50, 20, hWnd, (HMENU)IDC_STATIC2, NULL, NULL);
            SendMessage(static2, WM_SETFONT, (WPARAM)hFont, 1);
            button4 = CreateWindow(TEXT("BUTTON"), TEXT("进入猜动物环节"), WS_CHILD | WS_VISIBLE, 360, 200, 150, 40, hWnd, (HMENU)IDC_BUTTON4, NULL, NULL);
            SendMessage(button4, WM_SETFONT, (WPARAM)hFont, 1);
            button6 = CreateWindow(TEXT("BUTTON"), TEXT("将决策树写入文件"), WS_CHILD | WS_VISIBLE, 360, 300, 150, 40, hWnd, (HMENU)IDC_BUTTON6, NULL, NULL);
            SendMessage(button6, WM_SETFONT, (WPARAM)hFont, 1);
            button7 = CreateWindow(TEXT("BUTTON"), TEXT("从文件中读入决策树"), WS_CHILD | WS_VISIBLE, 360, 100, 150, 40, hWnd, (HMENU)IDC_BUTTON7, NULL, NULL);
            SendMessage(button7, WM_SETFONT, (WPARAM)hFont, 1);
            button10 = CreateWindow(TEXT("BUTTON"), TEXT("退出系统"), WS_CHILD | WS_VISIBLE, 360, 400, 150, 40, hWnd, (HMENU)IDC_BUTTON10, NULL, NULL);
            SendMessage(button10, WM_SETFONT, (WPARAM)hFont, 1);
            break;
        }
        case IDC_BUTTON6:
        {
            if (IsTreeEmpty())
            {
                MessageBox(hWnd, TEXT("您的决策树为空树!"), TEXT("提示"), MB_ICONWARNING);
                break;
            }
            ClearAllWindows();
            static1 = CreateWindow(TEXT("STATIC"), TEXT("将决策树写入文件"), WS_CHILD | WS_VISIBLE | WS_EX_TRANSPARENT, 10, 10, 140, 20, hWnd, (HMENU)IDC_STATIC1, NULL, NULL);
            SendMessage(static1, WM_SETFONT, (WPARAM)hFont, 1);
            static2 = CreateWindow(TEXT("STATIC"), TEXT("请输入txt文件的地址:"), WS_CHILD | WS_VISIBLE, 10, 100, 160, 20, hWnd, (HMENU)IDC_STATIC2, NULL, NULL);
            SendMessage(static2, WM_SETFONT, (WPARAM)hFont, 1);
            button9 = CreateWindow(TEXT("BUTTON"), TEXT("确定"), WS_CHILD | WS_VISIBLE, 320, 140, 80, 30, hWnd, (HMENU)IDC_BUTTON9, NULL, NULL);
            SendMessage(button9, WM_SETFONT, (WPARAM)hFont, 1);
            button5 = CreateWindow(TEXT("BUTTON"), TEXT("返回"), WS_CHILD | WS_VISIBLE, 320, 200, 80, 30, hWnd, (HMENU)IDC_BUTTON5, NULL, NULL);
            SendMessage(button5, WM_SETFONT, (WPARAM)hFont, 1);
            flag = 0;
            edit1 = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER|ES_MULTILINE|WS_HSCROLL, 10, 140, 300, 50, hWnd, (HMENU)IDC_EDIT1, NULL, NULL);
            SendMessage(edit1, WM_SETFONT, (WPARAM)hFont, 1);
            break;
        }
        case IDC_BUTTON9:
        {
            GetDlgItemText(hWnd, IDC_EDIT1, address, 100);
            TCHAR2Char(address, a);
            Save(hWnd);
            break;
        }
        case IDC_BUTTON7:
        {
            ClearAllWindows();
            static1 = CreateWindow(TEXT("STATIC"), TEXT("读取文件建立决策树"), WS_CHILD | WS_VISIBLE | WS_EX_TRANSPARENT, 10, 10, 140, 20, hWnd, (HMENU)IDC_STATIC1, NULL, NULL);
            SendMessage(static1, WM_SETFONT, (WPARAM)hFont, 1);
            static2 = CreateWindow(TEXT("STATIC"), TEXT("请输入txt文件的地址:"), WS_CHILD | WS_VISIBLE | WS_EX_TRANSPARENT, 10, 100, 160, 20, hWnd, (HMENU)IDC_STATIC2, NULL, NULL);
            SendMessage(static2, WM_SETFONT, (WPARAM)hFont, 1);
            button3 = CreateWindow(TEXT("BUTTON"), TEXT("确定"), WS_CHILD | WS_VISIBLE, 320, 140, 80, 30, hWnd, (HMENU)IDC_BUTTON3, NULL, NULL);
            SendMessage(button3, WM_SETFONT, (WPARAM)hFont, 1);
            flag = 0;
            edit1 = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER| WS_HSCROLL | ES_MULTILINE, 10, 140, 300, 50, hWnd, (HMENU)IDC_EDIT1, NULL, NULL);
            SendMessage(edit1, WM_SETFONT, (WPARAM)hFont, 1);
            button5 = CreateWindow(TEXT("BUTTON"), TEXT("返回"), WS_CHILD | WS_VISIBLE, 320, 200, 80, 30, hWnd, (HMENU)IDC_BUTTON5, NULL, NULL);
            SendMessage(button5, WM_SETFONT, (WPARAM)hFont, 1);
            break;
        }
        case IDC_BUTTON12:
        {
            MessageBox(hWnd, TEXT("你竟然被一台电脑打败了,,,"), TEXT("提示"), MB_OK);
            ClearAllWindows();
            button4 = CreateWindow(TEXT("BUTTON"), TEXT("再玩一次"), WS_CHILD | WS_VISIBLE, 420, 200, 150, 40, hWnd, (HMENU)IDC_BUTTON4, NULL, NULL);
            SendMessage(button4, WM_SETFONT, (WPARAM)hFont, 1);
            button5 = CreateWindow(TEXT("BUTTON"), TEXT("返回"), WS_CHILD | WS_VISIBLE, 160, 200, 150, 40, hWnd, (HMENU)IDC_BUTTON5, NULL, NULL);
            SendMessage(button5, WM_SETFONT, (WPARAM)hFont, 1);
            break;
        }
        case IDC_BUTTON13:
        {
            MessageBox(hWnd, TEXT("专家猜错,请告诉专家动物信息"), TEXT("提示"), MB_OK);
            ClearAllWindows();
            static1 = CreateWindow(TEXT("STATIC"), TEXT("动物名称"), WS_CHILD | WS_VISIBLE | WS_EX_TRANSPARENT, 10, 110, 150, 20, hWnd, (HMENU)IDC_STATIC1, NULL, NULL);
            SendMessage(static1, WM_SETFONT, (WPARAM)hFont, 1);
            static2 = CreateWindow(TEXT("STATIC"), TEXT("区别于专家猜测的动物的特征(例如“它(不)是/(不)会/(没)有”句式)"), WS_CHILD | WS_VISIBLE | WS_EX_TRANSPARENT, 10, 200, 600, 20, hWnd, (HMENU)IDC_STATIC2, NULL, NULL);
            SendMessage(static2, WM_SETFONT, (WPARAM)hFont, 1);
            edit1 = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | WS_HSCROLL | ES_MULTILINE, 10, 140, 300, 50, hWnd, (HMENU)IDC_EDIT1, NULL, NULL);
            SendMessage(edit1, WM_SETFONT, (WPARAM)hFont, 1);
            edit2 = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | WS_HSCROLL | ES_MULTILINE, 10, 230, 300, 50, hWnd, (HMENU)IDC_EDIT2, NULL, NULL);
            SendMessage(edit2, WM_SETFONT, (WPARAM)hFont, 1);
            button14 = CreateWindow(TEXT("BUTTON"), TEXT("确定"), WS_CHILD | WS_VISIBLE, 320, 300, 80, 30, hWnd, (HMENU)IDC_BUTTON14, NULL, NULL);
            SendMessage(button14, WM_SETFONT, (WPARAM)hFont, 1);
            button5 = CreateWindow(TEXT("BUTTON"), TEXT("返回"), WS_CHILD | WS_VISIBLE, 320, 350, 80, 30, hWnd, (HMENU)IDC_BUTTON5, NULL, NULL);
            SendMessage(button5, WM_SETFONT, (WPARAM)hFont, 1);
            break;
        }
        case IDC_BUTTON14:
        {
            GetDlgItemText(hWnd, IDC_EDIT1, a_name, 100);
            GetDlgItemText(hWnd, IDC_EDIT2, a_feature, 100);
            if (a_name[0] == '\0')
            {
                MessageBox(hWnd, TEXT("动物名称不能为空"), TEXT("提示"), MB_ICONWARNING);
                break;
            }
            if (a_feature[0] == '\0')
            {
                MessageBox(hWnd, TEXT("相关特征不能为空"), TEXT("提示"), MB_ICONWARNING);
                break;
            }
            Expert(14, hWnd);
            ClearAllWindows();
            button4 = CreateWindow(TEXT("BUTTON"), TEXT("再玩一次"), WS_CHILD | WS_VISIBLE, 420, 200, 150, 40, hWnd, (HMENU)IDC_BUTTON4, NULL, NULL);
            SendMessage(button4, WM_SETFONT, (WPARAM)hFont, 1);
            button5 = CreateWindow(TEXT("BUTTON"), TEXT("返回"), WS_CHILD | WS_VISIBLE, 160, 200, 150, 40, hWnd, (HMENU)IDC_BUTTON5, NULL, NULL);
            SendMessage(button5, WM_SETFONT, (WPARAM)hFont, 1);
            break;
        }
        case IDC_BUTTON10:
        {
            PostQuitMessage(0);
            return 0;
        }
        }
       
    }
    return 0;

    case WM_CTLCOLORSTATIC:
    {
        HDC hdc = (HDC)wParam;
        
    }
    return (BOOL)((HBRUSH)GetStockObject(NULL_BRUSH));
    
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    
    return DefWindowProc(hWnd, message, wParam, lParam);
}

三、测试与结论

1、测试环境:Visual Studio 2019
 1)从文件读取决策树如下图:

2)用户依次选择问题答案如下图:

 

3)程序输出猜测结果如下图:

 

4)若猜测正确则显示如下图:

 

5)猜测错误则用户输入动物名称并按照提示描述特征如下图(如果用户输入为空系统会发出提示):

 

 

6)用户可选择再玩一次或将新的决策树保存到文件中如下图:

 

 


7)在上侧菜单中,文件栏下,有以下辅助功能;在关于栏下,有开发者信息;在数据栏下,有动物的个数。

 

 

 

  1. 若用户没有读入决策树就开始进入猜动物环节,程序有相应提醒。

 

 

9)当用户非法输入时会有相应提醒。

 

  1. 当用户未建立决策树就开始保存到新文件时,会有相应提醒。

程序源码:

基于有序二叉树的专家系统应用——动物游戏(C++)源代码与应用程序-C/C++文档类资源-CSDN文库

 

标签:TEXT,WM,C++,WS,二叉树,hWnd,专家系统,NULL,IDC
来源: https://blog.csdn.net/where_are_u/article/details/122765089

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有