Advertisement
Hinski2

zad2

May 27th, 2024
12
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.30 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. enum {black, white, blank};
  5. typedef pair<int, int> pii;
  6. typedef vector<vector<int>> vvi;
  7. int max_tree_deep = 2;
  8. const int inf = 1e9 + 7;
  9. const int max_player = black;
  10. const int min_player = white;
  11.  
  12. struct State{
  13. vvi board;
  14. int deep;
  15. int player;
  16. int alfa;
  17. int beta;
  18. int val;
  19. vector<pii> black_poss;
  20. vector<pii> white_poss;
  21. };
  22.  
  23.  
  24. void set_initial_state(State &state, int player){
  25. state.board.resize(8);
  26. for(int i = 0; i < 8; i++){
  27. state.board[i].resize(8);
  28. for(int j = 0; j < 8; j++)
  29. state.board[i][j] = blank;
  30. }
  31.  
  32. state.board[3][3] = state.board[4][4] = black;
  33. state.board[3][4] = state.board[4][3] = white;
  34. state.black_poss.push_back({3, 3});
  35. state.black_poss.push_back({4, 4});
  36. state.white_poss.push_back({3, 4});
  37. state.white_poss.push_back({4, 3});
  38.  
  39. state.deep = 0;
  40. state.player = player;
  41. state.alfa = -inf;
  42. state.beta = inf;
  43. state.val = (player == max_player ? -inf : inf);
  44. }
  45.  
  46. bool valid_coord(const pii &poss){
  47. return 0 <= poss.first && poss.first < 8 && 0 <= poss.second && poss.second < 8;
  48. }
  49.  
  50. void make_move(State &child, const pii &move){
  51. //zmiana na chwile
  52. child.player ^= 1;
  53.  
  54. const int &x = move.first, &y = move.second;
  55. vector<pii> &my_poss = (child.player == black ? child.black_poss : child.white_poss);
  56. vector<pii> &his_poss = (child.player == black ? child.white_poss : child.black_poss);
  57.  
  58. child.board[x][y] = child.player;
  59. my_poss.push_back(move);
  60.  
  61. for(int i: {-1, 0, 1}){
  62. for(int j: {-1, 0, 1}){
  63. if(!i && !j) continue;
  64. pii poss = {x + i, y + j};
  65. vector<pii> to_flip;
  66.  
  67. while(valid_coord(poss) && child.board[poss.first][poss.second] == child.player ^ 1){
  68. to_flip.push_back(poss);
  69. poss.first += i, poss.second += j;
  70. }
  71.  
  72. if(valid_coord(poss) && child.board[poss.first][poss.second] == child.player){
  73. for(auto [a, b]: to_flip){
  74. child.board[a][b] = child.player;
  75. my_poss.push_back({a, b});
  76. auto rm = find(his_poss.begin(), his_poss.end(), make_pair(a, b));
  77.  
  78. if(rm != his_poss.end()) his_poss.erase(rm);
  79. }
  80. }
  81. }
  82. }
  83.  
  84. child.player ^= 1;
  85. }
  86.  
  87. void make_child_from_state(const State &state, State &child, const pii &move){
  88. child.board = state.board; // to jest kopia
  89. child.deep = state.deep + 1;
  90. child.player = state.player ^ 1;
  91. child.alfa = state.alfa;
  92. child.beta = state.beta;
  93. child.val = (child.player == max_player ? -inf : inf);
  94. child.black_poss = state.black_poss;
  95. child.white_poss = state.white_poss;
  96.  
  97. make_move(child, move);
  98. }
  99.  
  100. int eval_state(const State &state){
  101. // return state.black_poss.size() - state.white_poss.size();
  102. const vector<vector<int>> val = {
  103. {4,0,2,2,2,2,0,4},
  104. {0,0,2,1,1,2,0,0},
  105. {2,2,2,1,1,2,2,2},
  106. {2,1,1,1,1,1,1,2},
  107. {2,1,1,1,1,1,1,2},
  108. {2,2,2,1,1,2,2,2},
  109. {0,0,2,1,1,2,0,0},
  110. {4,0,2,2,2,2,0,4},
  111. };
  112.  
  113. int b = 0, w = 0;
  114. for(auto [x, y]: state.black_poss)
  115. b += val[x][y];
  116. for(auto [x, y]: state.white_poss)
  117. w += val[x][y];
  118.  
  119. return b - w;
  120. }
  121.  
  122.  
  123. vector<pii> generate_moves(const State &state){
  124. vector<pii> possible_moves;
  125. for(auto u: (state.player == black ? state.black_poss : state.white_poss)){
  126. for(int i: {-1, 0, 1}){
  127. for(int j: {-1, 0, 1}){
  128. if(!i and !j) continue;
  129. pii poss = {u.first + i, u.second + j};
  130. bool captured = false;
  131.  
  132. while(valid_coord(poss) && state.board[poss.first][poss.second] == (state.player ^ 1))
  133. captured = true, poss.first += i, poss.second += j;
  134.  
  135. if(valid_coord(poss) && state.board[poss.first][poss.second] == blank && captured)
  136. possible_moves.push_back(poss);
  137. }
  138. }
  139. }
  140.  
  141. return possible_moves;
  142. }
  143.  
  144. State min_max(State state){
  145. // sprawdzanie czy można grać
  146. if(state.deep >= max_tree_deep){
  147. state.val = eval_state(state);
  148. return state;
  149. }
  150.  
  151. vector<pii> possible_moves = generate_moves(state);
  152. if(possible_moves.size() == 0){
  153. state.val = eval_state(state);
  154. return state;
  155. }
  156.  
  157. // moge grać
  158. for(const auto move: possible_moves){
  159. State child; make_child_from_state(state, child, move);
  160. child = min_max(child);
  161.  
  162. if(state.player == max_player){
  163. state.val = max(state.val, child.val);
  164. state.alfa = max(state.alfa, state.val);
  165.  
  166. if(state.val >= state.beta)
  167. break;
  168. }
  169. else if(state.player == min_player){
  170. state.val = min(state.val, child.val);
  171. state.beta = min(state.beta, state.val);
  172. if(state.val <= state.alfa)
  173. break;
  174. }
  175. }
  176.  
  177. return state;
  178. }
  179.  
  180. State choose_random(const State &state){
  181. vector<pii> possible_moves = generate_moves(state);
  182. int idx = rand() % possible_moves.size();
  183. State child; make_child_from_state(state, child, possible_moves[idx]);
  184. return child;
  185. }
  186.  
  187. long seed()
  188. {
  189. auto t=chrono::system_clock::now();
  190. return std::chrono::duration_cast<std::chrono::milliseconds>(t.time_since_epoch()).count();
  191. }
  192.  
  193. int eval_end_board(State state){
  194. return state.black_poss.size() > state.white_poss.size();
  195. }
  196.  
  197. // czy a jest lepszy od b
  198. bool cmp(const State &a, const State &b){
  199. return eval_state(a) > eval_state(b);
  200. }
  201.  
  202. State choose_smart(State state){
  203. State best_child;
  204. vector<pii> possible_moves = generate_moves(state);
  205.  
  206. for(auto move: possible_moves){
  207. State child; make_child_from_state(state, child, move);
  208. child = min_max(child);
  209.  
  210. if(state.player == max_player){
  211. if(child.val > state.val){
  212. state.val = child.val;
  213. best_child = child;
  214. }
  215.  
  216. state.alfa = max(state.alfa, state.val);
  217. if(state.val >= state.beta)
  218. break;
  219.  
  220. }
  221. else if(state.player == min_player){
  222. if(child.val < state.val){
  223. state.val = child.val;
  224. best_child = child;
  225. }
  226.  
  227. state.beta = min(state.beta, state.val);
  228. if(state.val <= state.alfa)
  229. break;
  230. }
  231. }
  232.  
  233. return best_child;
  234. }
  235.  
  236. void tidy_state(State &state){
  237. state.deep = 0;
  238. state.alfa = -inf;
  239. state.beta = inf;
  240. state.val = (state.player == max_player ? -inf : inf);
  241. }
  242.  
  243. // debug
  244. void print_board(const State state);
  245.  
  246. int main(){
  247. srand(seed());
  248. pii score = {0, 0};
  249. for(int i = 0; i < 1000; i++){
  250.  
  251. // ustawianie gry
  252. State state;
  253. set_initial_state(state, black);
  254. int stranting_player = rand() % 2;
  255.  
  256. // gra dopuki ktoś nie wygra
  257. int cnt = 0;
  258. for(int turn = stranting_player; !generate_moves(state).empty(); turn ^= 1){
  259. if(turn == max_player)
  260. state = choose_smart(state);
  261. else
  262. state = choose_random(state);
  263.  
  264. tidy_state(state);
  265. cnt++;
  266. if(cnt == 4 && max_tree_deep < 5) cnt = 0, max_tree_deep++;
  267.  
  268. // debug
  269. // cout << visited << endl; visited = 0;
  270. // print_board(state); //debug
  271. }
  272. max_tree_deep = 2;
  273.  
  274.  
  275. if(eval_end_board(state) == stranting_player) score.first += 1;
  276. else score.second += 1;
  277. cout << "black: " << score.first << " white: " << score.second << endl;
  278. }
  279. }
  280.  
  281. void print_board(const State state){
  282. cout << (state.player == black ^ 1 ? "black" : "white") << endl;
  283. for(int i = 0; i < 8; i++){
  284. for(int j = 0; j < 8; j++)
  285. if(state.board[i][j] == black) cout << 'B' << ' ';
  286. else if(state.board[i][j] == white) cout << 'W' << ' ';
  287. else cout << '.' << ' ';
  288. cout << endl;
  289. }
  290. cout << endl;
  291. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement