贪吃蛇代码(转)
Posted gulangyuzzz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了贪吃蛇代码(转)相关的知识,希望对你有一定的参考价值。
双人博弈贪吃蛇游戏
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 ", 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 ", depth); 288 //printf ("Test: %d ", test); 289 //printf ("Next %d ", 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 }
...
以上是关于贪吃蛇代码(转)的主要内容,如果未能解决你的问题,请参考以下文章