zoukankan      html  css  js  c++  java
  • 猜单词--莫妮卡的新游戏

    Guess-the-word---Chinese-Version

    背景

    莫妮卡想要和我一起玩“上吊小人儿”(猜单词),但是我还是个中学生啊……

    可在github上下载完整代码,词库,教程等

    点我跳转

    为什么我要写这个程序

    当然是因为MAS(Monika After story)中Monika提出了的新游戏——上吊小人儿——过于困难啦~

    基本操作

    1.编译运行,输入要猜的残缺单词,未知部分用*表示。

    例如,app**

    2.按下回车。

    3.接下来输入你已经猜过但是猜错了的字母,中间不需要打空格,回车结束。如果还没有猜错了的字母的话就直接一个回车

    例如你猜了但是猜错了的字母有b,c,d

    那么你就输入bcd和一个回车

    4.接下来程序就会给你所有可能性以及其中出现每个字母的次数,方便你选择接下来要猜什么。

     

    技巧

    先输入常用的字母如e,t,a

    如果没有足够多的元音说明可能还有(aoeiu)

    元音的后面及其可能接着n、r

    Code

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<string>
      6 #include<cmath>
      7 #include<map>
      8 #include<set>
      9 #include<queue>
     10 #include<vector>
     11 #include<fstream>
     12 #define IL inline
     13 #define re register
     14 #define LL long long
     15 using namespace std;
     16 
     17 bool in(char ch)
     18 {
     19     if (ch <= 'z' && ch >= 'a') return 1;
     20     if (ch <= 'Z' && ch >= 'A') return 1;
     21     return 0;
     22 }
     23 
     24 bool exclude(string a, string b, string c)//a中没有b中的任何字母,a中没有c中不同位置的任何字母 
     25 {
     26     for (unsigned i = 0; i < a.size(); i++)
     27         for (unsigned j = 0; j < b.size(); j++)
     28             if (a[i] == b[j]) {
     29                 //cout<<"当前单词为"<<a<<",重复字母为"<<a[i]<<endl;
     30                 return 0;//猜错的字母不可能有 
     31             }
     32 
     33     map<char, int>lib;
     34     for (unsigned int i = 0; i < c.size(); i++) if (c[i] != '*') lib[c[i]]++;
     35     for (unsigned int i = 0; i < a.size(); i++) if (c[i] == '*' && lib.find(a[i]) != lib.end()) return 0;
     36 
     37     return 1;
     38 }
     39 
     40 vector<string>word;
     41 
     42 string t;
     43 int main()
     44 {
     45     ifstream fin("word.txt");
     46     ofstream fout("word.his", ios::app);
     47     ifstream his("word.his");
     48 
     49     if (his.peek() == EOF) cout << "没有查询历史
    ";
     50     else while (his.peek() != EOF) his >> t, word.push_back(t);
     51 
     52     cout << "读取数据库...
    ";
     53     while (fin.peek() != EOF) {
     54         string w;
     55         getline(fin, t);
     56         int post = 0;
     57         while (!in(t[post]) && post < t.size()) post++;
     58         while (in(t[post]) && post < t.size()) w.push_back((t[post] < 'a') ? (t[post] - 'A' + 'a') : t[post]), post++;
     59         word.push_back(w);
     60     }
     61     cout << "读取完毕!
    ";
     62     while (true) {
     63         string q, o;
     64         cout << "输入你想补全的残缺的单词,未知部分用*代替。
    ";
     65         cin >> q;
     66         getchar();//读取刚刚剩下的一个空格 
     67         cout << "输入已经猜错了的字母,没有的话直接按下回车键
    ";
     68         getline(cin, o);
     69         bool succ = 0;
     70         int total = 0;
     71         map<string, int>lib;
     72         int count[27];
     73         memset(count, 0, sizeof(count));
     74         for (unsigned int i = 0; i < word.size(); i++)
     75         {
     76             if (lib.find(word[i]) == lib.end())
     77                 if (q.size() == word[i].size() && exclude(word[i], o, q))
     78                 {
     79                     bool flag = 1;
     80                     for (unsigned int j = 0; j < q.size(); j++)
     81                     {
     82                         if (q[j] != '*' && q[j] != word[i][j]) {
     83                             flag = 0;
     84                             break;
     85                         }
     86                     }
     87                     if (flag) {
     88                         succ = 1;
     89                         lib[word[i]]++;
     90                         cout << ++total << "	" << word[i] << endl;
     91                         for (unsigned int j = 0; j < word[i].size(); j++) count[((word[i][j] < 'a') ? word[i][j] - 'A' + 'a' : word[i][j]) - 'a']++;
     92                     }
     93                 }
     94         }
     95         if (!succ) {
     96             cout << "单词没有找到啊~你知道答案么?(yes/no)";
     97             string know; cin >> know;
     98             if (know == "y" || know == "yes") {
     99                 cout << "请输入答案:";
    100                 string ans;
    101                 cin >> ans;
    102                 cout << "好哒,它已经被保存了
    ";
    103                 fout << ans << endl;
    104             }
    105         }
    106         else {
    107             cout << "共计" << total << "个符合条件的单词
    ";
    108             int max = -1;
    109             count[max] = -1;
    110             for (int i = 0; i < 26; i++) {
    111                 cout << (char)(i + 'a') << " " << count[i] << endl;
    112                 if (count[max] < count[i] && q.find(i + 'a') == q.npos) max = i;
    113             }
    114             cout << "建议猜测 " << (char)(max + 'a') << "  出现了 " << count[max] << "";
    115         }
    116         cout << endl << endl << endl;
    117     }
    118     return 0;
    119 }

    基本算法

    读取word.txt,进行无关字符的过滤,选取其有效部分加入vector<string>word中。读取时如果是大写字母则将其转化为小写

    同理读取历史

    输入要猜的单词以及猜错了的字母

    遍历word,按照一下顺序进行排除:

    1. 这个单词本轮中没有出现过(如果没有则将其加入lib)
    2. 长度相同
    3. exclude()检测这次扫的单词中没有猜错的单词,且其没有被猜到的单词位置上不能有猜对了的单词(否则应该已经被猜出来而不是还是未知的)
    4. 除了*以外,相同位置上字母相同
    5. 如果没有找到这个单词的话,询问要不要加入到错词本中
    6. 如果找到了,输入所有结果和总数以及字母频率分析

    特点

    • 词库不需要清洗
    • 你可以疯狂向词库末尾添加单词,而不需要在意它会输出多余相同的单词(因为lib会自动过滤)
    • 会向您推荐最佳的下一步应该猜的单词
    • 查不到的话可以记录下来,下次就可以查

    词库来源

    感谢词库

    本文使用的便是其其中的COCA_with_translation.txt,有20111个单词

  • 相关阅读:
    ORB Test Hanson
    ajax异步传输中的乱码问题
    调用淘宝API遇到的问题
    doc命令查看电脑配置大全
    从关联数组中取得键名
    php图片上传
    doc命令查看电脑配置
    一个空间配置多个虚拟主机
    淘客网站中系统信息获取
    opendir(path,context)
  • 原文地址:https://www.cnblogs.com/send-off-a-friend/p/13463414.html
Copyright © 2011-2022 走看看