game.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <cmath>
  5. #include "game.h"
  6. using namespace std;
  7. vector<int> a;
  8. bool u[S];
  9. //临时变量
  10. vector< vector<int> > f, g, h;
  11. //所有可能的答案,当前可能的答案,临时变量
  12. int t, ts, p;
  13. //当前局猜测步数,总步数,已使用的最大数字
  14. int ct[Size + 1][L + 1][L + 1];
  15. //ct[i][j][k]表示猜测h[i]返回jAkB时可能集的大小
  16. void dfs(int i)
  17. //扩展f
  18. {
  19. if (i == L) f.push_back(a);
  20. else
  21. for (int j = 0; j < S; ++j)
  22. if (!u[j]) {
  23. u[j] = true;
  24. a.push_back(j);
  25. dfs(i + 1);
  26. u[j] = false;
  27. a.erase(a.begin() + i);
  28. }
  29. }
  30. void dfs2(int i)
  31. //扩展本质不同集合
  32. {
  33. if (i == L) h.push_back(a);
  34. else
  35. for (int j = 0; j < S; ++j)
  36. if (!u[j] && (j <= p + 1 || u[j - 1])) {
  37. u[j] = true;
  38. a.push_back(j);
  39. dfs2(i + 1);
  40. u[j] = false;
  41. a.erase(a.begin() + i);
  42. }
  43. }
  44. pair<int, int> calc(const vector<int> &a, const vector<int> &b)
  45. //计算答案为a,猜测为b时的返回值
  46. {
  47. int A = 0, B = 0;
  48. memset(u, 0, sizeof(u));
  49. for (int i = 0; i < L; ++i)
  50. u[a[i]] = true;
  51. for (int i = 0; i < L; ++i)
  52. if (a[i] == b[i]) ++A;
  53. else
  54. if (u[b[i]]) ++B;
  55. return make_pair(A, B);
  56. }
  57. vector<int> find()
  58. //从g中计算出当前应该猜测的数字
  59. {
  60. if (t == 1) return f[0];
  61. if (g.size() == 1) return g[0];
  62. if (p >= S - 2) h = f;
  63. else {
  64. h.clear();
  65. a.clear();
  66. memset(u, 0, sizeof(u));
  67. dfs2(0);
  68. }
  69. //优化后的R值的计算,此时h为本质不同的X的集合
  70. memset(ct, 0, h.size() * (L + 1) * (L + 1) * sizeof(int));
  71. for (int i = 0; i < g.size(); ++i) {
  72. memset(u, 0, sizeof(u));
  73. for (int j = 0; j < L; ++j)
  74. u[g[i][j]] = true;
  75. for (int j = 0; j < h.size(); ++j) {
  76. int A = 0, B = 0;
  77. for (int k = 0; k < L; ++k)
  78. if (h[j][k] == g[i][k]) ++A;
  79. else
  80. if (u[h[j][k]]) ++B;
  81. ++ct[j][A][B];
  82. }
  83. }
  84. double bv = 1e9;
  85. vector<int> ret;
  86. for (int i = 0; i < h.size(); ++i) {
  87. double v = 0;
  88. //估价函数的计算
  89. for (int j = 0; j < L; ++j)
  90. for (int k = 0; j + k <= L; ++k)
  91. v += ct[i][j][k] * log(ct[i][j][k] + 1);
  92. //v += ct[i][j][k] * ct[i][j][k];//平均可能集大小
  93. //if (ct[i][j][k]) v += ct[i][j][k] * log(ct[i][j][k]);//预期步数
  94. //if (ct[i][j][k] > v) v = ct[i][j][k];//最坏可能集大小
  95. //if (ct[i][j][k]) --v;//反馈个数
  96. if (v < bv || (v == bv && binary_search(g.begin(), g.end(), h[i]))) {
  97. bv = v;
  98. ret = h[i];
  99. }
  100. }
  101. return ret;
  102. }
  103. int main()
  104. {
  105. AIname = "game";
  106. dfs(0);
  107. for (int P = 0; P < f.size(); ++P) {
  108. g = f;
  109. t = 0;
  110. p = L - 1;
  111. memset(u, 0, sizeof(u));
  112. do {
  113. ++t;
  114. a = find();
  115. pair<int, int> ret = guess(a);
  116. if (ret.first == 4) break;
  117. for (int i = 0; i < L; ++i)
  118. if (a[i] > p) p = a[i];
  119. h.clear();
  120. for (int i = 0; i < g.size(); ++i)
  121. if (calc(g[i], a) == ret) h.push_back(g[i]);
  122. g = h;
  123. }while (1);
  124. ts += t;
  125. cerr << P << " " << t << " " << double(ts) / (P + 1) << endl;
  126. }
  127. return 0;
  128. }