Advertisement
Guest User

Untitled

a guest
Jan 28th, 2021
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 19.80 KB | None | 0 0
  1. #pragma warning(disable: 4996)
  2. #include "DxLib.h"
  3. #include <mecab.h>
  4. #pragma comment(lib, "libmecab.lib")
  5. #include <string>
  6.  
  7. int InputHandle;
  8. int mozicount = 0;
  9. int gimonnlock = 0;
  10. int gimon = 0;
  11. int memorycount = 0;
  12. int memory = 0;
  13. char buffer[256];//★InputHandleに入ったのは文字のデータなので、文字のデータが受け取れる変数の型にする。
  14. char buffer2[256];
  15. char  buffer3[256];
  16. char  buffer4[256];
  17. char  buffer5[256];
  18. char input[256];
  19. char* p;
  20. char* p1;
  21. FILE* outputfile;         // 出力ストリーム
  22. int hyouzi = 0;
  23. char* memo[1000];//関数とは関係ない。//charの配列には必ず定数値を書かなければならない、なのでメモにある文字列1000行まで読み込めるように。100とした。
  24. int n_show = 0;
  25. int show_color = GetColor(255, 0, 255);
  26. int a;
  27. const char* z = "";  // z は drawString で表示する文字列
  28. int pos[2] = { 0 };  // z の表示文字位置(初期値をゼロにする)
  29. unsigned debug_color = GetColor(255, 255, 0);
  30. unsigned z_color = GetColor(5, 255, 255);
  31. int   LEFTmark = 0;
  32. int diffrent = 0;
  33.  
  34. const char* result = "";
  35. char buf[4096];
  36. const char* words[100];
  37. int n = 0;
  38. unsigned word_color = GetColor(0, 255, 255);
  39.  
  40. char my_str2(const char* s1, const char* s2)//ここで入力した文字列と用意された文字列を引数として扱う。
  41.  
  42. {
  43.     //s1, s2を比較する関数を使うためだけにs2の文字列のサイズが必要なので、変数aに用意した文字列の情報s2を文字列の長さを測るための関数strlenに引数として渡す。
  44.     const size_t a = strlen(s2);
  45.     //無限ループする。
  46.     for (;;) {
  47.         //関数memcmpの返り値が0の時は一致した時なので、==0とする。
  48.         if (memcmp(s1, s2, a) == 0)
  49.  
  50.             return 1;//入力した文字列にい指定された文字列が入っていた場合は1を返すように設定した。
  51. //入力した文字列が最後の文字まで到達した場合は一致する文字列がないということなので0を返すようにした。
  52.         else if (*s1 == '\0')
  53.  
  54.             return 0;//入っていなかった
  55. //文字列が一致した場合でも一致する文字列がない場合でも入力した文字列の一文字分の文字コードのバイト数?が繰り上がるようにした。
  56.         else
  57.  
  58.             ++s1;
  59.  
  60.     }
  61.  
  62. }
  63. // drawString -- 文字を一字ずつ表示する
  64. void drawString(int x, int y, int color, int* pos, const char* str)
  65. {
  66.     char c = str[*pos];  // *pos は pos[0] で表示文字位置
  67.     if (pos[1] == 0 && c != '\0') *pos += IsDBCSLeadByte(c) ? 2 : 1;
  68.     if (++pos[1] == 10) pos[1] = 0;  // pos[1] はフレームカウンタ
  69.     DrawFormatString(x, y, color, "%.*s", *pos, str);
  70. }
  71.  
  72.  
  73. int readMemo(char** memo, int n)
  74. {
  75.     outputfile = fopen("memo.txt", "r");
  76.     if (outputfile == NULL) return 0;
  77.     int i;
  78.     char buf[256];
  79.     memo[0] = (char*)"";
  80.     for (i = 1; i < n && fgets(buf, sizeof buf, outputfile); i++)
  81.         memo[i] = strdup(buf);
  82.     fclose(outputfile);
  83.     return i;
  84. }
  85.  
  86.  
  87. int findMemo(char** memo, int n, char* str)
  88. {
  89.     if (str[0] != '\0')
  90.         for (int i = 0; i < n; i++)
  91.             if (strstr(memo[i], str)) return i;
  92.     return 0;
  93. }
  94.  
  95. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  96. {
  97.     SetGraphMode(1500, 780, 32);         // ウィンドウの大きさを指定
  98.     ChangeWindowMode(TRUE);             // 全画面ではなくウインドウを使用
  99.     // DXライブラリの初期化
  100.     if (DxLib_Init() == -1) return -1;
  101.     SetFontSize(33);                             //サイズを42に変更
  102.     // 描画先を裏にする
  103.     SetDrawScreen(DX_SCREEN_BACK);
  104.     InputHandle = MakeKeyInput(150, FALSE, FALSE, FALSE); //これで総計150バイトの文字データを保持できる。
  105.     // 作成したキー入力ハンドルをアクティブにする
  106.     SetActiveKeyInput(InputHandle);
  107.  
  108.     while (ProcessMessage() == 0)
  109.     {
  110.         // 画面の初期化
  111.         ClearDrawScreen();
  112.         //まずは描画する部分から作る。
  113.         // 入力モードを描画
  114.         DrawKeyInputModeString(1500, 0); // 入力モードを描画
  115.         // 入力途中の文字列を描画
  116.         DrawKeyInputString(0, 0, InputHandle);//InputHandleはint型とリファレンスに書いてあったんで
  117.         //その後にif文での分岐を考える。
  118.           // 入力が終了している場合は終了
  119.           //ループ内とは言えエンターキー一回でCheckKeyInputが呼べればいい。
  120.          //エンターキーが押された時の部分。
  121.         if (CheckKeyInput(InputHandle) != 0) {
  122.             LEFTmark = 678;
  123.             hyouzi = 0;
  124.             gimon = 0;
  125.             memorycount = 0;
  126.             ++mozicount;
  127.             // 入力された文字列を取得、その文字列を数値に変換
  128.             GetKeyInputString(buffer, InputHandle);//ここでInputHandleに入力された文字列の数値をGetKeyInputStringにより文字コードに変換したものを上でchar型で定義したbufferに入れる。
  129.  
  130.             MeCab::Tagger* tagger = MeCab::createTagger("");
  131.             result = tagger->parse(buffer);
  132.             strcpy_s(buf, sizeof buf, result);
  133.             n = 0;
  134.             words[n] = strtok(buf, "\t\n");//bufに最初のワードのみしか入っていないには関数strtokによって文章が分解され、分解されたものがwoedsに入るので
  135.             //その残りというか、名残みたいなものだろうと考えている。
  136.             //★bufには最初の単語しか入らない、というのも、最初の単語以降は"\t\n"により消されているためである。
  137.             while (n < 100 && words[n]) {//★★ここでもnが0から始まるのが、上での「タバコ」に続く品詞や改行が strtok(NULL, "\t\n");
  138.                 //によりNULLになる。しかし、nが0の時の「タバコ」はwhileに入る前のwords[n] = strtok(buf, "\t\n");で
  139.                 //既にwords[n]に入っているため必要ない、なのでstrtok(NULL, "\t\n");のみしか書いていない。かつ、何周しても
  140.                 //  正しく単語がwords[++n]に入るように  strtok(NULL, "\t\n");と
  141.                 //  words[++n] = strtok(NULL, "\t\n");は同じ条件としている。
  142.                 //二行目の「を」やその後に続く単語には品詞や改行が続くので、その部分をNULLにして words[++n] に単語を入れるために
  143.                 //words[++n] = strtok(NULL, "\t\n");は書いてある。
  144.                 //っていうか、最初の話題は既に理解できたんだから、後のことに関してはバグってわけではないけど、理不尽な形、ある意味間違った書き方
  145.                 //にしたらそれ相応の出力が
  146.                 //されたとしか言えない。
  147.                 strtok(NULL, "\t\n");//★一週目のwords[n] = strtok(buf, "\t\n")のためにこいつがあり、その後の二周目以降のwords[++n] = strtok(NULL, "\n");
  148.                 //にも同じような条件にして差し支えないようにするために strtok(NULL, "\t\n")としたのだろう。
  149.                 words[++n] = strtok(NULL, "\t\n");//★nには++により1から入るのでかつwhile (n < 100 && words[n])によりnは定数で書けないのでn=0の場合は外に書いた。
  150.             }
  151.             //strtok(NULL, "\t");の場合、while前での一行目は単語だけだが、一行目にもwhileはかかるがwords[n] = strtok(buf, "\t\n");の部分で単語のみになり、
  152.             //二行目やその後の文章はstrtok(NULL, "\t")によりn=1での二行目の・の部分はNULLになり、
  153.             //words[++n] = strtok(NULL, "\t\n");によりn=1での・から最初の改行までNULLになるので
  154.             //残った品詞や改行が words[++n]に入る。
  155.             // strtok(NULL, "\n");の場合変わらないのは、二行目やその後の文章はstrtok(NULL, "\n")によりn=1
  156.             //で二行目の最初の改行がNULLになり、 words[++n] = strtok(NULL, "\t\n(このstrtokが後に書かれているので最初の改行)");によりn=1での・から二行目の改行(最後)までがNULLにより空になり
  157.             //単語の部分だけ words[++n]に入るのだろう。
  158.             //words[++n] = strtok(NULL, "\t");で変わらないのは、 strtok(NULL, "\t\n");により2行目以降の・から同じ行の最後の改行までNULLになり、(多分、
  159.             // strtok(NULL, "\t\n");の配置の順番で改行の最初か最後かが決まるのだろう。)
  160.             //そのままのときの「n=1」での言葉が words[++n] = strtok(NULL, "\t");に関係なくそのまま words[++n]に入るためだろう。
  161.             int n_memo = readMemo(memo, 1000);//ここで関数readMemoを書くことでキーを押すたびに書き込んだ文章が読み込める。
  162.             n_show = findMemo(memo, n_memo, buffer);  // メモを検索
  163.  
  164.  
  165.             if (my_str2(buffer, "覚えて")) {
  166.  
  167.                 z = "何を覚えますか?", pos[0] = pos[1] = 0;
  168.                 ++mozicount;
  169.                 memory = 1;
  170.                 gimon = 0;
  171.             }
  172.             //覚えてという言葉以外の場合はメモを読み込む込んでループに入るようにした。
  173.             else if (memory == 0) {
  174.                 outputfile = fopen("memo.txt", "r");  // ファイルを読み込み用にオープン(開く)
  175.                 if (outputfile == NULL) {          // オープンに失敗した場合
  176.                     printf("cannot open\n");         // エラーメッセージを出して
  177.                     exit(1);                         // 異常終了
  178.                 }
  179.                 z = "どうしましたか?", pos[0] = pos[1] = 0;
  180.                 //★bufferには文字入力の文字列を入れたので、ここにはメモからの文字列は入れられない。なので新しくbuffer2を作る。
  181.                 while ((fgets(buffer2, 256, outputfile)) != NULL)//メモに書いた文字列をbuffer2の中に入れる。
  182.                 {
  183.                     //注意「?」は全角の物を打たないと反応しない
  184.                     if (my_str2(buffer, "映画") && my_str2(buffer, "好き") && my_str2(buffer, "?")) {
  185.                         //  message = "どんな映画が好きなんですか?";
  186.                        // DrawFormatString(100, 300, GetColor(255, 255, 0), "%s", buffer);
  187.                         if (my_str2(buffer, "どんな")) {
  188.                             ++mozicount;
  189.                             gimonnlock = 1;
  190.                             if (my_str2(buffer2, "映画") && my_str2(buffer2, "どんな")) {
  191.                                 LEFTmark = 893;
  192.                                 hyouzi = 1;
  193.                                 p = strstr(buffer2, "→");//ここで→以降の文字をbuffer3に入れる。
  194.                                 p += 2;
  195.                                 strcpy(buffer3, p);//関数strcpyが指定した文字である「→」から2バイト動かしたポインタからの文字データを加算でbuffer3に入れている
  196.  
  197.                             }
  198.                         }
  199.                         if (my_str2(buffer, "なんで") or my_str2(buffer, "なぜ")) {
  200.                             ++mozicount;
  201.                             gimonnlock = 1;
  202.                             if (my_str2(buffer2, "映画") && my_str2(buffer2, "なぜ")) {
  203.                                 LEFTmark = 893;
  204.                                 hyouzi = 1;
  205.                                 p = strstr(buffer2, "→");//ここで→以降の文字をbuffer3に入れる。
  206.                                 p += 2;
  207.                                 strcpy(buffer3, p);//関数strcpyが指定した文字である「→」から2バイト動かしたポインタからの文字データを加算でbuffer3に入れている
  208.  
  209.                             }
  210.                         }
  211.                     }
  212.  
  213.                     // 文字の入力の入るバッファと、メモからの文字が入るバッファ2とで一致する文字が出てきた場合
  214.                     //一致する場合は1を返すようにしたので==1とする。
  215.                       //入力がない時。
  216.                     if (buffer[0] == '\0') {
  217.                         z = "文字を入力してください。", pos[0] = pos[1] = 0;
  218.                         diffrent = 0;
  219.                     }
  220.                     else if (my_str2(buffer2, buffer) == 0) {
  221.                         z = "すいません。わかりません。", pos[0] = pos[1] = 0;
  222.                         diffrent = 1;
  223.                     }
  224.                     else if (my_str2(buffer2, words[0]) == 1) {//一致した場合。//★上の二つの条件文により、words[0]の部分だけで一致しているかを確認できる。
  225.                         //buffer自体には全体の文が入るので、そこで単語が同じでも全体的な文が違うと判断されたら、残った単語で一致したものが返事となるためだろう。
  226.                         LEFTmark = 999;
  227.                         hyouzi = 1;
  228.                         gimon = 0;
  229.                         p = strstr(buffer2, "→");//ここで→以降の文字をbuffer3に入れる。
  230.                         p += 2;
  231.                         strcpy(buffer3, p);//関数strcpyが指定した文字である「→」から2バイト動かしたポインタからの文字データを加算でbuffer3に入れている
  232.                        // break;
  233.                         while ((fgets(buffer4, 256, outputfile)) != NULL)//メモに書いた文字列をbuffer3の中に入れる。
  234.                         {
  235.                             if (my_str2(buffer4, "健康に悪い→") == 1) {
  236.                                 LEFTmark = 288;
  237.                                 hyouzi = 1;
  238.  
  239.                                 p1 = strstr(buffer4, "→");//ここで→以降の文字をbuffer3に入れる。
  240.                                 p1 += 2;
  241.                                 strcpy(buffer5, p1);
  242.                                 break;
  243.                             }
  244.                             if (my_str2(buffer4, "健康に悪い→") == 0) {//上の二つの条件文を「タバコ」と「タバコとは?」などがすり抜けてしまった場合、
  245.                                 //words[0] =「タバコ」で一致してしまうので、返ってくる文章が統一されてしまうことがあるが、ここでの条件文のおかげで
  246.                                 //単語に対応した文章が返ってくる。
  247.                                 LEFTmark = 777;
  248.                                 break;
  249.  
  250.                             }
  251.                         }
  252.                     }
  253.  
  254.                     // 文字の入力の入るバッファと、メモからの文字が入るバッファ2とで一致しない文字が出てきた場合
  255.                    // if (hyouzi == 0) {
  256.                     //    if (strcmp(buffer2, buffer) == 0) {
  257.                      //       gimon = 1;
  258.                       //  }
  259.                     //}
  260.                 }
  261.                 fclose(outputfile);          // ファイルをクローズ(閉じる)
  262.             }
  263.             //できればエンターキーを押して、次の文章を記憶できるようにしたかったが、文章には必ずと言っていいほど「は」や「とは」
  264.             //が入るし、定義のように覚えさせたいので「覚えて」の後に下のような条件で文章を記憶するようにさせた。
  265.             if (memory == 1 && my_str2(buffer, "→")) {
  266.                 // キー入力ハンドルを作る(キャンセルなし全角文字有り数値入力じゃなし)
  267.                 ++mozicount;
  268.                 memory = 2;
  269.                 z = "記憶しました。", pos[0] = pos[1] = 0;
  270.             }
  271.             //duration = 1;
  272.             // 再度インプットハンドルをアクティブにする
  273.             SetActiveKeyInput(InputHandle);
  274.             // 入力文字列を初期化する
  275.             SetKeyInputString("", InputHandle);
  276.             //++mozicount;
  277.         }
  278.         //エンターキーが押されていないときでの処理
  279.         if (memory == 2) {
  280.             LEFTmark = 100;
  281.             //例えば、intとして49はそのままの値だが、charとしては49は文字コードで言う1を表す。//このような変換をしたようなもの。
  282.             outputfile = fopen("memo.txt", "a+");  // ファイルを書き込み用にオープン(開く)
  283.             if (outputfile == NULL) {          // オープンに失敗した場合
  284.                 printf("cannot open\n");         // エラーメッセージを出して
  285.                 exit(1);                         // 異常終了
  286.             }
  287.             fprintf(outputfile, "%s\n", buffer); // ファイルに書く
  288.             fclose(outputfile);          // ファイルをクローズ(閉じる)
  289.             //fclose(fp);//ファイルに書き込んだときにウィンドウが消えるようになっているので、memoryが1になった瞬間に書き込んでいるうんぬん以前に
  290.             //ファイルが閉じるのでウィンドウが消えてしまう。
  291.             memory = 0;
  292.             memorycount = 1;
  293.             // return 0;//ここで0になると終了してしまうので書き込んだ後も言葉が打ち込めるようにここを消す。    
  294.         }
  295.  
  296.         DrawFormatString(0, 150, GetColor(255, 255, 0), "mozicountは%d", mozicount);
  297.         DrawFormatString(0, 250, GetColor(255, 255, 0), " LEFTmarkは%d", LEFTmark);
  298.         DrawFormatString(100, 100, GetColor(255, 255, 0), " gimonnlockは%d,memoryは%d", gimonnlock, memory);
  299.         DrawFormatString(100, 300, GetColor(255, 255, 0), "hyouziは%d,gimonは%d,bufferは%s", hyouzi, gimon, buffer);
  300.        
  301.         DrawFormatString(100, 400, GetColor(5, 105, 0), " bufは%s", buf);
  302.         DrawFormatString(100, 500, GetColor(5, 105, 0), "  words[0]は%s,words[1]は%s,words[2]は%s", words[0], words[1], words[2]);
  303.  
  304.         if (gimon == 0 && hyouzi == 1) {
  305.             // DrawFormatString(100, 500, GetColor(5, 105, 19), " buffer2は%s", buffer2);
  306.             DrawFormatString(100, 600, GetColor(175, 80, 100), "%s%s", buffer3, buffer5);
  307.         }
  308.         //★記憶しましたの後で申し訳ありませんと出るので、memoryが2の時は申し訳ありませんと表示しないように2でない時に表示するように書いた。
  309.         if (mozicount >= 1 && gimon == 0 && hyouzi == 0 && diffrent == 1&&memory == 0&& memory !=2) {
  310.             DrawFormatString(10, 210, show_color, "申し訳ありません %s とは何ですか?", buffer);
  311.         }
  312.         if (mozicount >= 0 && gimon == 0 && hyouzi == 0) {
  313.             drawString(10, 100, z_color, pos, z);
  314.         }
  315.         for (int i = 0; i < n; i++)
  316.             DrawString(100, 200 + i * 40, words[i], word_color);
  317.  
  318.         DrawFormatString(100, 450, GetColor(175, 80, 100), "%s", result);
  319.         // 裏画面の内容を表画面に反映させる
  320.         ScreenFlip();
  321.  
  322.     }
  323.  
  324.     // 用済みのインプットハンドルを削除する
  325.     DeleteKeyInput(InputHandle);
  326.  
  327.     // 画面の初期化
  328.     ClearDrawScreen();
  329.  
  330.     // 裏画面の内容を表画面に反映させる
  331.     ScreenFlip();
  332.  
  333.     // キー入力待ち
  334.    // WaitKey();
  335.  
  336.     //ループないやループから出た後で何かしらの問題が発生したら終了する。
  337.     // DXライブラリの使用終了
  338.     DxLib_End();
  339.  
  340.     // 終了
  341.     return 0;
  342. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement