贪吃蛇代码(转)

双人博弈贪吃蛇游戏

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <jsoncpp/json.h>
  6 #include <cmath>
  7 #include <ctime>
  8 
  9 #define mp make_pair
 10 #define x first
 11 #define y second
 12 
 13 using namespace std;
 14 
 15 typedef pair<int,int> PII;
 16 
 17 const int WIN = 100000000;
 18 const int HASH_SIZE = 1 << 20;
 19 
 20 int n, m, R;
 21 int obs[20][20], disteps[300], pow_9[200];
 22 int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
 23 PII snake[2][300];
 24 int NEXT_STEP, Time;
 25 int hash_move[HASH_SIZE];
 26 
 27 int get_length(int r)
 28 {
 29     if (r <= 10) return r + 1;
 30     return (r - 10) / 3 + 11;
 31 }
 32 
 33 void print()
 34 {
 35     for (int i = 1; i <= m; i ++ )
 36     {
 37         for (int j = 1; j <= n; j ++ )
 38             printf ("%d", obs[j][i]);
 39         puts ("");
 40     }
 41     puts("");
 42 }
 43 
 44 int sum, DEPTH;
 45 
 46 void output(int d)
 47 {
 48     Json::Value ret;
 49     ret["response"]["direction"] = d;
 50     ret["response"]["myinformatin"] = DEPTH;
 51     Json::FastWriter writer;
 52     cout << writer.write(ret) << endl;
 53     system("pause");
 54 }
 55 
 56 void input()
 57 {
 58     string str, temp;
 59     while(getline(cin, temp)) str += temp;
 60 
 61     //str = string("{\"requests\":[{\"y\":1,\"x\":1,\"width\":11,\"obstacle\":[{\"y\":1,\"x\":5},{\"y\":11,\"x\":6},{\"y\":2,\"x\":7},{\"y\":10,\"x\":4},{\"y\":3,\"x\":8},{\"y\":9,\"x\":3},{\"y\":3,\"x\":9},{\"y\":9,\"x\":2},{\"y\":5,\"x\":1},{\"y\":7,\"x\":10}],\"height\":10},{\"direction\":3},{\"direction\":0},{\"direction\":3},{\"direction\":0},{\"direction\":0},{\"direction\":3},{\"direction\":3},{\"direction\":0},{\"direction\":0},{\"direction\":0},{\"direction\":0},{\"direction\":0},{\"direction\":0},{\"direction\":3},{\"direction\":2},{\"direction\":3},{\"direction\":3},{\"direction\":3},{\"direction\":2},{\"direction\":1},{\"direction\":1},{\"direction\":2},{\"direction\":1},{\"direction\":2},{\"direction\":3},{\"direction\":3},{\"direction\":0},{\"direction\":3},{\"direction\":2},{\"direction\":2},{\"direction\":3},{\"direction\":0},{\"direction\":0},{\"direction\":3},{\"direction\":0},{\"direction\":0},{\"direction\":0},{\"direction\":1},{\"direction\":2},{\"direction\":2},{\"direction\":1},{\"direction\":0},{\"direction\":0},{\"direction\":1},{\"direction\":2},{\"direction\":2},{\"direction\":1},{\"direction\":1}],\"responses\":[{\"direction\":1},{\"direction\":2},{\"direction\":2},{\"direction\":2},{\"direction\":1},{\"direction\":2},{\"direction\":1},{\"direction\":1},{\"direction\":1},{\"direction\":2},{\"direction\":3},{\"direction\":3},{\"direction\":3},{\"direction\":2},{\"direction\":1},{\"direction\":2},{\"direction\":2},{\"direction\":1},{\"direction\":0},{\"direction\":0},{\"direction\":1},{\"direction\":1},{\"direction\":0},{\"direction\":0},{\"direction\":1},{\"direction\":0},{\"direction\":1},{\"direction\":2},{\"direction\":2},{\"direction\":3},{\"direction\":2},{\"direction\":1},{\"direction\":1},{\"direction\":1},{\"direction\":2},{\"direction\":2},{\"direction\":2},{\"direction\":3},{\"direction\":3},{\"direction\":3},{\"direction\":0},{\"direction\":0},{\"direction\":3},{\"direction\":0},{\"direction\":3},{\"direction\":0},{\"direction\":0},{\"direction\":0}]}");
 62 
 63     Json::Reader reader;
 64     Json::Value input;
 65     reader.parse(str, input);
 66 
 67     n = input["requests"][(Json::Value::UInt)0]["height"].asInt();
 68     m = input["requests"][(Json::Value::UInt)0]["width"].asInt();
 69 
 70     for (int i = 1; i <= n; i ++ ) obs[i][0] = obs[i][m + 1] = 1;
 71     for (int i = 1; i <= m; i ++ ) obs[0][i] = obs[n + 1][i] = 1;
 72 
 73     int t = input["requests"][(Json::Value::UInt)0]["x"].asInt();
 74 
 75     snake[t != 1][0] = mp(1, 1);
 76     snake[t == 1][0] = mp(n, m);
 77 
 78     int obsCount = input["requests"][(Json::Value::UInt)0]["obstacle"].size();
 79 
 80     for (int i = 0, x, y; i < obsCount; i ++ )
 81     {
 82         x = input["requests"][(Json::Value::UInt)0]["obstacle"][i]["x"].asInt();
 83         y = input["requests"][(Json::Value::UInt)0]["obstacle"][i]["y"].asInt();
 84         obs[x][y] = 1;
 85     }
 86 
 87     R = input["responses"].size();
 88     for (int i = 0, d; i < R; i ++ )
 89     {
 90         d = input["responses"][(Json::Value::UInt)i]["direction"].asInt();
 91         snake[0][i + 1] = mp(snake[0][i].x + dx[d], snake[0][i].y + dy[d]);
 92 
 93         d = input["requests"][(Json::Value::UInt)(i + 1)]["direction"].asInt();
 94         snake[1][i + 1] = mp(snake[1][i].x + dx[d], snake[1][i].y + dy[d]);
 95     }
 96 
 97     for (int i = 0; i < 2; i ++ )
 98         for (int j = R - get_length(R) + 1; j <= R; j ++ )
 99             obs[snake[i][j].x][snake[i][j].y] = i + 2;
100 
101     for (int i = 0, j = 0; i < 300; i ++ )
102         if (get_length(i) == get_length(i + 1))
103             disteps[j ++ ] = i + 1;
104 
105     pow_9[0] = 10000;
106     for (int i = 1; i < 200; i ++ ) pow_9[i] = pow_9[i - 1] * 0.93;
107     //for (int i = 0; i < 200; i ++ ) printf ("%d %d\n", i, pow_9[i]);
108 }
109 
110 void move_tail()
111 {
112     if (get_length(R) == get_length(R + 1))
113     {
114         PII &r0 = snake[0][R + 1 - get_length(R + 1)], &r1 = snake[1][R + 1 - get_length(R + 1)];
115         obs[r0.x][r0.y] = obs[r1.x][r1.y] = 0;
116     }
117 }
118 
119 void remove_tail()
120 {
121     if (get_length(R) == get_length(R + 1))
122     {
123         PII &r0 = snake[0][R + 1 - get_length(R + 1)], &r1 = snake[1][R + 1 - get_length(R + 1)];
124         obs[r0.x][r0.y] = 2, obs[r1.x][r1.y] = 3;
125     }
126 }
127 
128 void move(int u, int d)
129 {
130     PII &t = snake[u][R + 1];
131     t = mp(snake[u][R].x + dx[d], snake[u][R].y + dy[d]);
132     obs[t.x][t.y] = u + 2;
133     if (u == 1) R ++ ;
134 }
135 
136 void remove(int u)
137 {
138     if (u == 1) R -- ;
139     PII &t = snake[u][R + 1];
140     obs[t.x][t.y] = 0;
141 }
142 
143 int special_work(int u)
144 {
145     if (!u)
146     {
147         bool flag = 0;
148         for (int i = 0; i < 4; i ++ )
149         {
150             PII t = mp(snake[1][R].x + dx[i], snake[1][R].y + dy[i]);
151             if (!obs[t.x][t.y])
152             {
153                 flag = 1;
154                 break;
155             }
156         }
157         if (flag) return -WIN;
158         return 0;
159     }
160     else
161     {
162         if (abs(snake[0][R + 1].x - snake[1][R].x) + abs(snake[0][R + 1].y - snake[1][R].y) == 1) return 10;
163         return -WIN;
164     }
165 }
166 
167 void shortest_path(int st[20][20], int d[20][20], int u)
168 {
169     static PII q[200];
170     int hh = 0, tt = 0;
171 
172     q[0] = snake[u][R];
173     d[q[0].x][q[0].y] = 0;
174 
175     while (hh <= tt)
176     {
177         PII &t = q[hh ++ ];
178         for (int i = 0; i < 4; i ++ )
179         {
180             PII p = mp(t.x + dx[i], t.y + dy[i]);
181             if (d[p.x][p.y] > d[t.x][t.y] + 1 && obs[p.x][p.y] != 1 && st[p.x][p.y] <= d[t.x][t.y] + 1)
182             {
183                 d[p.x][p.y] = d[t.x][t.y] + 1;
184                 q[ ++ tt] = p;
185             }
186         }
187     }
188 }
189 
190 int evaluate()
191 {
192     static int st[20][20], d0[20][20], d1[20][20], w[20][20];
193 
194     memset(st, 0, sizeof st);
195     memset(d0, 0x70, sizeof d0);
196     memset(d1, 0x70, sizeof d1);
197 
198     for (int i = R - get_length(R) + 1; i <= R; i ++ )
199         for (int j = 0; j < 2; j ++ )
200             st[snake[j][i].x][snake[j][i].y] = disteps[i] - R;
201 
202     shortest_path(st, d0, 0);
203     shortest_path(st, d1, 1);
204 
205     int s0 = 0, s1 = 0;
206     for (int i = 1; i <= n; i ++ )
207         for (int j = 1; j <= m; j ++ )
208         {
209             if (d0[i][j] < d1[i][j])
210                 s0 += pow_9[d0[i][j]];
211             else if (d0[i][j] > d1[i][j])
212                 s1 += pow_9[d1[i][j]];
213         }
214 
215     //int score0 = min(s0[0], s0[1]) * 2 + (s0[0] > s0[1]);
216     //int score1 = min(s1[0], s1[1]) * 2 + (s1[0] > s1[1]);
217     return s0 - s1;
218 }
219 
220 int alphabeta(int depth, int u, int alpha, int beta, bool isroot, int hash_value)
221 {
222     if (sum ++ > 400)
223     {
224         //cout << clock() - Time << endl;
225         output(NEXT_STEP);
226         exit(0);
227     }
228 
229     int current = -WIN, bestmove = 0;
230     bool flag = 1;
231     if (depth <= 0) return evaluate();
232 
233     int best = hash_move[hash_value & (HASH_SIZE - 1)];
234 
235     if (!u) move_tail();
236     for (int i = best, j = 0; j < 4 ; i = (i + 1) & 3, j ++ )
237     {
238         PII t = mp(snake[u][R].x + dx[i], snake[u][R].y + dy[i]);
239         if (obs[t.x][t.y]) continue;
240 
241         flag = 0;
242         move(u, i);
243         int score = -alphabeta(depth - 1, !u, -beta, -alpha, 0, hash_value * 20011 + i);
244         remove(u);
245 
246         if (score > current)
247         {
248             bestmove = i;
249             current = score;
250             if (alpha < score)
251             {
252                 alpha = score;
253                 if (isroot) NEXT_STEP = i;
254             }
255             if (score > beta) break;
256         }
257     }
258     if (flag) current = special_work(u);
259     if (!u) remove_tail();
260 
261     hash_move[hash_value & (HASH_SIZE - 1)] = bestmove;
262 
263     return current;
264 }
265 
266 int MTDF(int test, int depth)
267 {
268     int score = test, beta, l = -WIN, r = WIN;
269     while (l < r)
270     {
271         beta = (score == l ? score + 1 : score);
272         score = alphabeta(depth, 0, beta - 1, beta, 1, 0);
273         (score < beta ? r : l) = score;
274     }
275     return score;
276 }
277 
278 int strategy()
279 {
280     //print();
281 
282     int test = -WIN;
283     int depth = 6;
284     while (1)
285     {
286         test = MTDF(test, depth);
287         //printf ("Depth: %d\n", depth);
288         //printf ("Test: %d\n", test);
289         //printf ("Next %d\n", NEXT_STEP);
290         //getchar ();
291         depth += 2 ;
292         DEPTH = depth / 2;
293     }
294 
295     return NEXT_STEP;
296 }
297 
298 int main()
299 {
300     Time = clock();
301     input();
302     output(strategy());
303     return 0;
304 }

...

猜你喜欢

转载自www.cnblogs.com/gulangyuzzz/p/12067026.html